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 ---