@@ -26,21 +26,6 @@ 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-
4429static int p2sb_get_devfn (unsigned int * devfn )
4530{
4631 unsigned int fn = P2SB_DEVFN_DEFAULT ;
@@ -54,16 +39,8 @@ static int p2sb_get_devfn(unsigned int *devfn)
5439 return 0 ;
5540}
5641
57- static bool p2sb_valid_resource (struct resource * res )
58- {
59- if (res -> flags )
60- return true;
61-
62- return false;
63- }
64-
6542/* Copy resource from the first BAR of the device in question */
66- static void p2sb_read_bar0 (struct pci_dev * pdev , struct resource * mem )
43+ static int p2sb_read_bar0 (struct pci_dev * pdev , struct resource * mem )
6744{
6845 struct resource * bar0 = & pdev -> resource [0 ];
6946
@@ -79,64 +56,47 @@ static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem)
7956 mem -> end = bar0 -> end ;
8057 mem -> flags = bar0 -> flags ;
8158 mem -> desc = bar0 -> desc ;
59+
60+ return 0 ;
8261}
8362
84- static void p2sb_scan_and_cache_devfn (struct pci_bus * bus , unsigned int devfn )
63+ static int p2sb_scan_and_read (struct pci_bus * bus , unsigned int devfn , struct resource * mem )
8564{
86- struct p2sb_res_cache * cache = & p2sb_resources [PCI_FUNC (devfn )];
8765 struct pci_dev * pdev ;
66+ int ret ;
8867
8968 pdev = pci_scan_single_device (bus , devfn );
9069 if (!pdev )
91- return ;
70+ return - ENODEV ;
9271
93- p2sb_read_bar0 (pdev , & cache -> res );
94- cache -> bus_dev_id = bus -> dev .id ;
72+ ret = p2sb_read_bar0 (pdev , mem );
9573
9674 pci_stop_and_remove_bus_device (pdev );
97- return ;
98- }
99-
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 ;
75+ return ret ;
13576}
13677
137- static int p2sb_cache_resources (void )
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 )
13898{
139- struct pci_bus * bus ;
99+ struct pci_dev * pdev_p2sb ;
140100 unsigned int devfn_p2sb ;
141101 u32 value = P2SBC_HIDE ;
142102 int ret ;
@@ -146,89 +106,39 @@ static int p2sb_cache_resources(void)
146106 if (ret )
147107 return ret ;
148108
149- bus = p2sb_get_bus (NULL );
150- if (!bus )
151- return - ENODEV ;
109+ /* if @bus is NULL, use bus 0 in domain 0 */
110+ bus = bus ?: pci_find_bus (0 , 0 );
152111
153112 /*
154113 * Prevent concurrent PCI bus scan from seeing the P2SB device and
155114 * removing via sysfs while it is temporarily exposed.
156115 */
157116 pci_lock_rescan_remove ();
158117
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- */
118+ /* Unhide the P2SB device, if needed */
164119 pci_bus_read_config_dword (bus , devfn_p2sb , P2SBC , & value );
165120 if (value & P2SBC_HIDE )
166121 pci_bus_write_config_dword (bus , devfn_p2sb , P2SBC , 0 );
167122
168- ret = p2sb_scan_and_cache (bus , devfn_p2sb );
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 );
169129
170130 /* Hide the P2SB device, if it was hidden */
171131 if (value & P2SBC_HIDE )
172132 pci_bus_write_config_dword (bus , devfn_p2sb , P2SBC , P2SBC_HIDE );
173133
174134 pci_unlock_rescan_remove ();
175135
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 ;
197-
198- bus = p2sb_get_bus (bus );
199- if (!bus )
200- return - ENODEV ;
201-
202- if (!devfn ) {
203- ret = p2sb_get_devfn (& devfn );
204- if (ret )
205- return ret ;
206- }
136+ if (ret )
137+ return ret ;
207138
208- cache = & p2sb_resources [PCI_FUNC (devfn )];
209- if (cache -> bus_dev_id != bus -> dev .id )
139+ if (mem -> flags == 0 )
210140 return - ENODEV ;
211141
212- if (!p2sb_valid_resource (& cache -> res ))
213- return - ENOENT ;
214-
215- memcpy (mem , & cache -> res , sizeof (* mem ));
216142 return 0 ;
217143}
218144EXPORT_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