Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vpci.c
Go to the documentation of this file.
1 /*
2  * PCI Backend - Provides a Virtual PCI bus (with real devices)
3  * to the frontend
4  *
5  * Author: Ryan Wilson <[email protected]>
6  */
7 
8 #include <linux/list.h>
9 #include <linux/slab.h>
10 #include <linux/pci.h>
11 #include <linux/mutex.h>
12 #include "pciback.h"
13 
14 #define PCI_SLOT_MAX 32
15 
16 struct vpci_dev_data {
17  /* Access to dev_list must be protected by lock */
19  struct mutex lock;
20 };
21 
22 static inline struct list_head *list_first(struct list_head *head)
23 {
24  return head->next;
25 }
26 
27 static struct pci_dev *__xen_pcibk_get_pci_dev(struct xen_pcibk_device *pdev,
28  unsigned int domain,
29  unsigned int bus,
30  unsigned int devfn)
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 
36  if (domain != 0 || bus != 0)
37  return NULL;
38 
39  if (PCI_SLOT(devfn) < PCI_SLOT_MAX) {
40  mutex_lock(&vpci_dev->lock);
41 
42  list_for_each_entry(entry,
43  &vpci_dev->dev_list[PCI_SLOT(devfn)],
44  list) {
45  if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) {
46  dev = entry->dev;
47  break;
48  }
49  }
50 
51  mutex_unlock(&vpci_dev->lock);
52  }
53  return dev;
54 }
55 
56 static inline int match_slot(struct pci_dev *l, struct pci_dev *r)
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 
65 static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev,
66  struct pci_dev *dev, int devid,
67  publish_pci_dev_cb publish_cb)
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 
73  if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) {
74  err = -EFAULT;
75  xenbus_dev_fatal(pdev->xdev, err,
76  "Can't export bridges on the virtual PCI bus");
77  goto out;
78  }
79 
80  dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL);
81  if (!dev_entry) {
82  err = -ENOMEM;
83  xenbus_dev_fatal(pdev->xdev, err,
84  "Error adding entry to virtual PCI bus");
85  goto out;
86  }
87 
88  dev_entry->dev = dev;
89 
90  mutex_lock(&vpci_dev->lock);
91 
92  /*
93  * Keep multi-function devices together on the virtual PCI bus, except
94  * virtual functions.
95  */
96  if (!dev->is_virtfn) {
97  for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
98  if (list_empty(&vpci_dev->dev_list[slot]))
99  continue;
100 
101  t = list_entry(list_first(&vpci_dev->dev_list[slot]),
102  struct pci_dev_entry, list);
103 
104  if (match_slot(dev, t->dev)) {
105  pr_info(DRV_NAME ": vpci: %s: "
106  "assign to virtual slot %d func %d\n",
107  pci_name(dev), slot,
108  PCI_FUNC(dev->devfn));
109  list_add_tail(&dev_entry->list,
110  &vpci_dev->dev_list[slot]);
111  func = PCI_FUNC(dev->devfn);
112  goto unlock;
113  }
114  }
115  }
116 
117  /* Assign to a new slot on the virtual PCI bus */
118  for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
119  if (list_empty(&vpci_dev->dev_list[slot])) {
121  ": vpci: %s: assign to virtual slot %d\n",
122  pci_name(dev), slot);
123  list_add_tail(&dev_entry->list,
124  &vpci_dev->dev_list[slot]);
125  func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn);
126  goto unlock;
127  }
128  }
129 
130  err = -ENOMEM;
131  xenbus_dev_fatal(pdev->xdev, err,
132  "No more space on root virtual PCI bus");
133 
134 unlock:
135  mutex_unlock(&vpci_dev->lock);
136 
137  /* Publish this device. */
138  if (!err)
139  err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
140 
141 out:
142  return err;
143 }
144 
145 static void __xen_pcibk_release_pci_dev(struct xen_pcibk_device *pdev,
146  struct pci_dev *dev)
147 {
148  int slot;
149  struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
150  struct pci_dev *found_dev = NULL;
151 
152  mutex_lock(&vpci_dev->lock);
153 
154  for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
155  struct pci_dev_entry *e;
156 
157  list_for_each_entry(e, &vpci_dev->dev_list[slot], list) {
158  if (e->dev == dev) {
159  list_del(&e->list);
160  found_dev = e->dev;
161  kfree(e);
162  goto out;
163  }
164  }
165  }
166 
167 out:
168  mutex_unlock(&vpci_dev->lock);
169 
170  if (found_dev)
171  pcistub_put_pci_dev(found_dev);
172 }
173 
174 static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev)
175 {
176  int slot;
177  struct vpci_dev_data *vpci_dev;
178 
179  vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL);
180  if (!vpci_dev)
181  return -ENOMEM;
182 
183  mutex_init(&vpci_dev->lock);
184 
185  for (slot = 0; slot < PCI_SLOT_MAX; slot++)
186  INIT_LIST_HEAD(&vpci_dev->dev_list[slot]);
187 
188  pdev->pci_dev_data = vpci_dev;
189 
190  return 0;
191 }
192 
193 static int __xen_pcibk_publish_pci_roots(struct xen_pcibk_device *pdev,
194  publish_pci_root_cb publish_cb)
195 {
196  /* The Virtual PCI bus has only one root */
197  return publish_cb(pdev, 0, 0);
198 }
199 
200 static void __xen_pcibk_release_devices(struct xen_pcibk_device *pdev)
201 {
202  int slot;
203  struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
204 
205  for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
206  struct pci_dev_entry *e, *tmp;
207  list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot],
208  list) {
209  list_del(&e->list);
211  kfree(e);
212  }
213  }
214 
215  kfree(vpci_dev);
216  pdev->pci_dev_data = NULL;
217 }
218 
219 static int __xen_pcibk_get_pcifront_dev(struct pci_dev *pcidev,
220  struct xen_pcibk_device *pdev,
221  unsigned int *domain, unsigned int *bus,
222  unsigned int *devfn)
223 {
224  struct pci_dev_entry *entry;
225  struct pci_dev *dev = NULL;
226  struct vpci_dev_data *vpci_dev = pdev->pci_dev_data;
227  int found = 0, slot;
228 
229  mutex_lock(&vpci_dev->lock);
230  for (slot = 0; slot < PCI_SLOT_MAX; slot++) {
231  list_for_each_entry(entry,
232  &vpci_dev->dev_list[slot],
233  list) {
234  dev = entry->dev;
235  if (dev && dev->bus->number == pcidev->bus->number
236  && pci_domain_nr(dev->bus) ==
237  pci_domain_nr(pcidev->bus)
238  && dev->devfn == pcidev->devfn) {
239  found = 1;
240  *domain = 0;
241  *bus = 0;
242  *devfn = PCI_DEVFN(slot,
243  PCI_FUNC(pcidev->devfn));
244  }
245  }
246  }
247  mutex_unlock(&vpci_dev->lock);
248  return found;
249 }
250 
252  .name = "vpci",
253  .init = __xen_pcibk_init_devices,
254  .free = __xen_pcibk_release_devices,
255  .find = __xen_pcibk_get_pcifront_dev,
256  .publish = __xen_pcibk_publish_pci_roots,
257  .release = __xen_pcibk_release_pci_dev,
258  .add = __xen_pcibk_add_pci_dev,
259  .get = __xen_pcibk_get_pci_dev,
260 };