2 * PCI Backend - Provides a Virtual PCI bus (with real devices)
5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
8 #include <linux/list.h>
9 #include <linux/slab.h>
10 #include <linux/pci.h>
11 #include <linux/spinlock.h>
14 #define PCI_SLOT_MAX 32
15 #define DRV_NAME "xen-pciback"
17 struct vpci_dev_data {
18 /* Access to dev_list must be protected by lock */
19 struct list_head dev_list[PCI_SLOT_MAX];
23 static inline struct list_head *list_first(struct list_head *head)
28 struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
29 unsigned int domain, unsigned int bus,
32 struct pci_dev_entry *entry;
33 struct pci_dev *dev = NULL;
34 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
37 if (domain != 0 || bus != 0)
40 if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
41 spin_lock_irqsave(&vpci_dev->lock, flags);
43 list_for_each_entry(entry,
44 &vpci_dev->dev_list[PCI_SLOT(devfn)],
46 if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
52 spin_unlock_irqrestore(&vpci_dev->lock, flags);
57 static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
59 if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus)
60 && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn))
66 int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev,
67 int devid, publish_pci_dev_cb publish_cb)
69 int err = 0, slot, func = -1;
70 struct pci_dev_entry *t, *dev_entry;
71 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
74 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
76 xenbus_dev_fatal(pdev->xdev, err,
77 "Can't export bridges on the virtual PCI bus");
81 dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
84 xenbus_dev_fatal(pdev->xdev, err,
85 "Error adding entry to virtual PCI bus");
91 spin_lock_irqsave(&vpci_dev->lock, flags);
93 /* Keep multi-function devices together on the virtual PCI bus */
94 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
95 if (!list_empty(&vpci_dev->dev_list[slot])) {
96 t = list_entry(list_first(&vpci_dev->dev_list[slot]),
97 struct pci_dev_entry, list);
99 if (match_slot(dev, t->dev)) {
100 pr_info(DRV_NAME ": vpci: %s: "
101 "assign to virtual slot %d func %d\n",
103 PCI_FUNC(dev->devfn));
104 list_add_tail(&dev_entry->list,
105 &vpci_dev->dev_list[slot]);
106 func = PCI_FUNC(dev->devfn);
112 /* Assign to a new slot on the virtual PCI bus */
113 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
114 if (list_empty(&vpci_dev->dev_list[slot])) {
115 printk(KERN_INFO DRV_NAME
116 ": vpci: %s: assign to virtual slot %d\n",
117 pci_name(dev), slot);
118 list_add_tail(&dev_entry->list,
119 &vpci_dev->dev_list[slot]);
120 func = PCI_FUNC(dev->devfn);
126 xenbus_dev_fatal(pdev->xdev, err,
127 "No more space on root virtual PCI bus");
130 spin_unlock_irqrestore(&vpci_dev->lock, flags);
132 /* Publish this device. */
134 err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
140 void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
144 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
145 struct pci_dev *found_dev = NULL;
148 spin_lock_irqsave(&vpci_dev->lock, flags);
150 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
151 struct pci_dev_entry *e, *tmp;
152 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
164 spin_unlock_irqrestore(&vpci_dev->lock, flags);
167 pcistub_put_pci_dev(found_dev);
170 int xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
173 struct vpci_dev_data *vpci_dev;
175 vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL);
179 spin_lock_init(&vpci_dev->lock);
181 for (slot = 0; slot < PCI_SLOT_MAX; slot++)
182 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
184 pdev->pci_dev_data = vpci_dev;
189 int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
190 publish_pci_root_cb publish_cb)
192 /* The Virtual PCI bus has only one root */
193 return publish_cb(pdev, 0, 0);
196 void xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
199 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
201 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
202 struct pci_dev_entry *e, *tmp;
203 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
206 pcistub_put_pci_dev(e->dev);
212 pdev->pci_dev_data = NULL;
215 int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
216 struct xen_pcibk_device *pdev,
217 unsigned int *domain, unsigned int *bus,
220 struct pci_dev_entry *entry;
221 struct pci_dev *dev = NULL;
222 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
226 spin_lock_irqsave(&vpci_dev->lock, flags);
227 for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
228 list_for_each_entry(entry,
229 &vpci_dev->dev_list[slot],
232 if (dev && dev->bus->number == pcidev->bus->number
233 && pci_domain_nr(dev->bus) ==
234 pci_domain_nr(pcidev->bus)
235 && dev->devfn == pcidev->devfn) {
239 *devfn = PCI_DEVFN(slot,
240 PCI_FUNC(pcidev->devfn));
244 spin_unlock_irqrestore(&vpci_dev->lock, flags);