1 /*
2 * PCI HotPlug Utility functions
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <greg@kroah.com>
26 *
27 */
28
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/pci.h>
35 #include "pci_hotplug.h"
36
37
38 #if !defined(CONFIG_HOTPLUG_PCI_MODULE)
39 #define MY_NAME "pci_hotplug"
40 #else
41 #define MY_NAME THIS_MODULE->name
42 #endif
43
44 #define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
45 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
46 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
47 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
48
49
50 /* local variables */
51 static int debug;
52
build_dev(struct pci_bus * bus,unsigned int devfn,struct pci_dev ** pci_dev)53 static int build_dev (struct pci_bus *bus, unsigned int devfn, struct pci_dev **pci_dev)
54 {
55 struct pci_dev *my_dev;
56
57 my_dev = kmalloc (sizeof (struct pci_dev), GFP_KERNEL);
58 if (!my_dev)
59 return -ENOMEM;
60
61 memset(my_dev, 0, sizeof(struct pci_dev));
62
63 my_dev->devfn = devfn;
64 my_dev->bus = bus;
65 my_dev->sysdata = bus->sysdata;
66 *pci_dev = my_dev;
67 return 0;
68 }
69
70 /**
71 * pci_bus_read_config_byte - read a byte from a pci device
72 * @bus: pointer to the parent bus of the pci device to read from
73 * @devfn: the device / function of the pci device to read from
74 * @where: the location in the pci address space to read from
75 * @value: pointer to where to place the data read
76 *
77 * Like pci_read_config_byte() but works for pci devices that do not have a
78 * pci_dev structure set up yet.
79 * Returns 0 on success.
80 */
pci_bus_read_config_byte(struct pci_bus * bus,unsigned int devfn,int where,u8 * value)81 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *value)
82 {
83 struct pci_dev *dev = NULL;
84 int result;
85
86 dbg("%p, %d, %d, %p\n", bus, devfn, where, value);
87 dev = pci_find_slot(bus->number, devfn);
88 if (dev) {
89 dbg("using native pci_dev\n");
90 return pci_read_config_byte (dev, where, value);
91 }
92
93 result = build_dev(bus, devfn, &dev);
94 if (result)
95 return result;
96 result = pci_read_config_byte(dev, where, value);
97 kfree (dev);
98 return result;
99 }
100
101 /**
102 * pci_bus_read_config_word - read a word from a pci device
103 * @bus: pointer to the parent bus of the pci device to read from
104 * @devfn: the device / function of the pci device to read from
105 * @where: the location on the pci address space to read from
106 * @value: pointer to where to place the data read
107 *
108 * Like pci_read_config_word() but works for pci devices that do not have a
109 * pci_dev structure set up yet.
110 * Returns 0 on success.
111 */
pci_bus_read_config_word(struct pci_bus * bus,unsigned int devfn,int where,u16 * value)112 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *value)
113 {
114 struct pci_dev *dev = NULL;
115 int result;
116
117 dbg("%p, %d, %d, %p\n", bus, devfn, where, value);
118 dev = pci_find_slot(bus->number, devfn);
119 if (dev) {
120 dbg("using native pci_dev\n");
121 return pci_read_config_word (dev, where, value);
122 }
123
124 result = build_dev(bus, devfn, &dev);
125 if (result)
126 return result;
127 result = pci_read_config_word(dev, where, value);
128 kfree (dev);
129 return result;
130 }
131
132 /**
133 * pci_bus_read_config_dword - read a dword from a pci device
134 * @bus: pointer to the parent bus of the pci device to read from
135 * @devfn: the device / function of the pci device to read from
136 * @where: the location on the pci address space to read from
137 * @value: pointer to where to place the data read
138 *
139 * Like pci_read_config_dword() but works for pci devices that do not have a
140 * pci_dev structure set up yet.
141 * Returns 0 on success.
142 */
pci_bus_read_config_dword(struct pci_bus * bus,unsigned int devfn,int where,u32 * value)143 int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *value)
144 {
145 struct pci_dev *dev = NULL;
146 int result;
147
148 dbg("%p, %d, %d, %p\n", bus, devfn, where, value);
149 dev = pci_find_slot(bus->number, devfn);
150 if (dev) {
151 dbg("using native pci_dev\n");
152 return pci_read_config_dword (dev, where, value);
153 }
154
155 result = build_dev(bus, devfn, &dev);
156 if (result)
157 return result;
158 result = pci_read_config_dword(dev, where, value);
159 kfree (dev);
160 return result;
161 }
162
163 /**
164 * pci_bus_write_config_byte - write a byte to a pci device
165 * @bus: pointer to the parent bus of the pci device to read from
166 * @devfn: the device / function of the pci device to read from
167 * @where: the location on the pci address space to write to
168 * @value: the value to write to the pci device
169 *
170 * Like pci_write_config_byte() but works for pci devices that do not have a
171 * pci_dev structure set up yet.
172 * Returns 0 on success.
173 */
pci_bus_write_config_byte(struct pci_bus * bus,unsigned int devfn,int where,u8 value)174 int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 value)
175 {
176 struct pci_dev *dev = NULL;
177 int result;
178
179 dbg("%p, %d, %d, %d\n", bus, devfn, where, value);
180 dev = pci_find_slot(bus->number, devfn);
181 if (dev) {
182 dbg("using native pci_dev\n");
183 return pci_write_config_byte (dev, where, value);
184 }
185
186 result = build_dev(bus, devfn, &dev);
187 if (result)
188 return result;
189 result = pci_write_config_byte(dev, where, value);
190 kfree (dev);
191 return result;
192 }
193
194 /**
195 * pci_bus_write_config_word - write a word to a pci device
196 * @bus: pointer to the parent bus of the pci device to read from
197 * @devfn: the device / function of the pci device to read from
198 * @where: the location on the pci address space to write to
199 * @value: the value to write to the pci device
200 *
201 * Like pci_write_config_word() but works for pci devices that do not have a
202 * pci_dev structure set up yet.
203 * Returns 0 on success.
204 */
pci_bus_write_config_word(struct pci_bus * bus,unsigned int devfn,int where,u16 value)205 int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 value)
206 {
207 struct pci_dev *dev = NULL;
208 int result;
209
210 dbg("%p, %d, %d, %d\n", bus, devfn, where, value);
211 dev = pci_find_slot(bus->number, devfn);
212 if (dev) {
213 dbg("using native pci_dev\n");
214 return pci_write_config_word (dev, where, value);
215 }
216
217 result = build_dev(bus, devfn, &dev);
218 if (result)
219 return result;
220 result = pci_write_config_word(dev, where, value);
221 kfree (dev);
222 return result;
223 }
224
225 /**
226 * pci_bus_write_config_dword - write a dword to a pci device
227 * @bus: pointer to the parent bus of the pci device to read from
228 * @devfn: the device / function of the pci device to read from
229 * @where: the location on the pci address space to write to
230 * @value: the value to write to the pci device
231 *
232 * Like pci_write_config_dword() but works for pci devices that do not have a
233 * pci_dev structure set up yet.
234 * Returns 0 on success.
235 */
pci_bus_write_config_dword(struct pci_bus * bus,unsigned int devfn,int where,u32 value)236 int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 value)
237 {
238 struct pci_dev *dev = NULL;
239 int result;
240
241 dbg("%p, %d, %d, %d\n", bus, devfn, where, value);
242 dev = pci_find_slot(bus->number, devfn);
243 if (dev) {
244 dbg("using native pci_dev\n");
245 return pci_write_config_dword (dev, where, value);
246 }
247
248 result = build_dev(bus, devfn, &dev);
249 if (result)
250 return result;
251 result = pci_write_config_dword(dev, where, value);
252 kfree (dev);
253 return result;
254 }
255
256 /*
257 * This is code that scans the pci buses.
258 * Every bus and every function is presented to a custom
259 * function that can act upon it.
260 */
261
pci_visit_bus(struct pci_visit * fn,struct pci_bus_wrapped * wrapped_bus,struct pci_dev_wrapped * wrapped_parent)262 static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent)
263 {
264 struct list_head *ln;
265 struct pci_dev *dev;
266 struct pci_dev_wrapped wrapped_dev;
267 int result = 0;
268
269 dbg("scanning bus %02x\n", wrapped_bus->bus->number);
270
271 if (fn->pre_visit_pci_bus) {
272 result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent);
273 if (result)
274 return result;
275 }
276
277 ln = wrapped_bus->bus->devices.next;
278 while (ln != &wrapped_bus->bus->devices) {
279 dev = pci_dev_b(ln);
280 ln = ln->next;
281
282 memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
283 wrapped_dev.dev = dev;
284
285 result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus);
286 if (result)
287 return result;
288 }
289
290 if (fn->post_visit_pci_bus)
291 result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent);
292
293 return result;
294 }
295
296
pci_visit_bridge(struct pci_visit * fn,struct pci_dev_wrapped * wrapped_dev,struct pci_bus_wrapped * wrapped_parent)297 static int pci_visit_bridge (struct pci_visit * fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
298 {
299 struct pci_bus *bus = wrapped_dev->dev->subordinate;
300 struct pci_bus_wrapped wrapped_bus;
301 int result;
302
303 memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
304 wrapped_bus.bus = bus;
305
306 dbg("scanning bridge %02x, %02x\n", wrapped_dev->dev->devfn >> 3,
307 wrapped_dev->dev->devfn & 0x7);
308
309 if (fn->visit_pci_dev) {
310 result = fn->visit_pci_dev(wrapped_dev, wrapped_parent);
311 if (result)
312 return result;
313 }
314
315 result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev);
316 return result;
317 }
318
319
pci_visit_dev(struct pci_visit * fn,struct pci_dev_wrapped * wrapped_dev,struct pci_bus_wrapped * wrapped_parent)320 int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent)
321 {
322 struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL;
323 int result = 0;
324
325 if (!dev)
326 return 0;
327
328 if (fn->pre_visit_pci_dev) {
329 result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent);
330 if (result)
331 return result;
332 }
333
334 switch (dev->class >> 8) {
335 case PCI_CLASS_BRIDGE_PCI:
336 result = pci_visit_bridge(fn, wrapped_dev,
337 wrapped_parent);
338 if (result)
339 return result;
340 break;
341 default:
342 dbg("scanning device %02x, %02x\n",
343 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
344 if (fn->visit_pci_dev) {
345 result = fn->visit_pci_dev (wrapped_dev,
346 wrapped_parent);
347 if (result)
348 return result;
349 }
350 }
351
352 if (fn->post_visit_pci_dev)
353 result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent);
354
355 return result;
356 }
357
358 /* Compatibility wrapper functions */
359
alloc_bus(struct pci_ops * ops,u8 bus_nr)360 static struct pci_bus *alloc_bus(struct pci_ops *ops, u8 bus_nr)
361 {
362 struct pci_bus *bus = kmalloc(sizeof(struct pci_bus), GFP_KERNEL);
363 if (!bus)
364 return NULL;
365 memset(bus, 0, sizeof(struct pci_bus));
366 bus->number = bus_nr;
367 bus->ops = ops;
368 return bus;
369 }
370
pci_read_config_byte_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u8 * value)371 int pci_read_config_byte_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u8 *value)
372 {
373 int result;
374 struct pci_bus *bus = alloc_bus(ops, bus_nr);
375 if (!bus)
376 return -ENOMEM;
377 result = pci_bus_read_config_byte(bus, PCI_DEVFN(slot, function),
378 where, value);
379 kfree(bus);
380 return result;
381 }
382
pci_read_config_word_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u16 * value)383 int pci_read_config_word_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u16 *value)
384 {
385 int result;
386 struct pci_bus *bus = alloc_bus(ops, bus_nr);
387 if (!bus)
388 return -ENOMEM;
389 result = pci_bus_read_config_word(bus, PCI_DEVFN(slot, function),
390 where, value);
391 kfree(bus);
392 return result;
393 }
394
pci_read_config_dword_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u32 * value)395 int pci_read_config_dword_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u32 *value)
396 {
397 int result;
398 struct pci_bus *bus = alloc_bus(ops, bus_nr);
399 if (!bus)
400 return -ENOMEM;
401 result = pci_bus_read_config_dword(bus, PCI_DEVFN(slot, function),
402 where, value);
403 kfree(bus);
404 return result;
405 }
406
pci_write_config_byte_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u8 value)407 int pci_write_config_byte_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u8 value)
408 {
409 int result;
410 struct pci_bus *bus = alloc_bus(ops, bus_nr);
411 if (!bus)
412 return -ENOMEM;
413 result = pci_bus_write_config_byte(bus, PCI_DEVFN(slot, function),
414 where, value);
415 kfree(bus);
416 return result;
417 }
418
pci_write_config_word_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u16 value)419 int pci_write_config_word_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u16 value)
420 {
421 int result;
422 struct pci_bus *bus = alloc_bus(ops, bus_nr);
423 if (!bus)
424 return -ENOMEM;
425 result = pci_bus_write_config_word(bus, PCI_DEVFN(slot, function),
426 where, value);
427 kfree(bus);
428 return result;
429 }
430
pci_write_config_dword_nodev(struct pci_ops * ops,u8 bus_nr,u8 slot,u8 function,int where,u32 value)431 int pci_write_config_dword_nodev(struct pci_ops *ops, u8 bus_nr, u8 slot, u8 function, int where, u32 value)
432 {
433 int result;
434 struct pci_bus *bus = alloc_bus(ops, bus_nr);
435 if (!bus)
436 return -ENOMEM;
437 result = pci_bus_write_config_dword(bus, PCI_DEVFN(slot, function),
438 where, value);
439 kfree(bus);
440 return result;
441 }
442
443 EXPORT_SYMBOL(pci_visit_dev);
444 EXPORT_SYMBOL(pci_bus_read_config_byte);
445 EXPORT_SYMBOL(pci_bus_read_config_word);
446 EXPORT_SYMBOL(pci_bus_read_config_dword);
447 EXPORT_SYMBOL(pci_bus_write_config_byte);
448 EXPORT_SYMBOL(pci_bus_write_config_word);
449 EXPORT_SYMBOL(pci_bus_write_config_dword);
450 EXPORT_SYMBOL(pci_read_config_byte_nodev);
451 EXPORT_SYMBOL(pci_read_config_word_nodev);
452 EXPORT_SYMBOL(pci_read_config_dword_nodev);
453 EXPORT_SYMBOL(pci_write_config_byte_nodev);
454 EXPORT_SYMBOL(pci_write_config_word_nodev);
455 EXPORT_SYMBOL(pci_write_config_dword_nodev);
456
457