added mtd driver
[linux-2.4.git] / drivers / hotplug / pci_hotplug_util.c
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
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  */
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  */
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  */
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  */
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  */
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  */
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
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
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
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
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
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
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
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
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
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
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