Subversion Repositories shark

Rev

Rev 430 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
428 giacomo 1
/*
2
 * drivers/pci/pci-driver.c
3
 *
4
 */
5
 
430 giacomo 6
#include <linuxcomp.h>
7
 
428 giacomo 8
#include <linux/pci.h>
9
#include <linux/module.h>
10
#include <linux/init.h>
11
#include <linux/device.h>
12
#include <linux/pci-dynids.h>
13
#include "pci.h"
14
 
15
/*
16
 *  Registration of PCI drivers and handling of hot-pluggable devices.
17
 */
18
 
19
/**
20
 * pci_match_one_device - Tell if a PCI device structure has a matching
21
 *                        PCI device id structure
22
 * @id: single PCI device id structure to match
23
 * @dev: the PCI device structure to match against
24
 *
25
 * Returns the matching pci_device_id structure or %NULL if there is no match.
26
 */
27
 
28
static inline const struct pci_device_id *
29
pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
30
{
31
        if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
32
            (id->device == PCI_ANY_ID || id->device == dev->device) &&
33
            (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
34
            (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
35
            !((id->class ^ dev->class) & id->class_mask))
36
                return id;
37
        return NULL;
38
}
39
 
40
/*
41
 * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
42
 */
43
 
44
#ifdef CONFIG_HOTPLUG
45
/**
46
 * pci_device_probe_dynamic()
47
 *
48
 * Walk the dynamic ID list looking for a match.
49
 * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
50
 */
51
static int
52
pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
53
{
54
        int error = -ENODEV;
55
        struct list_head *pos;
56
        struct dynid *dynid;
57
 
58
        spin_lock(&drv->dynids.lock);
59
        list_for_each(pos, &drv->dynids.list) {
60
                dynid = list_entry(pos, struct dynid, node);
61
                if (pci_match_one_device(&dynid->id, pci_dev)) {
62
                        spin_unlock(&drv->dynids.lock);
63
                        error = drv->probe(pci_dev, &dynid->id);
64
                        if (error >= 0) {
65
                                pci_dev->driver = drv;
66
                                return 0;
67
                        }
68
                        return error;
69
                }
70
        }
71
        spin_unlock(&drv->dynids.lock);
72
        return error;
73
}
74
 
75
static inline void
76
dynid_init(struct dynid *dynid)
77
{
78
        memset(dynid, 0, sizeof(*dynid));
79
        INIT_LIST_HEAD(&dynid->node);
80
}
81
 
82
/**
83
 * store_new_id
84
 *
85
 * Adds a new dynamic pci device ID to this driver,
86
 * and causes the driver to probe for all devices again.
87
 */
88
static inline ssize_t
89
store_new_id(struct device_driver *driver, const char *buf, size_t count)
90
{
91
        struct dynid *dynid;
92
        struct bus_type * bus;
93
        struct pci_driver *pdrv = to_pci_driver(driver);
94
        __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
95
                subdevice=PCI_ANY_ID, class=0, class_mask=0;
96
        unsigned long driver_data=0;
97
        int fields=0;
98
 
99
        fields = sscanf(buf, "%x %x %x %x %x %x %lux",
100
                        &vendor, &device, &subvendor, &subdevice,
101
                        &class, &class_mask, &driver_data);
102
        if (fields < 0)
103
                return -EINVAL;
104
 
105
        dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
106
        if (!dynid)
107
                return -ENOMEM;
108
        dynid_init(dynid);
109
 
110
        dynid->id.vendor = vendor;
111
        dynid->id.device = device;
112
        dynid->id.subvendor = subvendor;
113
        dynid->id.subdevice = subdevice;
114
        dynid->id.class = class;
115
        dynid->id.class_mask = class_mask;
116
        dynid->id.driver_data = pdrv->dynids.use_driver_data ?
117
                driver_data : 0UL;
118
 
119
        spin_lock(&pdrv->dynids.lock);
120
        list_add_tail(&pdrv->dynids.list, &dynid->node);
121
        spin_unlock(&pdrv->dynids.lock);
122
 
123
        bus = get_bus(pdrv->driver.bus);
124
        if (bus) {
125
                if (get_driver(&pdrv->driver)) {
126
                        down_write(&bus->subsys.rwsem);
127
                        driver_attach(&pdrv->driver);
128
                        up_write(&bus->subsys.rwsem);
129
                        put_driver(&pdrv->driver);
130
                }
131
                put_bus(bus);
132
        }
133
 
134
        return count;
135
}
136
 
137
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
138
static inline void
139
pci_init_dynids(struct pci_dynids *dynids)
140
{
141
        memset(dynids, 0, sizeof(*dynids));
142
        spin_lock_init(&dynids->lock);
143
        INIT_LIST_HEAD(&dynids->list);
144
}
145
 
146
static void
147
pci_free_dynids(struct pci_driver *drv)
148
{
149
        struct list_head *pos, *n;
150
        struct dynid *dynid;
151
 
152
        spin_lock(&drv->dynids.lock);
153
        list_for_each_safe(pos, n, &drv->dynids.list) {
154
                dynid = list_entry(pos, struct dynid, node);
155
                list_del(&dynid->node);
156
                kfree(dynid);
157
        }
158
        spin_unlock(&drv->dynids.lock);
159
}
160
 
161
static int
162
pci_create_newid_file(struct pci_driver *drv)
163
{
164
        int error = 0;
165
        if (drv->probe != NULL)
166
                error = sysfs_create_file(&drv->driver.kobj,
167
                                          &driver_attr_new_id.attr);
168
        return error;
169
}
170
 
171
static int
172
pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
173
{
174
        struct list_head *pos;
175
        struct dynid *dynid;
176
 
177
        spin_lock(&pci_drv->dynids.lock);
178
        list_for_each(pos, &pci_drv->dynids.list) {
179
                dynid = list_entry(pos, struct dynid, node);
180
                if (pci_match_one_device(&dynid->id, pci_dev)) {
181
                        spin_unlock(&pci_drv->dynids.lock);
182
                        return 1;
183
                }
184
        }
185
        spin_unlock(&pci_drv->dynids.lock);
186
        return 0;
187
}
188
 
189
#else /* !CONFIG_HOTPLUG */
190
static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
191
{
192
        return -ENODEV;
193
}
194
static inline void dynid_init(struct dynid *dynid) {}
195
static inline void pci_init_dynids(struct pci_dynids *dynids) {}
196
static inline void pci_free_dynids(struct pci_driver *drv) {}
197
static inline int pci_create_newid_file(struct pci_driver *drv)
198
{
199
        return 0;
200
}
201
static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
202
{
203
        return 0;
204
}
205
#endif
206
 
207
/**
208
 * pci_match_device - Tell if a PCI device structure has a matching
209
 *                    PCI device id structure
210
 * @ids: array of PCI device id structures to search in
211
 * @dev: the PCI device structure to match against
212
 *
213
 * Used by a driver to check whether a PCI device present in the
214
 * system is in its list of supported devices.Returns the matching
215
 * pci_device_id structure or %NULL if there is no match.
216
 */
217
const struct pci_device_id *
218
pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
219
{
220
        while (ids->vendor || ids->subvendor || ids->class_mask) {
221
                if (pci_match_one_device(ids, dev))
222
                        return ids;
223
                ids++;
224
        }
225
        return NULL;
226
}
227
 
228
/**
229
 * pci_device_probe_static()
230
 *
231
 * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
232
 */
233
static int
234
pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
235
{                  
236
        int error = -ENODEV;
237
        const struct pci_device_id *id;
238
 
239
        if (!drv->id_table)
240
                return error;
241
        id = pci_match_device(drv->id_table, pci_dev);
242
        if (id)
243
                error = drv->probe(pci_dev, id);
244
        if (error >= 0) {
245
                pci_dev->driver = drv;
246
                return 0;
247
        }
248
        return error;
249
}
250
 
251
/**
252
 * __pci_device_probe()
253
 *
254
 * returns 0  on success, else error.
255
 * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
256
 */
257
static int
258
__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
259
{                  
260
        int error = 0;
261
 
262
        if (!pci_dev->driver && drv->probe) {
263
                error = pci_device_probe_static(drv, pci_dev);
264
                if (error == -ENODEV)
265
                        error = pci_device_probe_dynamic(drv, pci_dev);
266
        }
267
        return error;
268
}
269
 
270
static int pci_device_probe(struct device * dev)
271
{
272
        int error = 0;
273
        struct pci_driver *drv;
274
        struct pci_dev *pci_dev;
275
 
276
        drv = to_pci_driver(dev->driver);
277
        pci_dev = to_pci_dev(dev);
278
        pci_dev_get(pci_dev);
279
        error = __pci_device_probe(drv, pci_dev);
280
        if (error)
281
                pci_dev_put(pci_dev);
282
 
283
        return error;
284
}
285
 
286
static int pci_device_remove(struct device * dev)
287
{
288
        struct pci_dev * pci_dev = to_pci_dev(dev);
289
        struct pci_driver * drv = pci_dev->driver;
290
 
291
        if (drv) {
292
                if (drv->remove)
293
                        drv->remove(pci_dev);
294
                pci_dev->driver = NULL;
295
        }
296
        pci_dev_put(pci_dev);
297
        return 0;
298
}
299
 
300
static int pci_device_suspend(struct device * dev, u32 state)
301
{
302
        struct pci_dev * pci_dev = to_pci_dev(dev);
303
        struct pci_driver * drv = pci_dev->driver;
304
 
305
        if (drv && drv->suspend)
306
                return drv->suspend(pci_dev,state);
307
        return 0;
308
}
309
 
310
static int pci_device_resume(struct device * dev)
311
{
312
        struct pci_dev * pci_dev = to_pci_dev(dev);
313
        struct pci_driver * drv = pci_dev->driver;
314
 
315
        if (drv && drv->resume)
316
                drv->resume(pci_dev);
317
        return 0;
318
}
319
 
320
 
321
#define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
322
#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
323
 
324
static ssize_t
325
pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
326
{
327
        struct device_driver *driver = kobj_to_pci_driver(kobj);
328
        struct driver_attribute *dattr = attr_to_driver_attribute(attr);
329
        ssize_t ret = 0;
330
 
331
        if (get_driver(driver)) {
332
                if (dattr->show)
333
                        ret = dattr->show(driver, buf);
334
                put_driver(driver);
335
        }
336
        return ret;
337
}
338
 
339
static ssize_t
340
pci_driver_attr_store(struct kobject * kobj, struct attribute *attr,
341
                      const char *buf, size_t count)
342
{
343
        struct device_driver *driver = kobj_to_pci_driver(kobj);
344
        struct driver_attribute *dattr = attr_to_driver_attribute(attr);
345
        ssize_t ret = 0;
346
 
347
        if (get_driver(driver)) {
348
                if (dattr->store)
349
                        ret = dattr->store(driver, buf, count);
350
                put_driver(driver);
351
        }
352
        return ret;
353
}
354
 
355
static struct sysfs_ops pci_driver_sysfs_ops = {
356
        .show = pci_driver_attr_show,
357
        .store = pci_driver_attr_store,
358
};
359
static struct kobj_type pci_driver_kobj_type = {
360
        .sysfs_ops = &pci_driver_sysfs_ops,
361
};
362
 
363
static int
364
pci_populate_driver_dir(struct pci_driver *drv)
365
{
366
        return pci_create_newid_file(drv);
367
}
368
 
369
/**
370
 * pci_register_driver - register a new pci driver
371
 * @drv: the driver structure to register
372
 *
373
 * Adds the driver structure to the list of registered drivers
374
 * Returns the number of pci devices which were claimed by the driver
375
 * during registration.  The driver remains registered even if the
376
 * return value is zero.
377
 */
378
int
379
pci_register_driver(struct pci_driver *drv)
380
{
381
        int count = 0;
382
 
383
        /* initialize common driver fields */
384
        drv->driver.name = drv->name;
385
        drv->driver.bus = &pci_bus_type;
386
        drv->driver.probe = pci_device_probe;
387
        drv->driver.remove = pci_device_remove;
388
        drv->driver.kobj.ktype = &pci_driver_kobj_type;
389
        pci_init_dynids(&drv->dynids);
390
 
391
        /* register with core */
392
        count = driver_register(&drv->driver);
393
 
394
        if (count >= 0) {
395
                pci_populate_driver_dir(drv);
396
        }
397
 
398
        return count ? count : 1;
399
}
400
 
401
/**
402
 * pci_unregister_driver - unregister a pci driver
403
 * @drv: the driver structure to unregister
404
 *
405
 * Deletes the driver structure from the list of registered PCI drivers,
406
 * gives it a chance to clean up by calling its remove() function for
407
 * each device it was responsible for, and marks those devices as
408
 * driverless.
409
 */
410
 
411
void
412
pci_unregister_driver(struct pci_driver *drv)
413
{
414
        driver_unregister(&drv->driver);
415
        pci_free_dynids(drv);
416
}
417
 
418
static struct pci_driver pci_compat_driver = {
419
        .name = "compat"
420
};
421
 
422
/**
423
 * pci_dev_driver - get the pci_driver of a device
424
 * @dev: the device to query
425
 *
426
 * Returns the appropriate pci_driver structure or %NULL if there is no
427
 * registered driver for the device.
428
 */
429
struct pci_driver *
430
pci_dev_driver(const struct pci_dev *dev)
431
{
432
        if (dev->driver)
433
                return dev->driver;
434
        else {
435
                int i;
436
                for(i=0; i<=PCI_ROM_RESOURCE; i++)
437
                        if (dev->resource[i].flags & IORESOURCE_BUSY)
438
                                return &pci_compat_driver;
439
        }
440
        return NULL;
441
}
442
 
443
/**
444
 * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure
445
 * @ids: array of PCI device id structures to search in
446
 * @dev: the PCI device structure to match against
447
 *
448
 * Used by a driver to check whether a PCI device present in the
449
 * system is in its list of supported devices.Returns the matching
450
 * pci_device_id structure or %NULL if there is no match.
451
 */
452
static int pci_bus_match(struct device * dev, struct device_driver * drv)
453
{
454
        const struct pci_dev * pci_dev = to_pci_dev(dev);
455
        struct pci_driver * pci_drv = to_pci_driver(drv);
456
        const struct pci_device_id * ids = pci_drv->id_table;
457
        const struct pci_device_id *found_id;
458
 
459
        if (!ids)
460
                return 0;
461
 
462
        found_id = pci_match_device(ids, pci_dev);
463
        if (found_id)
464
                return 1;
465
 
466
        return pci_bus_match_dynids(pci_dev, pci_drv);
467
}
468
 
469
/**
470
 * pci_dev_get - increments the reference count of the pci device structure
471
 * @dev: the device being referenced
472
 *
473
 * Each live reference to a device should be refcounted.
474
 *
475
 * Drivers for PCI devices should normally record such references in
476
 * their probe() methods, when they bind to a device, and release
477
 * them by calling pci_dev_put(), in their disconnect() methods.
478
 *
479
 * A pointer to the device with the incremented reference counter is returned.
480
 */
481
struct pci_dev *pci_dev_get(struct pci_dev *dev)
482
{
483
        struct device *tmp;
484
 
485
        if (!dev)
486
                return NULL;
487
 
488
        tmp = get_device(&dev->dev);
489
        if (tmp)        
490
                return to_pci_dev(tmp);
491
        else
492
                return NULL;
493
}
494
 
495
/**
496
 * pci_dev_put - release a use of the pci device structure
497
 * @dev: device that's been disconnected
498
 *
499
 * Must be called when a user of a device is finished with it.  When the last
500
 * user of the device calls this function, the memory of the device is freed.
501
 */
502
void pci_dev_put(struct pci_dev *dev)
503
{
504
        if (dev)
505
                put_device(&dev->dev);
506
}
507
 
508
#ifndef CONFIG_HOTPLUG
509
int pci_hotplug (struct device *dev, char **envp, int num_envp,
510
                 char *buffer, int buffer_size)
511
{
512
        return -ENODEV;
513
}
514
#endif
515
 
516
struct bus_type pci_bus_type = {
517
        .name           = "pci",
518
        .match          = pci_bus_match,
519
        .hotplug        = pci_hotplug,
520
        .suspend        = pci_device_suspend,
521
        .resume         = pci_device_resume,
522
};
523
 
456 giacomo 524
int __init pci_driver_init(void)
428 giacomo 525
{
526
        return bus_register(&pci_bus_type);
527
}
528
 
529
postcore_initcall(pci_driver_init);
530
 
531
EXPORT_SYMBOL(pci_match_device);
532
EXPORT_SYMBOL(pci_register_driver);
533
EXPORT_SYMBOL(pci_unregister_driver);
534
EXPORT_SYMBOL(pci_dev_driver);
535
EXPORT_SYMBOL(pci_bus_type);
536
EXPORT_SYMBOL(pci_dev_get);
537
EXPORT_SYMBOL(pci_dev_put);