@@ -521,7 +521,7 @@ static void pci_release_host_bridge_dev(struct device *dev)
521
521
kfree (bridge );
522
522
}
523
523
524
- static struct pci_host_bridge * pci_alloc_host_bridge (struct pci_bus * b )
524
+ static struct pci_host_bridge * pci_alloc_host_bridge (void )
525
525
{
526
526
struct pci_host_bridge * bridge ;
527
527
@@ -530,7 +530,7 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b)
530
530
return NULL ;
531
531
532
532
INIT_LIST_HEAD (& bridge -> windows );
533
- bridge -> bus = b ;
533
+
534
534
return bridge ;
535
535
}
536
536
@@ -717,6 +717,122 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)
717
717
dev_set_msi_domain (& bus -> dev , d );
718
718
}
719
719
720
+ static int pci_register_host_bridge (struct pci_host_bridge * bridge )
721
+ {
722
+ struct device * parent = bridge -> dev .parent ;
723
+ struct resource_entry * window , * n ;
724
+ struct pci_bus * bus , * b ;
725
+ resource_size_t offset ;
726
+ LIST_HEAD (resources );
727
+ struct resource * res ;
728
+ char addr [64 ], * fmt ;
729
+ const char * name ;
730
+ int err ;
731
+
732
+ bus = pci_alloc_bus (NULL );
733
+ if (!bus )
734
+ return - ENOMEM ;
735
+
736
+ bridge -> bus = bus ;
737
+
738
+ /* temporarily move resources off the list */
739
+ list_splice_init (& bridge -> windows , & resources );
740
+ bus -> sysdata = bridge -> sysdata ;
741
+ bus -> msi = bridge -> msi ;
742
+ bus -> ops = bridge -> ops ;
743
+ bus -> number = bus -> busn_res .start = bridge -> busnr ;
744
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
745
+ bus -> domain_nr = pci_bus_find_domain_nr (bus , parent );
746
+ #endif
747
+
748
+ b = pci_find_bus (pci_domain_nr (bus ), bridge -> busnr );
749
+ if (b ) {
750
+ /* If we already got to this bus through a different bridge, ignore it */
751
+ dev_dbg (& b -> dev , "bus already known\n" );
752
+ err = - EEXIST ;
753
+ goto free ;
754
+ }
755
+
756
+ dev_set_name (& bridge -> dev , "pci%04x:%02x" , pci_domain_nr (bus ),
757
+ bridge -> busnr );
758
+
759
+ err = pcibios_root_bridge_prepare (bridge );
760
+ if (err )
761
+ goto free ;
762
+
763
+ err = device_register (& bridge -> dev );
764
+ if (err )
765
+ put_device (& bridge -> dev );
766
+
767
+ bus -> bridge = get_device (& bridge -> dev );
768
+ device_enable_async_suspend (bus -> bridge );
769
+ pci_set_bus_of_node (bus );
770
+ pci_set_bus_msi_domain (bus );
771
+
772
+ if (!parent )
773
+ set_dev_node (bus -> bridge , pcibus_to_node (bus ));
774
+
775
+ bus -> dev .class = & pcibus_class ;
776
+ bus -> dev .parent = bus -> bridge ;
777
+
778
+ dev_set_name (& bus -> dev , "%04x:%02x" , pci_domain_nr (bus ), bus -> number );
779
+ name = dev_name (& bus -> dev );
780
+
781
+ err = device_register (& bus -> dev );
782
+ if (err )
783
+ goto unregister ;
784
+
785
+ pcibios_add_bus (bus );
786
+
787
+ /* Create legacy_io and legacy_mem files for this bus */
788
+ pci_create_legacy_files (bus );
789
+
790
+ if (parent )
791
+ dev_info (parent , "PCI host bridge to bus %s\n" , name );
792
+ else
793
+ pr_info ("PCI host bridge to bus %s\n" , name );
794
+
795
+ /* Add initial resources to the bus */
796
+ resource_list_for_each_entry_safe (window , n , & resources ) {
797
+ list_move_tail (& window -> node , & bridge -> windows );
798
+ offset = window -> offset ;
799
+ res = window -> res ;
800
+
801
+ if (res -> flags & IORESOURCE_BUS )
802
+ pci_bus_insert_busn_res (bus , bus -> number , res -> end );
803
+ else
804
+ pci_bus_add_resource (bus , res , 0 );
805
+
806
+ if (offset ) {
807
+ if (resource_type (res ) == IORESOURCE_IO )
808
+ fmt = " (bus address [%#06llx-%#06llx])" ;
809
+ else
810
+ fmt = " (bus address [%#010llx-%#010llx])" ;
811
+
812
+ snprintf (addr , sizeof (addr ), fmt ,
813
+ (unsigned long long )(res -> start - offset ),
814
+ (unsigned long long )(res -> end - offset ));
815
+ } else
816
+ addr [0 ] = '\0' ;
817
+
818
+ dev_info (& bus -> dev , "root bus resource %pR%s\n" , res , addr );
819
+ }
820
+
821
+ down_write (& pci_bus_sem );
822
+ list_add_tail (& bus -> node , & pci_root_buses );
823
+ up_write (& pci_bus_sem );
824
+
825
+ return 0 ;
826
+
827
+ unregister :
828
+ put_device (& bridge -> dev );
829
+ device_unregister (& bridge -> dev );
830
+
831
+ free :
832
+ kfree (bus );
833
+ return err ;
834
+ }
835
+
720
836
static struct pci_bus * pci_alloc_child_bus (struct pci_bus * parent ,
721
837
struct pci_dev * bridge , int busnr )
722
838
{
@@ -2130,113 +2246,43 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
2130
2246
{
2131
2247
}
2132
2248
2133
- struct pci_bus * pci_create_root_bus (struct device * parent , int bus ,
2134
- struct pci_ops * ops , void * sysdata , struct list_head * resources )
2249
+ static struct pci_bus * pci_create_root_bus_msi (struct device * parent ,
2250
+ int bus , struct pci_ops * ops , void * sysdata ,
2251
+ struct list_head * resources , struct msi_controller * msi )
2135
2252
{
2136
2253
int error ;
2137
2254
struct pci_host_bridge * bridge ;
2138
- struct pci_bus * b , * b2 ;
2139
- struct resource_entry * window , * n ;
2140
- struct resource * res ;
2141
- resource_size_t offset ;
2142
- char bus_addr [64 ];
2143
- char * fmt ;
2144
-
2145
- b = pci_alloc_bus (NULL );
2146
- if (!b )
2147
- return NULL ;
2148
2255
2149
- b -> sysdata = sysdata ;
2150
- b -> ops = ops ;
2151
- b -> number = b -> busn_res .start = bus ;
2152
- #ifdef CONFIG_PCI_DOMAINS_GENERIC
2153
- b -> domain_nr = pci_bus_find_domain_nr (b , parent );
2154
- #endif
2155
- b2 = pci_find_bus (pci_domain_nr (b ), bus );
2156
- if (b2 ) {
2157
- /* If we already got to this bus through a different bridge, ignore it */
2158
- dev_dbg (& b2 -> dev , "bus already known\n" );
2159
- goto err_out ;
2160
- }
2161
-
2162
- bridge = pci_alloc_host_bridge (b );
2256
+ bridge = pci_alloc_host_bridge ();
2163
2257
if (!bridge )
2164
- goto err_out ;
2258
+ return NULL ;
2165
2259
2166
2260
bridge -> dev .parent = parent ;
2167
2261
bridge -> dev .release = pci_release_host_bridge_dev ;
2168
- dev_set_name (& bridge -> dev , "pci%04x:%02x" , pci_domain_nr (b ), bus );
2169
- error = pcibios_root_bridge_prepare (bridge );
2170
- if (error ) {
2171
- kfree (bridge );
2172
- goto err_out ;
2173
- }
2174
-
2175
- error = device_register (& bridge -> dev );
2176
- if (error ) {
2177
- put_device (& bridge -> dev );
2178
- goto err_out ;
2179
- }
2180
- b -> bridge = get_device (& bridge -> dev );
2181
- device_enable_async_suspend (b -> bridge );
2182
- pci_set_bus_of_node (b );
2183
- pci_set_bus_msi_domain (b );
2184
2262
2185
- if (!parent )
2186
- set_dev_node (b -> bridge , pcibus_to_node (b ));
2187
-
2188
- b -> dev .class = & pcibus_class ;
2189
- b -> dev .parent = b -> bridge ;
2190
- dev_set_name (& b -> dev , "%04x:%02x" , pci_domain_nr (b ), bus );
2191
- error = device_register (& b -> dev );
2192
- if (error )
2193
- goto class_dev_reg_err ;
2263
+ list_splice_init (resources , & bridge -> windows );
2264
+ bridge -> sysdata = sysdata ;
2265
+ bridge -> busnr = bus ;
2266
+ bridge -> ops = ops ;
2267
+ bridge -> msi = msi ;
2194
2268
2195
- pcibios_add_bus (b );
2196
-
2197
- /* Create legacy_io and legacy_mem files for this bus */
2198
- pci_create_legacy_files (b );
2199
-
2200
- if (parent )
2201
- dev_info (parent , "PCI host bridge to bus %s\n" , dev_name (& b -> dev ));
2202
- else
2203
- printk (KERN_INFO "PCI host bridge to bus %s\n" , dev_name (& b -> dev ));
2204
-
2205
- /* Add initial resources to the bus */
2206
- resource_list_for_each_entry_safe (window , n , resources ) {
2207
- list_move_tail (& window -> node , & bridge -> windows );
2208
- res = window -> res ;
2209
- offset = window -> offset ;
2210
- if (res -> flags & IORESOURCE_BUS )
2211
- pci_bus_insert_busn_res (b , bus , res -> end );
2212
- else
2213
- pci_bus_add_resource (b , res , 0 );
2214
- if (offset ) {
2215
- if (resource_type (res ) == IORESOURCE_IO )
2216
- fmt = " (bus address [%#06llx-%#06llx])" ;
2217
- else
2218
- fmt = " (bus address [%#010llx-%#010llx])" ;
2219
- snprintf (bus_addr , sizeof (bus_addr ), fmt ,
2220
- (unsigned long long ) (res -> start - offset ),
2221
- (unsigned long long ) (res -> end - offset ));
2222
- } else
2223
- bus_addr [0 ] = '\0' ;
2224
- dev_info (& b -> dev , "root bus resource %pR%s\n" , res , bus_addr );
2225
- }
2269
+ error = pci_register_host_bridge (bridge );
2270
+ if (error < 0 )
2271
+ goto err_out ;
2226
2272
2227
- down_write (& pci_bus_sem );
2228
- list_add_tail (& b -> node , & pci_root_buses );
2229
- up_write (& pci_bus_sem );
2273
+ return bridge -> bus ;
2230
2274
2231
- return b ;
2232
-
2233
- class_dev_reg_err :
2234
- put_device (& bridge -> dev );
2235
- device_unregister (& bridge -> dev );
2236
2275
err_out :
2237
- kfree (b );
2276
+ kfree (bridge );
2238
2277
return NULL ;
2239
2278
}
2279
+
2280
+ struct pci_bus * pci_create_root_bus (struct device * parent , int bus ,
2281
+ struct pci_ops * ops , void * sysdata , struct list_head * resources )
2282
+ {
2283
+ return pci_create_root_bus_msi (parent , bus , ops , sysdata , resources ,
2284
+ NULL );
2285
+ }
2240
2286
EXPORT_SYMBOL_GPL (pci_create_root_bus );
2241
2287
2242
2288
int pci_bus_insert_busn_res (struct pci_bus * b , int bus , int bus_max )
@@ -2317,12 +2363,10 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
2317
2363
break ;
2318
2364
}
2319
2365
2320
- b = pci_create_root_bus (parent , bus , ops , sysdata , resources );
2366
+ b = pci_create_root_bus_msi (parent , bus , ops , sysdata , resources , msi );
2321
2367
if (!b )
2322
2368
return NULL ;
2323
2369
2324
- b -> msi = msi ;
2325
-
2326
2370
if (!found ) {
2327
2371
dev_info (& b -> dev ,
2328
2372
"No busn resource found for root bus, will use [bus %02x-ff]\n" ,
0 commit comments