1010struct pci_root_info {
1111 struct acpi_device * bridge ;
1212 char name [16 ];
13- unsigned int res_num ;
14- struct resource * res ;
15- resource_size_t * res_offset ;
1613 struct pci_sysdata sd ;
1714#ifdef CONFIG_PCI_MMCONFIG
1815 bool mcfg_added ;
@@ -218,132 +215,41 @@ static void teardown_mcfg_map(struct pci_root_info *info)
218215}
219216#endif
220217
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 )
268220{
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 ;
319224
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 ;
327227
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 ;
331232
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 ;
342234 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+ }
344250
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 ;
347253 if (!(res2 -> flags & type ))
348254 continue ;
349255
@@ -355,118 +261,92 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
355261 if (resource_overlaps (res1 , res2 )) {
356262 res2 -> start = min (res1 -> start , res2 -> start );
357263 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" ,
360265 res2 , res1 );
361- res1 -> flags = 0 ;
266+ free = true;
267+ goto next ;
362268 }
363269 }
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 );
364277 }
365278}
366279
367280static void add_resources (struct pci_root_info * info ,
368- struct list_head * resources )
281+ struct list_head * resources ,
282+ struct list_head * crs_res )
369283{
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 ;
375286
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 ) ;
378289
290+ resource_list_for_each_entry_safe (entry , tmp , crs_res ) {
291+ res = entry -> res ;
379292 if (res -> flags & IORESOURCE_MEM )
380293 root = & iomem_resource ;
381294 else if (res -> flags & IORESOURCE_IO )
382295 root = & ioport_resource ;
383296 else
384- continue ;
297+ BUG_ON ( res ) ;
385298
386299 conflict = insert_resource_conflict (root , res );
387- if (conflict )
300+ if (conflict ) {
388301 dev_info (& info -> bridge -> dev ,
389302 "ignoring host bridge window %pR (conflicts with %s %pR)\n" ,
390303 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+ }
394306 }
395- }
396307
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 );
404309}
405310
406- static void __release_pci_root_info (struct pci_root_info * info )
311+ static void release_pci_root_info (struct pci_host_bridge * bridge )
407312{
408- int i ;
409313 struct resource * res ;
314+ struct resource_entry * entry ;
315+ struct pci_root_info * info = bridge -> release_data ;
410316
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 );
421322 }
422323
423- free_pci_root_info_res (info );
424-
425324 teardown_mcfg_map (info );
426-
427325 kfree (info );
428326}
429327
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-
437328static void probe_pci_root_info (struct pci_root_info * info ,
438329 struct acpi_device * device ,
439- int busnum , int domain )
330+ int busnum , int domain ,
331+ struct list_head * list )
440332{
441- size_t size ;
333+ int ret ;
334+ struct resource_entry * entry ;
442335
443336 sprintf (info -> name , "PCI Bus %04x:%02x" , domain , busnum );
444337 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 ;
470350}
471351
472352struct 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)
475355 struct pci_root_info * info ;
476356 int domain = root -> segment ;
477357 int busnum = root -> secondary .start ;
358+ struct resource_entry * res_entry ;
359+ LIST_HEAD (crs_res );
478360 LIST_HEAD (resources );
479361 struct pci_bus * bus ;
480362 struct pci_sysdata * sd ;
@@ -522,18 +404,22 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
522404 memcpy (bus -> sysdata , sd , sizeof (* sd ));
523405 kfree (info );
524406 } else {
525- probe_pci_root_info (info , device , busnum , domain );
526-
527407 /* insert busn res at first */
528408 pci_add_resource (& resources , & root -> secondary );
409+
529410 /*
530411 * _CRS with no apertures is normal, so only fall back to
531412 * defaults or native bridge info if we're ignoring _CRS.
532413 */
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 );
537423 x86_pci_root_bus_resources (busnum , & resources );
538424 }
539425
@@ -548,8 +434,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
548434 to_pci_host_bridge (bus -> bridge ),
549435 release_pci_root_info , info );
550436 } 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 );
553440 }
554441 }
555442
0 commit comments