OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [hotplug/] [pci_hotplug_util.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.