vpci.c (30edc14bf39afde24ef7db2de66c91805db80828) | vpci.c (a92336a1176b2119eaa990a1e8bf3109665fdbc6) |
---|---|
1/* 2 * PCI Backend - Provides a Virtual PCI bus (with real devices) 3 * to the frontend 4 * 5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 6 */ 7 8#include <linux/list.h> 9#include <linux/slab.h> 10#include <linux/pci.h> 11#include <linux/spinlock.h> 12#include "pciback.h" 13 14#define PCI_SLOT_MAX 32 | 1/* 2 * PCI Backend - Provides a Virtual PCI bus (with real devices) 3 * to the frontend 4 * 5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 6 */ 7 8#include <linux/list.h> 9#include <linux/slab.h> 10#include <linux/pci.h> 11#include <linux/spinlock.h> 12#include "pciback.h" 13 14#define PCI_SLOT_MAX 32 |
15#define DRV_NAME "xen-pciback" |
|
15 16struct vpci_dev_data { 17 /* Access to dev_list must be protected by lock */ 18 struct list_head dev_list[PCI_SLOT_MAX]; 19 spinlock_t lock; 20}; 21 22static inline struct list_head *list_first(struct list_head *head) 23{ 24 return head->next; 25} 26 | 16 17struct vpci_dev_data { 18 /* Access to dev_list must be protected by lock */ 19 struct list_head dev_list[PCI_SLOT_MAX]; 20 spinlock_t lock; 21}; 22 23static inline struct list_head *list_first(struct list_head *head) 24{ 25 return head->next; 26} 27 |
27struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev, 28 unsigned int domain, unsigned int bus, 29 unsigned int devfn) | 28struct pci_dev *xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev, 29 unsigned int domain, unsigned int bus, 30 unsigned int devfn) |
30{ 31 struct pci_dev_entry *entry; 32 struct pci_dev *dev = NULL; 33 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 34 unsigned long flags; 35 36 if (domain != 0 || bus != 0) 37 return NULL; --- 19 unchanged lines hidden (view full) --- 57{ 58 if (pci_domain_nr(l->bus) == pci_domain_nr(r->bus) 59 && l->bus == r->bus && PCI_SLOT(l->devfn) == PCI_SLOT(r->devfn)) 60 return 1; 61 62 return 0; 63} 64 | 31{ 32 struct pci_dev_entry *entry; 33 struct pci_dev *dev = NULL; 34 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 35 unsigned long flags; 36 37 if (domain != 0 || bus != 0) 38 return NULL; --- 19 unchanged lines hidden (view full) --- 58{ 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)) 61 return 1; 62 63 return 0; 64} 65 |
65int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev, 66 int devid, publish_pci_dev_cb publish_cb) | 66int xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, struct pci_dev *dev, 67 int devid, publish_pci_dev_cb publish_cb) |
67{ 68 int err = 0, slot, func = -1; 69 struct pci_dev_entry *t, *dev_entry; 70 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 71 unsigned long flags; 72 73 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { 74 err = -EFAULT; --- 16 unchanged lines hidden (view full) --- 91 92 /* Keep multi-function devices together on the virtual PCI bus */ 93 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 94 if (!list_empty(&vpci_dev->dev_list[slot])) { 95 t = list_entry(list_first(&vpci_dev->dev_list[slot]), 96 struct pci_dev_entry, list); 97 98 if (match_slot(dev, t->dev)) { | 68{ 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; 72 unsigned long flags; 73 74 if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { 75 err = -EFAULT; --- 16 unchanged lines hidden (view full) --- 92 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); 98 99 if (match_slot(dev, t->dev)) { |
99 pr_info("pciback: vpci: %s: " | 100 pr_info(DRV_NAME ": vpci: %s: " |
100 "assign to virtual slot %d func %d\n", 101 pci_name(dev), slot, 102 PCI_FUNC(dev->devfn)); 103 list_add_tail(&dev_entry->list, 104 &vpci_dev->dev_list[slot]); 105 func = PCI_FUNC(dev->devfn); 106 goto unlock; 107 } 108 } 109 } 110 111 /* Assign to a new slot on the virtual PCI bus */ 112 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 113 if (list_empty(&vpci_dev->dev_list[slot])) { | 101 "assign to virtual slot %d func %d\n", 102 pci_name(dev), slot, 103 PCI_FUNC(dev->devfn)); 104 list_add_tail(&dev_entry->list, 105 &vpci_dev->dev_list[slot]); 106 func = PCI_FUNC(dev->devfn); 107 goto unlock; 108 } 109 } 110 } 111 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])) { |
114 printk(KERN_INFO 115 "pciback: vpci: %s: assign to virtual slot %d\n", | 115 printk(KERN_INFO DRV_NAME 116 ": vpci: %s: assign to virtual slot %d\n", |
116 pci_name(dev), slot); 117 list_add_tail(&dev_entry->list, 118 &vpci_dev->dev_list[slot]); 119 func = PCI_FUNC(dev->devfn); 120 goto unlock; 121 } 122 } 123 --- 7 unchanged lines hidden (view full) --- 131 /* Publish this device. */ 132 if (!err) 133 err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid); 134 135out: 136 return err; 137} 138 | 117 pci_name(dev), slot); 118 list_add_tail(&dev_entry->list, 119 &vpci_dev->dev_list[slot]); 120 func = PCI_FUNC(dev->devfn); 121 goto unlock; 122 } 123 } 124 --- 7 unchanged lines hidden (view full) --- 132 /* Publish this device. */ 133 if (!err) 134 err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid); 135 136out: 137 return err; 138} 139 |
139void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) | 140void xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev, 141 struct pci_dev *dev) |
140{ 141 int slot; 142 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 143 struct pci_dev *found_dev = NULL; 144 unsigned long flags; 145 146 spin_lock_irqsave(&vpci_dev->lock, flags); 147 --- 12 unchanged lines hidden (view full) --- 160 161out: 162 spin_unlock_irqrestore(&vpci_dev->lock, flags); 163 164 if (found_dev) 165 pcistub_put_pci_dev(found_dev); 166} 167 | 142{ 143 int slot; 144 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 145 struct pci_dev *found_dev = NULL; 146 unsigned long flags; 147 148 spin_lock_irqsave(&vpci_dev->lock, flags); 149 --- 12 unchanged lines hidden (view full) --- 162 163out: 164 spin_unlock_irqrestore(&vpci_dev->lock, flags); 165 166 if (found_dev) 167 pcistub_put_pci_dev(found_dev); 168} 169 |
168int pciback_init_devices(struct pciback_device *pdev) | 170int xen_pcibk_init_devices(struct xen_pcibk_device *pdev) |
169{ 170 int slot; 171 struct vpci_dev_data *vpci_dev; 172 173 vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL); 174 if (!vpci_dev) 175 return -ENOMEM; 176 177 spin_lock_init(&vpci_dev->lock); 178 179 for (slot = 0; slot < PCI_SLOT_MAX; slot++) 180 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]); 181 182 pdev->pci_dev_data = vpci_dev; 183 184 return 0; 185} 186 | 171{ 172 int slot; 173 struct vpci_dev_data *vpci_dev; 174 175 vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL); 176 if (!vpci_dev) 177 return -ENOMEM; 178 179 spin_lock_init(&vpci_dev->lock); 180 181 for (slot = 0; slot < PCI_SLOT_MAX; slot++) 182 INIT_LIST_HEAD(&vpci_dev->dev_list[slot]); 183 184 pdev->pci_dev_data = vpci_dev; 185 186 return 0; 187} 188 |
187int pciback_publish_pci_roots(struct pciback_device *pdev, 188 publish_pci_root_cb publish_cb) | 189int xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev, 190 publish_pci_root_cb publish_cb) |
189{ 190 /* The Virtual PCI bus has only one root */ 191 return publish_cb(pdev, 0, 0); 192} 193 | 191{ 192 /* The Virtual PCI bus has only one root */ 193 return publish_cb(pdev, 0, 0); 194} 195 |
194void pciback_release_devices(struct pciback_device *pdev) | 196void xen_pcibk_release_devices(struct xen_pcibk_device *pdev) |
195{ 196 int slot; 197 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 198 199 for (slot = 0; slot < PCI_SLOT_MAX; slot++) { 200 struct pci_dev_entry *e, *tmp; 201 list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot], 202 list) { 203 list_del(&e->list); 204 pcistub_put_pci_dev(e->dev); 205 kfree(e); 206 } 207 } 208 209 kfree(vpci_dev); 210 pdev->pci_dev_data = NULL; 211} 212 | 197{ 198 int slot; 199 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 200 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], 204 list) { 205 list_del(&e->list); 206 pcistub_put_pci_dev(e->dev); 207 kfree(e); 208 } 209 } 210 211 kfree(vpci_dev); 212 pdev->pci_dev_data = NULL; 213} 214 |
213int pciback_get_pcifront_dev(struct pci_dev *pcidev, 214 struct pciback_device *pdev, 215 unsigned int *domain, unsigned int *bus, 216 unsigned int *devfn) | 215int xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev, 216 struct xen_pcibk_device *pdev, 217 unsigned int *domain, unsigned int *bus, 218 unsigned int *devfn) |
217{ 218 struct pci_dev_entry *entry; 219 struct pci_dev *dev = NULL; 220 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 221 unsigned long flags; 222 int found = 0, slot; 223 224 spin_lock_irqsave(&vpci_dev->lock, flags); --- 20 unchanged lines hidden --- | 219{ 220 struct pci_dev_entry *entry; 221 struct pci_dev *dev = NULL; 222 struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; 223 unsigned long flags; 224 int found = 0, slot; 225 226 spin_lock_irqsave(&vpci_dev->lock, flags); --- 20 unchanged lines hidden --- |