10
10
struct pci_root_info {
11
11
struct acpi_device * bridge ;
12
12
char name [16 ];
13
- unsigned int res_num ;
14
- struct resource * res ;
15
- resource_size_t * res_offset ;
16
13
struct pci_sysdata sd ;
17
14
#ifdef CONFIG_PCI_MMCONFIG
18
15
bool mcfg_added ;
@@ -218,132 +215,41 @@ static void teardown_mcfg_map(struct pci_root_info *info)
218
215
}
219
216
#endif
220
217
221
- static acpi_status resource_to_addr (struct acpi_resource * resource ,
222
- struct acpi_resource_address64 * addr )
223
- {
224
- acpi_status status ;
225
- struct acpi_resource_memory24 * memory24 ;
226
- struct acpi_resource_memory32 * memory32 ;
227
- struct acpi_resource_fixed_memory32 * fixed_memory32 ;
228
-
229
- memset (addr , 0 , sizeof (* addr ));
230
- switch (resource -> type ) {
231
- case ACPI_RESOURCE_TYPE_MEMORY24 :
232
- memory24 = & resource -> data .memory24 ;
233
- addr -> resource_type = ACPI_MEMORY_RANGE ;
234
- addr -> address .minimum = memory24 -> minimum ;
235
- addr -> address .address_length = memory24 -> address_length ;
236
- addr -> address .maximum = addr -> address .minimum + addr -> address .address_length - 1 ;
237
- return AE_OK ;
238
- case ACPI_RESOURCE_TYPE_MEMORY32 :
239
- memory32 = & resource -> data .memory32 ;
240
- addr -> resource_type = ACPI_MEMORY_RANGE ;
241
- addr -> address .minimum = memory32 -> minimum ;
242
- addr -> address .address_length = memory32 -> address_length ;
243
- addr -> address .maximum = addr -> address .minimum + addr -> address .address_length - 1 ;
244
- return AE_OK ;
245
- case ACPI_RESOURCE_TYPE_FIXED_MEMORY32 :
246
- fixed_memory32 = & resource -> data .fixed_memory32 ;
247
- addr -> resource_type = ACPI_MEMORY_RANGE ;
248
- addr -> address .minimum = fixed_memory32 -> address ;
249
- addr -> address .address_length = fixed_memory32 -> address_length ;
250
- addr -> address .maximum = addr -> address .minimum + addr -> address .address_length - 1 ;
251
- return AE_OK ;
252
- case ACPI_RESOURCE_TYPE_ADDRESS16 :
253
- case ACPI_RESOURCE_TYPE_ADDRESS32 :
254
- case ACPI_RESOURCE_TYPE_ADDRESS64 :
255
- status = acpi_resource_to_address64 (resource , addr );
256
- if (ACPI_SUCCESS (status ) &&
257
- (addr -> resource_type == ACPI_MEMORY_RANGE ||
258
- addr -> resource_type == ACPI_IO_RANGE ) &&
259
- addr -> address .address_length > 0 ) {
260
- return AE_OK ;
261
- }
262
- break ;
263
- }
264
- return AE_ERROR ;
265
- }
266
-
267
- static acpi_status count_resource (struct acpi_resource * acpi_res , void * data )
218
+ static void validate_resources (struct device * dev , struct list_head * crs_res ,
219
+ unsigned long type )
268
220
{
269
- struct pci_root_info * info = data ;
270
- struct acpi_resource_address64 addr ;
271
- acpi_status status ;
272
-
273
- status = resource_to_addr (acpi_res , & addr );
274
- if (ACPI_SUCCESS (status ))
275
- info -> res_num ++ ;
276
- return AE_OK ;
277
- }
278
-
279
- static acpi_status setup_resource (struct acpi_resource * acpi_res , void * data )
280
- {
281
- struct pci_root_info * info = data ;
282
- struct resource * res ;
283
- struct acpi_resource_address64 addr ;
284
- acpi_status status ;
285
- unsigned long flags ;
286
- u64 start , orig_end , end , res_end ;
287
-
288
- status = resource_to_addr (acpi_res , & addr );
289
- if (!ACPI_SUCCESS (status ))
290
- return AE_OK ;
291
-
292
- if (addr .resource_type == ACPI_MEMORY_RANGE ) {
293
- flags = IORESOURCE_MEM ;
294
- if (addr .info .mem .caching == ACPI_PREFETCHABLE_MEMORY )
295
- flags |= IORESOURCE_PREFETCH ;
296
- res_end = (u64 )iomem_resource .end ;
297
- } else if (addr .resource_type == ACPI_IO_RANGE ) {
298
- flags = IORESOURCE_IO ;
299
- res_end = (u64 )ioport_resource .end ;
300
- } else
301
- return AE_OK ;
302
-
303
- start = addr .address .minimum + addr .address .translation_offset ;
304
- orig_end = end = addr .address .maximum + addr .address .translation_offset ;
305
-
306
- /* Exclude non-addressable range or non-addressable portion of range */
307
- end = min (end , res_end );
308
- if (end <= start ) {
309
- dev_info (& info -> bridge -> dev ,
310
- "host bridge window [%#llx-%#llx] "
311
- "(ignored, not CPU addressable)\n" , start , orig_end );
312
- return AE_OK ;
313
- } else if (orig_end != end ) {
314
- dev_info (& info -> bridge -> dev ,
315
- "host bridge window [%#llx-%#llx] "
316
- "([%#llx-%#llx] ignored, not CPU addressable)\n" ,
317
- start , orig_end , end + 1 , orig_end );
318
- }
221
+ LIST_HEAD (list );
222
+ struct resource * res1 , * res2 , * root = NULL ;
223
+ struct resource_entry * tmp , * entry , * entry2 ;
319
224
320
- res = & info -> res [info -> res_num ];
321
- res -> name = info -> name ;
322
- res -> flags = flags ;
323
- res -> start = start ;
324
- res -> end = end ;
325
- info -> res_offset [info -> res_num ] = addr .address .translation_offset ;
326
- info -> res_num ++ ;
225
+ BUG_ON ((type & (IORESOURCE_MEM | IORESOURCE_IO )) == 0 );
226
+ root = (type & IORESOURCE_MEM ) ? & iomem_resource : & ioport_resource ;
327
227
328
- if (!pci_use_crs )
329
- dev_printk (KERN_DEBUG , & info -> bridge -> dev ,
330
- "host bridge window %pR (ignored)\n" , res );
228
+ list_splice_init (crs_res , & list );
229
+ resource_list_for_each_entry_safe (entry , tmp , & list ) {
230
+ bool free = false;
231
+ resource_size_t end ;
331
232
332
- return AE_OK ;
333
- }
334
-
335
- static void coalesce_windows (struct pci_root_info * info , unsigned long type )
336
- {
337
- int i , j ;
338
- struct resource * res1 , * res2 ;
339
-
340
- for (i = 0 ; i < info -> res_num ; i ++ ) {
341
- res1 = & info -> res [i ];
233
+ res1 = entry -> res ;
342
234
if (!(res1 -> flags & type ))
343
- continue ;
235
+ goto next ;
236
+
237
+ /* Exclude non-addressable range or non-addressable portion */
238
+ end = min (res1 -> end , root -> end );
239
+ if (end <= res1 -> start ) {
240
+ dev_info (dev , "host bridge window %pR (ignored, not CPU addressable)\n" ,
241
+ res1 );
242
+ free = true;
243
+ goto next ;
244
+ } else if (res1 -> end != end ) {
245
+ dev_info (dev , "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n" ,
246
+ res1 , (unsigned long long )end + 1 ,
247
+ (unsigned long long )res1 -> end );
248
+ res1 -> end = end ;
249
+ }
344
250
345
- for ( j = i + 1 ; j < info -> res_num ; j ++ ) {
346
- res2 = & info -> res [ j ] ;
251
+ resource_list_for_each_entry ( entry2 , crs_res ) {
252
+ res2 = entry2 -> res ;
347
253
if (!(res2 -> flags & type ))
348
254
continue ;
349
255
@@ -355,118 +261,92 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
355
261
if (resource_overlaps (res1 , res2 )) {
356
262
res2 -> start = min (res1 -> start , res2 -> start );
357
263
res2 -> end = max (res1 -> end , res2 -> end );
358
- dev_info (& info -> bridge -> dev ,
359
- "host bridge window expanded to %pR; %pR ignored\n" ,
264
+ dev_info (dev , "host bridge window expanded to %pR; %pR ignored\n" ,
360
265
res2 , res1 );
361
- res1 -> flags = 0 ;
266
+ free = true;
267
+ goto next ;
362
268
}
363
269
}
270
+
271
+ next :
272
+ resource_list_del (entry );
273
+ if (free )
274
+ resource_list_free_entry (entry );
275
+ else
276
+ resource_list_add_tail (entry , crs_res );
364
277
}
365
278
}
366
279
367
280
static void add_resources (struct pci_root_info * info ,
368
- struct list_head * resources )
281
+ struct list_head * resources ,
282
+ struct list_head * crs_res )
369
283
{
370
- int i ;
371
- struct resource * res , * root , * conflict ;
372
-
373
- coalesce_windows (info , IORESOURCE_MEM );
374
- coalesce_windows (info , IORESOURCE_IO );
284
+ struct resource_entry * entry , * tmp ;
285
+ struct resource * res , * conflict , * root = NULL ;
375
286
376
- for ( i = 0 ; i < info -> res_num ; i ++ ) {
377
- res = & info -> res [ i ] ;
287
+ validate_resources ( & info -> bridge -> dev , crs_res , IORESOURCE_MEM );
288
+ validate_resources ( & info -> bridge -> dev , crs_res , IORESOURCE_IO ) ;
378
289
290
+ resource_list_for_each_entry_safe (entry , tmp , crs_res ) {
291
+ res = entry -> res ;
379
292
if (res -> flags & IORESOURCE_MEM )
380
293
root = & iomem_resource ;
381
294
else if (res -> flags & IORESOURCE_IO )
382
295
root = & ioport_resource ;
383
296
else
384
- continue ;
297
+ BUG_ON ( res ) ;
385
298
386
299
conflict = insert_resource_conflict (root , res );
387
- if (conflict )
300
+ if (conflict ) {
388
301
dev_info (& info -> bridge -> dev ,
389
302
"ignoring host bridge window %pR (conflicts with %s %pR)\n" ,
390
303
res , conflict -> name , conflict );
391
- else
392
- pci_add_resource_offset (resources , res ,
393
- info -> res_offset [i ]);
304
+ resource_list_destroy_entry (entry );
305
+ }
394
306
}
395
- }
396
307
397
- static void free_pci_root_info_res (struct pci_root_info * info )
398
- {
399
- kfree (info -> res );
400
- info -> res = NULL ;
401
- kfree (info -> res_offset );
402
- info -> res_offset = NULL ;
403
- info -> res_num = 0 ;
308
+ list_splice_tail (crs_res , resources );
404
309
}
405
310
406
- static void __release_pci_root_info (struct pci_root_info * info )
311
+ static void release_pci_root_info (struct pci_host_bridge * bridge )
407
312
{
408
- int i ;
409
313
struct resource * res ;
314
+ struct resource_entry * entry ;
315
+ struct pci_root_info * info = bridge -> release_data ;
410
316
411
- for (i = 0 ; i < info -> res_num ; i ++ ) {
412
- res = & info -> res [i ];
413
-
414
- if (!res -> parent )
415
- continue ;
416
-
417
- if (!(res -> flags & (IORESOURCE_MEM | IORESOURCE_IO )))
418
- continue ;
419
-
420
- release_resource (res );
317
+ resource_list_for_each_entry (entry , & bridge -> windows ) {
318
+ res = entry -> res ;
319
+ if (res -> parent &&
320
+ (res -> flags & (IORESOURCE_MEM | IORESOURCE_IO )))
321
+ release_resource (res );
421
322
}
422
323
423
- free_pci_root_info_res (info );
424
-
425
324
teardown_mcfg_map (info );
426
-
427
325
kfree (info );
428
326
}
429
327
430
- static void release_pci_root_info (struct pci_host_bridge * bridge )
431
- {
432
- struct pci_root_info * info = bridge -> release_data ;
433
-
434
- __release_pci_root_info (info );
435
- }
436
-
437
328
static void probe_pci_root_info (struct pci_root_info * info ,
438
329
struct acpi_device * device ,
439
- int busnum , int domain )
330
+ int busnum , int domain ,
331
+ struct list_head * list )
440
332
{
441
- size_t size ;
333
+ int ret ;
334
+ struct resource_entry * entry ;
442
335
443
336
sprintf (info -> name , "PCI Bus %04x:%02x" , domain , busnum );
444
337
info -> bridge = device ;
445
-
446
- info -> res_num = 0 ;
447
- acpi_walk_resources (device -> handle , METHOD_NAME__CRS , count_resource ,
448
- info );
449
- if (!info -> res_num )
450
- return ;
451
-
452
- size = sizeof (* info -> res ) * info -> res_num ;
453
- info -> res = kzalloc_node (size , GFP_KERNEL , info -> sd .node );
454
- if (!info -> res ) {
455
- info -> res_num = 0 ;
456
- return ;
457
- }
458
-
459
- size = sizeof (* info -> res_offset ) * info -> res_num ;
460
- info -> res_num = 0 ;
461
- info -> res_offset = kzalloc_node (size , GFP_KERNEL , info -> sd .node );
462
- if (!info -> res_offset ) {
463
- kfree (info -> res );
464
- info -> res = NULL ;
465
- return ;
466
- }
467
-
468
- acpi_walk_resources (device -> handle , METHOD_NAME__CRS , setup_resource ,
469
- info );
338
+ ret = acpi_dev_get_resources (device , list ,
339
+ acpi_dev_filter_resource_type_cb ,
340
+ (void * )(IORESOURCE_IO | IORESOURCE_MEM ));
341
+ if (ret < 0 )
342
+ dev_warn (& device -> dev ,
343
+ "failed to parse _CRS method, error code %d\n" , ret );
344
+ else if (ret == 0 )
345
+ dev_dbg (& device -> dev ,
346
+ "no IO and memory resources present in _CRS\n" );
347
+ else
348
+ resource_list_for_each_entry (entry , list )
349
+ entry -> res -> name = info -> name ;
470
350
}
471
351
472
352
struct pci_bus * pci_acpi_scan_root (struct acpi_pci_root * root )
@@ -475,6 +355,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
475
355
struct pci_root_info * info ;
476
356
int domain = root -> segment ;
477
357
int busnum = root -> secondary .start ;
358
+ struct resource_entry * res_entry ;
359
+ LIST_HEAD (crs_res );
478
360
LIST_HEAD (resources );
479
361
struct pci_bus * bus ;
480
362
struct pci_sysdata * sd ;
@@ -522,18 +404,22 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
522
404
memcpy (bus -> sysdata , sd , sizeof (* sd ));
523
405
kfree (info );
524
406
} else {
525
- probe_pci_root_info (info , device , busnum , domain );
526
-
527
407
/* insert busn res at first */
528
408
pci_add_resource (& resources , & root -> secondary );
409
+
529
410
/*
530
411
* _CRS with no apertures is normal, so only fall back to
531
412
* defaults or native bridge info if we're ignoring _CRS.
532
413
*/
533
- if (pci_use_crs )
534
- add_resources (info , & resources );
535
- else {
536
- free_pci_root_info_res (info );
414
+ probe_pci_root_info (info , device , busnum , domain , & crs_res );
415
+ if (pci_use_crs ) {
416
+ add_resources (info , & resources , & crs_res );
417
+ } else {
418
+ resource_list_for_each_entry (res_entry , & crs_res )
419
+ dev_printk (KERN_DEBUG , & device -> dev ,
420
+ "host bridge window %pR (ignored)\n" ,
421
+ res_entry -> res );
422
+ resource_list_free (& crs_res );
537
423
x86_pci_root_bus_resources (busnum , & resources );
538
424
}
539
425
@@ -548,8 +434,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
548
434
to_pci_host_bridge (bus -> bridge ),
549
435
release_pci_root_info , info );
550
436
} else {
551
- pci_free_resource_list (& resources );
552
- __release_pci_root_info (info );
437
+ resource_list_free (& resources );
438
+ teardown_mcfg_map (info );
439
+ kfree (info );
553
440
}
554
441
}
555
442
0 commit comments