6 #include <linux/module.h>
8 #include <linux/list.h>
12 #include <xen/events.h>
16 #define INVALID_EVTCHN_IRQ (-1)
22 "Option to specify how to export PCI topology to guest:\n"\
23 " 0 - (default) Hide the true PCI topology and makes the frontend\n"\
24 " there is a single PCI bus with only the exported devices on it.\n"\
25 " For example, a device at 03:05.0 will be re-assigned to 00:00.0\n"\
26 " while second device at 02:1a.1 will be re-assigned to 00:01.1.\n"\
27 " 1 - Passthrough provides a real view of the PCI topology to the\n"\
28 " frontend (for example, a device at 06:01.b will still appear at\n"\
29 " 06:01.b to the frontend). This is similar to how Xen 2.0.x\n"\
30 " exposed PCI devices to its driver domains. This may be required\n"\
31 " for drivers which depend on finding their hardward in certain\n"\
32 " bus/slot locations.");
41 dev_dbg(&xdev->
dev,
"allocated pdev @ 0x%p\n", pdev);
54 if (xen_pcibk_init_devices(pdev)) {
91 xen_pcibk_disconnect(pdev);
93 xen_pcibk_release_devices(pdev);
108 "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n",
109 gnt_ref, remote_evtchn);
114 "Error mapping other domain page in ours.");
125 "Error binding event channel to IRQ");
139 int gnt_ref, remote_evtchn;
154 dev_dbg(&pdev->
xdev->dev,
"Reading frontend config\n");
157 "pci-op-ref",
"%u", &gnt_ref,
158 "event-channel",
"%u", &remote_evtchn,
163 "Error reading configuration from frontend");
169 "version mismatch (%s/%s) with pcifront - "
175 err = xen_pcibk_do_attach(pdev, gnt_ref, remote_evtchn);
184 "Error switching to connected state!");
196 unsigned int domain,
unsigned int bus,
203 len =
snprintf(str,
sizeof(str),
"vdev-%d", devid);
204 if (
unlikely(len >= (
sizeof(str) - 1))) {
211 "%04x:%02x:%02x.%02x", domain, bus,
219 int domain,
int bus,
int slot,
int func,
225 dev_dbg(&pdev->
xdev->dev,
"exporting dom %x bus %x slot %x func %x\n",
226 domain, bus, slot, func);
232 "Couldn't locate PCI device "
233 "(%04x:%02x:%02x.%d)! "
234 "perhaps already in-use?",
235 domain, bus, slot, func);
239 err = xen_pcibk_add_pci_dev(pdev, dev, devid,
240 xen_pcibk_publish_pci_dev);
244 dev_dbg(&dev->
dev,
"registering for %d\n", pdev->
xdev->otherend_id);
245 if (xen_register_device_domain_owner(dev,
246 pdev->
xdev->otherend_id) != 0) {
247 dev_err(&dev->
dev,
"Stealing ownership from dom%d.\n",
248 xen_find_device_domain_owner(dev));
249 xen_unregister_device_domain_owner(dev);
250 xen_register_device_domain_owner(dev, pdev->
xdev->otherend_id);
266 int domain,
int bus,
int slot,
int func)
271 dev_dbg(&pdev->
xdev->dev,
"removing dom %x bus %x slot %x func %x\n",
272 domain, bus, slot, func);
274 dev = xen_pcibk_get_pci_dev(pdev, domain, bus,
PCI_DEVFN(slot, func));
277 dev_dbg(&pdev->
xdev->dev,
"Couldn't locate PCI device "
278 "(%04x:%02x:%02x.%d)! not owned by this domain\n",
279 domain, bus, slot, func);
283 dev_dbg(&dev->
dev,
"unregistering for %d\n", pdev->
xdev->otherend_id);
284 xen_unregister_device_domain_owner(dev);
286 xen_pcibk_release_pci_dev(pdev, dev);
293 unsigned int domain,
unsigned int bus)
296 int i, root_num, len,
err;
299 dev_dbg(&pdev->
xdev->dev,
"Publishing pci roots\n");
302 "root_num",
"%d", &root_num);
303 if (err == 0 || err == -
ENOENT)
309 for (i = 0; i < root_num; i++) {
310 len =
snprintf(str,
sizeof(str),
"root-%d", i);
311 if (
unlikely(len >= (
sizeof(str) - 1))) {
317 str,
"%x:%x", &d, &b);
325 if (d == domain && b == bus) {
331 len =
snprintf(str,
sizeof(str),
"root-%d", root_num);
332 if (
unlikely(len >= (
sizeof(str) - 1))) {
337 dev_dbg(&pdev->
xdev->dev,
"writing root %d at %04x:%02x\n",
338 root_num, domain, bus);
341 "%04x:%02x", domain, bus);
346 "root_num",
"%d", (root_num + 1));
363 dev_dbg(&pdev->
xdev->dev,
"Reconfiguring device ...\n");
377 "Error reading number of devices");
381 for (i = 0; i < num_devs; i++) {
382 len =
snprintf(state_str,
sizeof(state_str),
"state-%d", i);
383 if (
unlikely(len >= (
sizeof(state_str) - 1))) {
386 "String overflow while reading "
397 dev_dbg(&pdev->
xdev->dev,
"Attaching dev-%d ...\n", i);
399 len =
snprintf(dev_str,
sizeof(dev_str),
"dev-%d", i);
400 if (
unlikely(len >= (
sizeof(dev_str) - 1))) {
403 "String overflow while "
404 "reading configuration");
408 dev_str,
"%x:%x:%x.%x",
409 &domain, &bus, &slot, &func);
412 "Error reading device "
419 "Error parsing pci device "
424 err = xen_pcibk_export_device(pdev, domain, bus, slot,
430 err = xen_pcibk_publish_pci_roots(pdev,
431 xen_pcibk_publish_pci_root);
434 "Error while publish PCI root"
435 "buses for frontend");
444 "Error switching substate of "
451 dev_dbg(&pdev->
xdev->dev,
"Detaching dev-%d ...\n", i);
453 len =
snprintf(dev_str,
sizeof(dev_str),
"vdev-%d", i);
454 if (
unlikely(len >= (
sizeof(dev_str) - 1))) {
457 "String overflow while "
458 "reading configuration");
462 dev_str,
"%x:%x:%x.%x",
463 &domain, &bus, &slot, &func);
466 "Error reading device "
473 "Error parsing pci device "
478 err = xen_pcibk_remove_device(pdev, domain, bus, slot,
498 "Error switching to reconfigured state!");
507 static void xen_pcibk_frontend_changed(
struct xenbus_device *xdev,
512 dev_dbg(&xdev->
dev,
"fe state changed %d\n", fe_state);
516 xen_pcibk_attach(pdev);
520 xen_pcibk_reconfigure(pdev);
531 xen_pcibk_disconnect(pdev);
536 xen_pcibk_disconnect(pdev);
542 dev_dbg(&xdev->
dev,
"frontend is gone! unregister device\n");
576 "Error reading number of devices");
580 for (i = 0; i < num_devs; i++) {
581 int l =
snprintf(dev_str,
sizeof(dev_str),
"dev-%d", i);
582 if (
unlikely(l >= (
sizeof(dev_str) - 1))) {
585 "String overflow while reading "
591 "%x:%x:%x.%x", &domain, &bus, &slot, &func);
594 "Error reading device configuration");
600 "Error parsing pci device "
605 err = xen_pcibk_export_device(pdev, domain, bus, slot, func, i);
610 l =
snprintf(state_str,
sizeof(state_str),
"state-%d", i);
611 if (
unlikely(l >= (
sizeof(state_str) - 1))) {
614 "String overflow while reading "
622 "substate of dev-%d\n", i);
627 err = xen_pcibk_publish_pci_roots(pdev, xen_pcibk_publish_pci_root);
630 "Error while publish PCI root buses "
638 "Error switching to initialised state!");
644 xen_pcibk_attach(pdev);
649 const char **vec,
unsigned int len)
656 xen_pcibk_setup_backend(pdev);
673 "Error allocating xen_pcibk_device struct");
699 static int xen_pcibk_xenbus_remove(
struct xenbus_device *dev)
715 .probe = xen_pcibk_xenbus_probe,
716 .
remove = xen_pcibk_xenbus_remove,
717 .otherend_changed = xen_pcibk_frontend_changed,
727 "xen_pciback_workqueue failed\n", __func__);