direct-io.hg

view linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c @ 14330:a6316fc7a87f

pci back: Various fixes.

- remove superfluous call to pciback_field_is_dup()
- fix a variable type mismatch in pciback_field_is_dup()
- make readability improvements by using the OFFSET macro
- revises quirk data output via the sysfs quirks node so that
- displayed offset information includes base_offset.

Thanks to Jambunathan K. for giving such specific bug diagnosis.

Signed-off-by: Chris Bookholt <hap10@tycho.ncsc.mil>
author kfraser@localhost.localdomain
date Sat Mar 10 17:01:21 2007 +0000 (2007-03-10)
parents 10dc10473c3f
children 64ab7d443549
line source
1 /*
2 * PCI Stub Driver - Grabs devices in backend to be exported later
3 *
4 * Ryan Wilson <hap9@epoch.ncsc.mil>
5 * Chris Bookholt <hap10@epoch.ncsc.mil>
6 */
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/list.h>
10 #include <linux/spinlock.h>
11 #include <linux/kref.h>
12 #include <asm/atomic.h>
13 #include "pciback.h"
14 #include "conf_space.h"
15 #include "conf_space_quirks.h"
17 static char *pci_devs_to_hide = NULL;
18 module_param_named(hide, pci_devs_to_hide, charp, 0444);
20 struct pcistub_device_id {
21 struct list_head slot_list;
22 int domain;
23 unsigned char bus;
24 unsigned int devfn;
25 };
26 static LIST_HEAD(pcistub_device_ids);
27 static DEFINE_SPINLOCK(device_ids_lock);
29 struct pcistub_device {
30 struct kref kref;
31 struct list_head dev_list;
32 spinlock_t lock;
34 struct pci_dev *dev;
35 struct pciback_device *pdev; /* non-NULL if struct pci_dev is in use */
36 };
38 /* Access to pcistub_devices & seized_devices lists and the initialize_devices
39 * flag must be locked with pcistub_devices_lock
40 */
41 static DEFINE_SPINLOCK(pcistub_devices_lock);
42 static LIST_HEAD(pcistub_devices);
44 /* wait for device_initcall before initializing our devices
45 * (see pcistub_init_devices_late)
46 */
47 static int initialize_devices = 0;
48 static LIST_HEAD(seized_devices);
50 static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
51 {
52 struct pcistub_device *psdev;
54 dev_dbg(&dev->dev, "pcistub_device_alloc\n");
56 psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
57 if (!psdev)
58 return NULL;
60 psdev->dev = pci_dev_get(dev);
61 if (!psdev->dev) {
62 kfree(psdev);
63 return NULL;
64 }
66 kref_init(&psdev->kref);
67 spin_lock_init(&psdev->lock);
69 return psdev;
70 }
72 /* Don't call this directly as it's called by pcistub_device_put */
73 static void pcistub_device_release(struct kref *kref)
74 {
75 struct pcistub_device *psdev;
77 psdev = container_of(kref, struct pcistub_device, kref);
79 dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
81 /* Clean-up the device */
82 pciback_reset_device(psdev->dev);
83 pciback_config_free_dyn_fields(psdev->dev);
84 pciback_config_free_dev(psdev->dev);
85 kfree(pci_get_drvdata(psdev->dev));
86 pci_set_drvdata(psdev->dev, NULL);
88 pci_dev_put(psdev->dev);
90 kfree(psdev);
91 }
93 static inline void pcistub_device_get(struct pcistub_device *psdev)
94 {
95 kref_get(&psdev->kref);
96 }
98 static inline void pcistub_device_put(struct pcistub_device *psdev)
99 {
100 kref_put(&psdev->kref, pcistub_device_release);
101 }
103 static struct pcistub_device *pcistub_device_find(int domain, int bus,
104 int slot, int func)
105 {
106 struct pcistub_device *psdev = NULL;
107 unsigned long flags;
109 spin_lock_irqsave(&pcistub_devices_lock, flags);
111 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
112 if (psdev->dev != NULL
113 && domain == pci_domain_nr(psdev->dev->bus)
114 && bus == psdev->dev->bus->number
115 && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
116 pcistub_device_get(psdev);
117 goto out;
118 }
119 }
121 /* didn't find it */
122 psdev = NULL;
124 out:
125 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
126 return psdev;
127 }
129 static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev,
130 struct pcistub_device *psdev)
131 {
132 struct pci_dev *pci_dev = NULL;
133 unsigned long flags;
135 pcistub_device_get(psdev);
137 spin_lock_irqsave(&psdev->lock, flags);
138 if (!psdev->pdev) {
139 psdev->pdev = pdev;
140 pci_dev = psdev->dev;
141 }
142 spin_unlock_irqrestore(&psdev->lock, flags);
144 if (!pci_dev)
145 pcistub_device_put(psdev);
147 return pci_dev;
148 }
150 struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev,
151 int domain, int bus,
152 int slot, int func)
153 {
154 struct pcistub_device *psdev;
155 struct pci_dev *found_dev = NULL;
156 unsigned long flags;
158 spin_lock_irqsave(&pcistub_devices_lock, flags);
160 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
161 if (psdev->dev != NULL
162 && domain == pci_domain_nr(psdev->dev->bus)
163 && bus == psdev->dev->bus->number
164 && PCI_DEVFN(slot, func) == psdev->dev->devfn) {
165 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
166 break;
167 }
168 }
170 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
171 return found_dev;
172 }
174 struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev,
175 struct pci_dev *dev)
176 {
177 struct pcistub_device *psdev;
178 struct pci_dev *found_dev = NULL;
179 unsigned long flags;
181 spin_lock_irqsave(&pcistub_devices_lock, flags);
183 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
184 if (psdev->dev == dev) {
185 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
186 break;
187 }
188 }
190 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
191 return found_dev;
192 }
194 void pcistub_put_pci_dev(struct pci_dev *dev)
195 {
196 struct pcistub_device *psdev, *found_psdev = NULL;
197 unsigned long flags;
199 spin_lock_irqsave(&pcistub_devices_lock, flags);
201 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
202 if (psdev->dev == dev) {
203 found_psdev = psdev;
204 break;
205 }
206 }
208 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
210 /* Cleanup our device
211 * (so it's ready for the next domain)
212 */
213 pciback_reset_device(found_psdev->dev);
214 pciback_config_free_dyn_fields(found_psdev->dev);
215 pciback_config_reset_dev(found_psdev->dev);
217 spin_lock_irqsave(&found_psdev->lock, flags);
218 found_psdev->pdev = NULL;
219 spin_unlock_irqrestore(&found_psdev->lock, flags);
221 pcistub_device_put(found_psdev);
222 }
224 static int __devinit pcistub_match_one(struct pci_dev *dev,
225 struct pcistub_device_id *pdev_id)
226 {
227 /* Match the specified device by domain, bus, slot, func and also if
228 * any of the device's parent bridges match.
229 */
230 for (; dev != NULL; dev = dev->bus->self) {
231 if (pci_domain_nr(dev->bus) == pdev_id->domain
232 && dev->bus->number == pdev_id->bus
233 && dev->devfn == pdev_id->devfn)
234 return 1;
236 /* Sometimes topmost bridge links to itself. */
237 if (dev == dev->bus->self)
238 break;
239 }
241 return 0;
242 }
244 static int __devinit pcistub_match(struct pci_dev *dev)
245 {
246 struct pcistub_device_id *pdev_id;
247 unsigned long flags;
248 int found = 0;
250 spin_lock_irqsave(&device_ids_lock, flags);
251 list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) {
252 if (pcistub_match_one(dev, pdev_id)) {
253 found = 1;
254 break;
255 }
256 }
257 spin_unlock_irqrestore(&device_ids_lock, flags);
259 return found;
260 }
262 static int __devinit pcistub_init_device(struct pci_dev *dev)
263 {
264 struct pciback_dev_data *dev_data;
265 int err = 0;
267 dev_dbg(&dev->dev, "initializing...\n");
269 /* The PCI backend is not intended to be a module (or to work with
270 * removable PCI devices (yet). If it were, pciback_config_free()
271 * would need to be called somewhere to free the memory allocated
272 * here and then to call kfree(pci_get_drvdata(psdev->dev)).
273 */
274 dev_data = kzalloc(sizeof(*dev_data), GFP_ATOMIC);
275 if (!dev_data) {
276 err = -ENOMEM;
277 goto out;
278 }
279 pci_set_drvdata(dev, dev_data);
281 dev_dbg(&dev->dev, "initializing config\n");
282 err = pciback_config_init_dev(dev);
283 if (err)
284 goto out;
286 /* HACK: Force device (& ACPI) to determine what IRQ it's on - we
287 * must do this here because pcibios_enable_device may specify
288 * the pci device's true irq (and possibly its other resources)
289 * if they differ from what's in the configuration space.
290 * This makes the assumption that the device's resources won't
291 * change after this point (otherwise this code may break!)
292 */
293 dev_dbg(&dev->dev, "enabling device\n");
294 err = pci_enable_device(dev);
295 if (err)
296 goto config_release;
298 /* Now disable the device (this also ensures some private device
299 * data is setup before we export)
300 */
301 dev_dbg(&dev->dev, "reset device\n");
302 pciback_reset_device(dev);
304 return 0;
306 config_release:
307 pciback_config_free_dev(dev);
309 out:
310 pci_set_drvdata(dev, NULL);
311 kfree(dev_data);
312 return err;
313 }
315 /*
316 * Because some initialization still happens on
317 * devices during fs_initcall, we need to defer
318 * full initialization of our devices until
319 * device_initcall.
320 */
321 static int __init pcistub_init_devices_late(void)
322 {
323 struct pcistub_device *psdev;
324 unsigned long flags;
325 int err = 0;
327 pr_debug("pciback: pcistub_init_devices_late\n");
329 spin_lock_irqsave(&pcistub_devices_lock, flags);
331 while (!list_empty(&seized_devices)) {
332 psdev = container_of(seized_devices.next,
333 struct pcistub_device, dev_list);
334 list_del(&psdev->dev_list);
336 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
338 err = pcistub_init_device(psdev->dev);
339 if (err) {
340 dev_err(&psdev->dev->dev,
341 "error %d initializing device\n", err);
342 kfree(psdev);
343 psdev = NULL;
344 }
346 spin_lock_irqsave(&pcistub_devices_lock, flags);
348 if (psdev)
349 list_add_tail(&psdev->dev_list, &pcistub_devices);
350 }
352 initialize_devices = 1;
354 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
356 return 0;
357 }
359 static int __devinit pcistub_seize(struct pci_dev *dev)
360 {
361 struct pcistub_device *psdev;
362 unsigned long flags;
363 int err = 0;
365 psdev = pcistub_device_alloc(dev);
366 if (!psdev)
367 return -ENOMEM;
369 spin_lock_irqsave(&pcistub_devices_lock, flags);
371 if (initialize_devices) {
372 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
374 /* don't want irqs disabled when calling pcistub_init_device */
375 err = pcistub_init_device(psdev->dev);
377 spin_lock_irqsave(&pcistub_devices_lock, flags);
379 if (!err)
380 list_add(&psdev->dev_list, &pcistub_devices);
381 } else {
382 dev_dbg(&dev->dev, "deferring initialization\n");
383 list_add(&psdev->dev_list, &seized_devices);
384 }
386 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
388 if (err)
389 pcistub_device_put(psdev);
391 return err;
392 }
394 static int __devinit pcistub_probe(struct pci_dev *dev,
395 const struct pci_device_id *id)
396 {
397 int err = 0;
399 dev_dbg(&dev->dev, "probing...\n");
401 if (pcistub_match(dev)) {
403 if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
404 && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
405 dev_err(&dev->dev, "can't export pci devices that "
406 "don't have a normal (0) or bridge (1) "
407 "header type!\n");
408 err = -ENODEV;
409 goto out;
410 }
412 dev_info(&dev->dev, "seizing device\n");
413 err = pcistub_seize(dev);
414 } else
415 /* Didn't find the device */
416 err = -ENODEV;
418 out:
419 return err;
420 }
422 static void pcistub_remove(struct pci_dev *dev)
423 {
424 struct pcistub_device *psdev, *found_psdev = NULL;
425 unsigned long flags;
427 dev_dbg(&dev->dev, "removing\n");
429 spin_lock_irqsave(&pcistub_devices_lock, flags);
431 pciback_config_quirk_release(dev);
433 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
434 if (psdev->dev == dev) {
435 found_psdev = psdev;
436 break;
437 }
438 }
440 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
442 if (found_psdev) {
443 dev_dbg(&dev->dev, "found device to remove - in use? %p\n",
444 found_psdev->pdev);
446 if (found_psdev->pdev) {
447 printk(KERN_WARNING "pciback: ****** removing device "
448 "%s while still in-use! ******\n",
449 pci_name(found_psdev->dev));
450 printk(KERN_WARNING "pciback: ****** driver domain may "
451 "still access this device's i/o resources!\n");
452 printk(KERN_WARNING "pciback: ****** shutdown driver "
453 "domain before binding device\n");
454 printk(KERN_WARNING "pciback: ****** to other drivers "
455 "or domains\n");
457 pciback_release_pci_dev(found_psdev->pdev,
458 found_psdev->dev);
459 }
461 spin_lock_irqsave(&pcistub_devices_lock, flags);
462 list_del(&found_psdev->dev_list);
463 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
465 /* the final put for releasing from the list */
466 pcistub_device_put(found_psdev);
467 }
468 }
470 static struct pci_device_id pcistub_ids[] = {
471 {
472 .vendor = PCI_ANY_ID,
473 .device = PCI_ANY_ID,
474 .subvendor = PCI_ANY_ID,
475 .subdevice = PCI_ANY_ID,
476 },
477 {0,},
478 };
480 /*
481 * Note: There is no MODULE_DEVICE_TABLE entry here because this isn't
482 * for a normal device. I don't want it to be loaded automatically.
483 */
485 static struct pci_driver pciback_pci_driver = {
486 .name = "pciback",
487 .id_table = pcistub_ids,
488 .probe = pcistub_probe,
489 .remove = pcistub_remove,
490 };
492 static inline int str_to_slot(const char *buf, int *domain, int *bus,
493 int *slot, int *func)
494 {
495 int err;
497 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
498 if (err == 4)
499 return 0;
500 else if (err < 0)
501 return -EINVAL;
503 /* try again without domain */
504 *domain = 0;
505 err = sscanf(buf, " %x:%x.%x", bus, slot, func);
506 if (err == 3)
507 return 0;
509 return -EINVAL;
510 }
512 static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
513 *slot, int *func, int *reg, int *size, int *mask)
514 {
515 int err;
517 err =
518 sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot,
519 func, reg, size, mask);
520 if (err == 7)
521 return 0;
522 return -EINVAL;
523 }
525 static int pcistub_device_id_add(int domain, int bus, int slot, int func)
526 {
527 struct pcistub_device_id *pci_dev_id;
528 unsigned long flags;
530 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
531 if (!pci_dev_id)
532 return -ENOMEM;
534 pci_dev_id->domain = domain;
535 pci_dev_id->bus = bus;
536 pci_dev_id->devfn = PCI_DEVFN(slot, func);
538 pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n",
539 domain, bus, slot, func);
541 spin_lock_irqsave(&device_ids_lock, flags);
542 list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids);
543 spin_unlock_irqrestore(&device_ids_lock, flags);
545 return 0;
546 }
548 static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
549 {
550 struct pcistub_device_id *pci_dev_id, *t;
551 int devfn = PCI_DEVFN(slot, func);
552 int err = -ENOENT;
553 unsigned long flags;
555 spin_lock_irqsave(&device_ids_lock, flags);
556 list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) {
558 if (pci_dev_id->domain == domain
559 && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) {
560 /* Don't break; here because it's possible the same
561 * slot could be in the list more than once
562 */
563 list_del(&pci_dev_id->slot_list);
564 kfree(pci_dev_id);
566 err = 0;
568 pr_debug("pciback: removed %04x:%02x:%02x.%01x from "
569 "seize list\n", domain, bus, slot, func);
570 }
571 }
572 spin_unlock_irqrestore(&device_ids_lock, flags);
574 return err;
575 }
577 static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
578 int size, int mask)
579 {
580 int err = 0;
581 struct pcistub_device *psdev;
582 struct pci_dev *dev;
583 struct config_field *field;
585 psdev = pcistub_device_find(domain, bus, slot, func);
586 if (!psdev || !psdev->dev) {
587 err = -ENODEV;
588 goto out;
589 }
590 dev = psdev->dev;
592 field = kzalloc(sizeof(*field), GFP_ATOMIC);
593 if (!field) {
594 err = -ENOMEM;
595 goto out;
596 }
598 field->offset = reg;
599 field->size = size;
600 field->mask = mask;
601 field->init = NULL;
602 field->reset = NULL;
603 field->release = NULL;
604 field->clean = pciback_config_field_free;
606 err = pciback_config_quirks_add_field(dev, field);
607 if (err)
608 kfree(field);
609 out:
610 return err;
611 }
613 static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf,
614 size_t count)
615 {
616 int domain, bus, slot, func;
617 int err;
619 err = str_to_slot(buf, &domain, &bus, &slot, &func);
620 if (err)
621 goto out;
623 err = pcistub_device_id_add(domain, bus, slot, func);
625 out:
626 if (!err)
627 err = count;
628 return err;
629 }
631 DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add);
633 static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf,
634 size_t count)
635 {
636 int domain, bus, slot, func;
637 int err;
639 err = str_to_slot(buf, &domain, &bus, &slot, &func);
640 if (err)
641 goto out;
643 err = pcistub_device_id_remove(domain, bus, slot, func);
645 out:
646 if (!err)
647 err = count;
648 return err;
649 }
651 DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove);
653 static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf)
654 {
655 struct pcistub_device_id *pci_dev_id;
656 size_t count = 0;
657 unsigned long flags;
659 spin_lock_irqsave(&device_ids_lock, flags);
660 list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) {
661 if (count >= PAGE_SIZE)
662 break;
664 count += scnprintf(buf + count, PAGE_SIZE - count,
665 "%04x:%02x:%02x.%01x\n",
666 pci_dev_id->domain, pci_dev_id->bus,
667 PCI_SLOT(pci_dev_id->devfn),
668 PCI_FUNC(pci_dev_id->devfn));
669 }
670 spin_unlock_irqrestore(&device_ids_lock, flags);
672 return count;
673 }
675 DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL);
677 static ssize_t pcistub_quirk_add(struct device_driver *drv, const char *buf,
678 size_t count)
679 {
680 int domain, bus, slot, func, reg, size, mask;
681 int err;
683 err = str_to_quirk(buf, &domain, &bus, &slot, &func, &reg, &size,
684 &mask);
685 if (err)
686 goto out;
688 err = pcistub_reg_add(domain, bus, slot, func, reg, size, mask);
690 out:
691 if (!err)
692 err = count;
693 return err;
694 }
696 static ssize_t pcistub_quirk_show(struct device_driver *drv, char *buf)
697 {
698 int count = 0;
699 unsigned long flags;
700 extern struct list_head pciback_quirks;
701 struct pciback_config_quirk *quirk;
702 struct pciback_dev_data *dev_data;
703 struct config_field *field;
704 struct config_field_entry *cfg_entry;
706 spin_lock_irqsave(&device_ids_lock, flags);
707 list_for_each_entry(quirk, &pciback_quirks, quirks_list) {
708 if (count >= PAGE_SIZE)
709 goto out;
711 count += scnprintf(buf + count, PAGE_SIZE - count,
712 "%02x:%02x.%01x\n\t%04x:%04x:%04x:%04x\n",
713 quirk->pdev->bus->number,
714 PCI_SLOT(quirk->pdev->devfn),
715 PCI_FUNC(quirk->pdev->devfn),
716 quirk->devid.vendor, quirk->devid.device,
717 quirk->devid.subvendor,
718 quirk->devid.subdevice);
720 dev_data = pci_get_drvdata(quirk->pdev);
722 list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
723 field = cfg_entry->field;
724 if (count >= PAGE_SIZE)
725 goto out;
727 count += scnprintf(buf + count, PAGE_SIZE - count,
728 "\t\t%08x:%01x:%08x\n",
729 cfg_entry->base_offset + field->offset,
730 field->size, field->mask);
731 }
732 }
734 out:
735 spin_unlock_irqrestore(&device_ids_lock, flags);
737 return count;
738 }
740 DRIVER_ATTR(quirks, S_IRUSR | S_IWUSR, pcistub_quirk_show, pcistub_quirk_add);
742 static ssize_t permissive_add(struct device_driver *drv, const char *buf,
743 size_t count)
744 {
745 int domain, bus, slot, func;
746 int err;
747 struct pcistub_device *psdev;
748 struct pciback_dev_data *dev_data;
749 err = str_to_slot(buf, &domain, &bus, &slot, &func);
750 if (err)
751 goto out;
752 psdev = pcistub_device_find(domain, bus, slot, func);
753 if (!psdev) {
754 err = -ENODEV;
755 goto out;
756 }
757 if (!psdev->dev) {
758 err = -ENODEV;
759 goto release;
760 }
761 dev_data = pci_get_drvdata(psdev->dev);
762 /* the driver data for a device should never be null at this point */
763 if (!dev_data) {
764 err = -ENXIO;
765 goto release;
766 }
767 if (!dev_data->permissive) {
768 dev_data->permissive = 1;
769 /* Let user know that what they're doing could be unsafe */
770 dev_warn(&psdev->dev->dev,
771 "enabling permissive mode configuration space accesses!\n");
772 dev_warn(&psdev->dev->dev,
773 "permissive mode is potentially unsafe!\n");
774 }
775 release:
776 pcistub_device_put(psdev);
777 out:
778 if (!err)
779 err = count;
780 return err;
781 }
783 static ssize_t permissive_show(struct device_driver *drv, char *buf)
784 {
785 struct pcistub_device *psdev;
786 struct pciback_dev_data *dev_data;
787 size_t count = 0;
788 unsigned long flags;
789 spin_lock_irqsave(&pcistub_devices_lock, flags);
790 list_for_each_entry(psdev, &pcistub_devices, dev_list) {
791 if (count >= PAGE_SIZE)
792 break;
793 if (!psdev->dev)
794 continue;
795 dev_data = pci_get_drvdata(psdev->dev);
796 if (!dev_data || !dev_data->permissive)
797 continue;
798 count +=
799 scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
800 pci_name(psdev->dev));
801 }
802 spin_unlock_irqrestore(&pcistub_devices_lock, flags);
803 return count;
804 }
806 DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
808 static int __init pcistub_init(void)
809 {
810 int pos = 0;
811 int err = 0;
812 int domain, bus, slot, func;
813 int parsed;
815 if (pci_devs_to_hide && *pci_devs_to_hide) {
816 do {
817 parsed = 0;
819 err = sscanf(pci_devs_to_hide + pos,
820 " (%x:%x:%x.%x) %n",
821 &domain, &bus, &slot, &func, &parsed);
822 if (err != 4) {
823 domain = 0;
824 err = sscanf(pci_devs_to_hide + pos,
825 " (%x:%x.%x) %n",
826 &bus, &slot, &func, &parsed);
827 if (err != 3)
828 goto parse_error;
829 }
831 err = pcistub_device_id_add(domain, bus, slot, func);
832 if (err)
833 goto out;
835 /* if parsed<=0, we've reached the end of the string */
836 pos += parsed;
837 } while (parsed > 0 && pci_devs_to_hide[pos]);
838 }
840 /* If we're the first PCI Device Driver to register, we're the
841 * first one to get offered PCI devices as they become
842 * available (and thus we can be the first to grab them)
843 */
844 err = pci_register_driver(&pciback_pci_driver);
845 if (err < 0)
846 goto out;
848 driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
849 driver_create_file(&pciback_pci_driver.driver,
850 &driver_attr_remove_slot);
851 driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots);
852 driver_create_file(&pciback_pci_driver.driver, &driver_attr_quirks);
853 driver_create_file(&pciback_pci_driver.driver, &driver_attr_permissive);
855 out:
856 return err;
858 parse_error:
859 printk(KERN_ERR "pciback: Error parsing pci_devs_to_hide at \"%s\"\n",
860 pci_devs_to_hide + pos);
861 return -EINVAL;
862 }
864 #ifndef MODULE
865 /*
866 * fs_initcall happens before device_initcall
867 * so pciback *should* get called first (b/c we
868 * want to suck up any device before other drivers
869 * get a chance by being the first pci device
870 * driver to register)
871 */
872 fs_initcall(pcistub_init);
873 #endif
875 static int __init pciback_init(void)
876 {
877 int err;
879 err = pciback_config_init();
880 if (err)
881 return err;
883 #ifdef MODULE
884 err = pcistub_init();
885 if (err < 0)
886 return err;
887 #endif
889 pcistub_init_devices_late();
890 pciback_xenbus_register();
892 return 0;
893 }
895 static void __exit pciback_cleanup(void)
896 {
897 pciback_xenbus_unregister();
899 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot);
900 driver_remove_file(&pciback_pci_driver.driver,
901 &driver_attr_remove_slot);
902 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots);
903 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_quirks);
904 driver_remove_file(&pciback_pci_driver.driver, &driver_attr_permissive);
906 pci_unregister_driver(&pciback_pci_driver);
907 }
909 module_init(pciback_init);
910 module_exit(pciback_cleanup);
912 MODULE_LICENSE("Dual BSD/GPL");