@@ -26,6 +26,21 @@ static const struct x86_cpu_id p2sb_cpu_ids[] = {
2626 {}
2727};
2828
29+ /*
30+ * Cache BAR0 of P2SB device functions 0 to 7.
31+ * TODO: The constant 8 is the number of functions that PCI specification
32+ * defines. Same definitions exist tree-wide. Unify this definition and
33+ * the other definitions then move to include/uapi/linux/pci.h.
34+ */
35+ #define NR_P2SB_RES_CACHE 8
36+
37+ struct p2sb_res_cache {
38+ u32 bus_dev_id ;
39+ struct resource res ;
40+ };
41+
42+ static struct p2sb_res_cache p2sb_resources [NR_P2SB_RES_CACHE ];
43+
2944static int p2sb_get_devfn (unsigned int * devfn )
3045{
3146 unsigned int fn = P2SB_DEVFN_DEFAULT ;
@@ -39,8 +54,16 @@ static int p2sb_get_devfn(unsigned int *devfn)
3954 return 0 ;
4055}
4156
57+ static bool p2sb_valid_resource (struct resource * res )
58+ {
59+ if (res -> flags )
60+ return true;
61+
62+ return false;
63+ }
64+
4265/* Copy resource from the first BAR of the device in question */
43- static int p2sb_read_bar0 (struct pci_dev * pdev , struct resource * mem )
66+ static void p2sb_read_bar0 (struct pci_dev * pdev , struct resource * mem )
4467{
4568 struct resource * bar0 = & pdev -> resource [0 ];
4669
@@ -56,47 +79,64 @@ static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem)
5679 mem -> end = bar0 -> end ;
5780 mem -> flags = bar0 -> flags ;
5881 mem -> desc = bar0 -> desc ;
59-
60- return 0 ;
6182}
6283
63- static int p2sb_scan_and_read (struct pci_bus * bus , unsigned int devfn , struct resource * mem )
84+ static void p2sb_scan_and_cache_devfn (struct pci_bus * bus , unsigned int devfn )
6485{
86+ struct p2sb_res_cache * cache = & p2sb_resources [PCI_FUNC (devfn )];
6587 struct pci_dev * pdev ;
66- int ret ;
6788
6889 pdev = pci_scan_single_device (bus , devfn );
6990 if (!pdev )
70- return - ENODEV ;
91+ return ;
7192
72- ret = p2sb_read_bar0 (pdev , mem );
93+ p2sb_read_bar0 (pdev , & cache -> res );
94+ cache -> bus_dev_id = bus -> dev .id ;
7395
7496 pci_stop_and_remove_bus_device (pdev );
75- return ret ;
97+ return ;
7698}
7799
78- /**
79- * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
80- * @bus: PCI bus to communicate with
81- * @devfn: PCI slot and function to communicate with
82- * @mem: memory resource to be filled in
83- *
84- * The BIOS prevents the P2SB device from being enumerated by the PCI
85- * subsystem, so we need to unhide and hide it back to lookup the BAR.
86- *
87- * if @bus is NULL, the bus 0 in domain 0 will be used.
88- * If @devfn is 0, it will be replaced by devfn of the P2SB device.
89- *
90- * Caller must provide a valid pointer to @mem.
91- *
92- * Locking is handled by pci_rescan_remove_lock mutex.
93- *
94- * Return:
95- * 0 on success or appropriate errno value on error.
96- */
97- int p2sb_bar (struct pci_bus * bus , unsigned int devfn , struct resource * mem )
100+ static int p2sb_scan_and_cache (struct pci_bus * bus , unsigned int devfn )
101+ {
102+ unsigned int slot , fn ;
103+
104+ if (PCI_FUNC (devfn ) == 0 ) {
105+ /*
106+ * When function number of the P2SB device is zero, scan it and
107+ * other function numbers, and if devices are available, cache
108+ * their BAR0s.
109+ */
110+ slot = PCI_SLOT (devfn );
111+ for (fn = 0 ; fn < NR_P2SB_RES_CACHE ; fn ++ )
112+ p2sb_scan_and_cache_devfn (bus , PCI_DEVFN (slot , fn ));
113+ } else {
114+ /* Scan the P2SB device and cache its BAR0 */
115+ p2sb_scan_and_cache_devfn (bus , devfn );
116+ }
117+
118+ if (!p2sb_valid_resource (& p2sb_resources [PCI_FUNC (devfn )].res ))
119+ return - ENOENT ;
120+
121+ return 0 ;
122+ }
123+
124+ static struct pci_bus * p2sb_get_bus (struct pci_bus * bus )
125+ {
126+ static struct pci_bus * p2sb_bus ;
127+
128+ bus = bus ?: p2sb_bus ;
129+ if (bus )
130+ return bus ;
131+
132+ /* Assume P2SB is on the bus 0 in domain 0 */
133+ p2sb_bus = pci_find_bus (0 , 0 );
134+ return p2sb_bus ;
135+ }
136+
137+ static int p2sb_cache_resources (void )
98138{
99- struct pci_dev * pdev_p2sb ;
139+ struct pci_bus * bus ;
100140 unsigned int devfn_p2sb ;
101141 u32 value = P2SBC_HIDE ;
102142 int ret ;
@@ -106,39 +146,89 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
106146 if (ret )
107147 return ret ;
108148
109- /* if @bus is NULL, use bus 0 in domain 0 */
110- bus = bus ?: pci_find_bus (0 , 0 );
149+ bus = p2sb_get_bus (NULL );
150+ if (!bus )
151+ return - ENODEV ;
111152
112153 /*
113154 * Prevent concurrent PCI bus scan from seeing the P2SB device and
114155 * removing via sysfs while it is temporarily exposed.
115156 */
116157 pci_lock_rescan_remove ();
117158
118- /* Unhide the P2SB device, if needed */
159+ /*
160+ * The BIOS prevents the P2SB device from being enumerated by the PCI
161+ * subsystem, so we need to unhide and hide it back to lookup the BAR.
162+ * Unhide the P2SB device here, if needed.
163+ */
119164 pci_bus_read_config_dword (bus , devfn_p2sb , P2SBC , & value );
120165 if (value & P2SBC_HIDE )
121166 pci_bus_write_config_dword (bus , devfn_p2sb , P2SBC , 0 );
122167
123- pdev_p2sb = pci_scan_single_device (bus , devfn_p2sb );
124- if (devfn )
125- ret = p2sb_scan_and_read (bus , devfn , mem );
126- else
127- ret = p2sb_read_bar0 (pdev_p2sb , mem );
128- pci_stop_and_remove_bus_device (pdev_p2sb );
168+ ret = p2sb_scan_and_cache (bus , devfn_p2sb );
129169
130170 /* Hide the P2SB device, if it was hidden */
131171 if (value & P2SBC_HIDE )
132172 pci_bus_write_config_dword (bus , devfn_p2sb , P2SBC , P2SBC_HIDE );
133173
134174 pci_unlock_rescan_remove ();
135175
136- if (ret )
137- return ret ;
176+ return ret ;
177+ }
178+
179+ /**
180+ * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
181+ * @bus: PCI bus to communicate with
182+ * @devfn: PCI slot and function to communicate with
183+ * @mem: memory resource to be filled in
184+ *
185+ * If @bus is NULL, the bus 0 in domain 0 will be used.
186+ * If @devfn is 0, it will be replaced by devfn of the P2SB device.
187+ *
188+ * Caller must provide a valid pointer to @mem.
189+ *
190+ * Return:
191+ * 0 on success or appropriate errno value on error.
192+ */
193+ int p2sb_bar (struct pci_bus * bus , unsigned int devfn , struct resource * mem )
194+ {
195+ struct p2sb_res_cache * cache ;
196+ int ret ;
138197
139- if (mem -> flags == 0 )
198+ bus = p2sb_get_bus (bus );
199+ if (!bus )
140200 return - ENODEV ;
141201
202+ if (!devfn ) {
203+ ret = p2sb_get_devfn (& devfn );
204+ if (ret )
205+ return ret ;
206+ }
207+
208+ cache = & p2sb_resources [PCI_FUNC (devfn )];
209+ if (cache -> bus_dev_id != bus -> dev .id )
210+ return - ENODEV ;
211+
212+ if (!p2sb_valid_resource (& cache -> res ))
213+ return - ENOENT ;
214+
215+ memcpy (mem , & cache -> res , sizeof (* mem ));
142216 return 0 ;
143217}
144218EXPORT_SYMBOL_GPL (p2sb_bar );
219+
220+ static int __init p2sb_fs_init (void )
221+ {
222+ p2sb_cache_resources ();
223+ return 0 ;
224+ }
225+
226+ /*
227+ * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can
228+ * not be locked in sysfs pci bus rescan path because of deadlock. To
229+ * avoid the deadlock, access to P2SB devices with the lock at an early
230+ * step in kernel initialization and cache required resources. This
231+ * should happen after subsys_initcall which initializes PCI subsystem
232+ * and before device_initcall which requires P2SB resources.
233+ */
234+ fs_initcall (p2sb_fs_init );
0 commit comments