xenbus.c (494ef20db6ea2e2ab1c3a45a1461e6e717fdcf48) | xenbus.c (a92336a1176b2119eaa990a1e8bf3109665fdbc6) |
---|---|
1/* 2 * PCI Backend Xenbus Setup - handles setup with frontend and xend 3 * 4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 5 */ 6#include <linux/module.h> 7#include <linux/init.h> 8#include <linux/list.h> 9#include <linux/vmalloc.h> 10#include <linux/workqueue.h> 11#include <xen/xenbus.h> 12#include <xen/events.h> 13#include <asm/xen/pci.h> 14#include <linux/workqueue.h> 15#include "pciback.h" 16 | 1/* 2 * PCI Backend Xenbus Setup - handles setup with frontend and xend 3 * 4 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 5 */ 6#include <linux/module.h> 7#include <linux/init.h> 8#include <linux/list.h> 9#include <linux/vmalloc.h> 10#include <linux/workqueue.h> 11#include <xen/xenbus.h> 12#include <xen/events.h> 13#include <asm/xen/pci.h> 14#include <linux/workqueue.h> 15#include "pciback.h" 16 |
17#define DRV_NAME "xen-pciback" |
|
17#define INVALID_EVTCHN_IRQ (-1) | 18#define INVALID_EVTCHN_IRQ (-1) |
18struct workqueue_struct *pciback_wq; | 19struct workqueue_struct *xen_pcibk_wq; |
19 | 20 |
20static struct pciback_device *alloc_pdev(struct xenbus_device *xdev) | 21static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev) |
21{ | 22{ |
22 struct pciback_device *pdev; | 23 struct xen_pcibk_device *pdev; |
23 | 24 |
24 pdev = kzalloc(sizeof(struct pciback_device), GFP_KERNEL); | 25 pdev = kzalloc(sizeof(struct xen_pcibk_device), GFP_KERNEL); |
25 if (pdev == NULL) 26 goto out; 27 dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev); 28 29 pdev->xdev = xdev; 30 dev_set_drvdata(&xdev->dev, pdev); 31 32 spin_lock_init(&pdev->dev_lock); 33 34 pdev->sh_info = NULL; 35 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 36 pdev->be_watching = 0; 37 | 26 if (pdev == NULL) 27 goto out; 28 dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev); 29 30 pdev->xdev = xdev; 31 dev_set_drvdata(&xdev->dev, pdev); 32 33 spin_lock_init(&pdev->dev_lock); 34 35 pdev->sh_info = NULL; 36 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 37 pdev->be_watching = 0; 38 |
38 INIT_WORK(&pdev->op_work, pciback_do_op); | 39 INIT_WORK(&pdev->op_work, xen_pcibk_do_op); |
39 | 40 |
40 if (pciback_init_devices(pdev)) { | 41 if (xen_pcibk_init_devices(pdev)) { |
41 kfree(pdev); 42 pdev = NULL; 43 } 44out: 45 return pdev; 46} 47 | 42 kfree(pdev); 43 pdev = NULL; 44 } 45out: 46 return pdev; 47} 48 |
48static void pciback_disconnect(struct pciback_device *pdev) | 49static void xen_pcibk_disconnect(struct xen_pcibk_device *pdev) |
49{ 50 spin_lock(&pdev->dev_lock); 51 52 /* Ensure the guest can't trigger our handler before removing devices */ 53 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) { 54 unbind_from_irqhandler(pdev->evtchn_irq, pdev); 55 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 56 } 57 spin_unlock(&pdev->dev_lock); 58 59 /* If the driver domain started an op, make sure we complete it 60 * before releasing the shared memory */ 61 62 /* Note, the workqueue does not use spinlocks at all.*/ | 50{ 51 spin_lock(&pdev->dev_lock); 52 53 /* Ensure the guest can't trigger our handler before removing devices */ 54 if (pdev->evtchn_irq != INVALID_EVTCHN_IRQ) { 55 unbind_from_irqhandler(pdev->evtchn_irq, pdev); 56 pdev->evtchn_irq = INVALID_EVTCHN_IRQ; 57 } 58 spin_unlock(&pdev->dev_lock); 59 60 /* If the driver domain started an op, make sure we complete it 61 * before releasing the shared memory */ 62 63 /* Note, the workqueue does not use spinlocks at all.*/ |
63 flush_workqueue(pciback_wq); | 64 flush_workqueue(xen_pcibk_wq); |
64 65 spin_lock(&pdev->dev_lock); 66 if (pdev->sh_info != NULL) { 67 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info); 68 pdev->sh_info = NULL; 69 } 70 spin_unlock(&pdev->dev_lock); 71 72} 73 | 65 66 spin_lock(&pdev->dev_lock); 67 if (pdev->sh_info != NULL) { 68 xenbus_unmap_ring_vfree(pdev->xdev, pdev->sh_info); 69 pdev->sh_info = NULL; 70 } 71 spin_unlock(&pdev->dev_lock); 72 73} 74 |
74static void free_pdev(struct pciback_device *pdev) | 75static void free_pdev(struct xen_pcibk_device *pdev) |
75{ 76 if (pdev->be_watching) { 77 unregister_xenbus_watch(&pdev->be_watch); 78 pdev->be_watching = 0; 79 } 80 | 76{ 77 if (pdev->be_watching) { 78 unregister_xenbus_watch(&pdev->be_watch); 79 pdev->be_watching = 0; 80 } 81 |
81 pciback_disconnect(pdev); | 82 xen_pcibk_disconnect(pdev); |
82 | 83 |
83 pciback_release_devices(pdev); | 84 xen_pcibk_release_devices(pdev); |
84 85 dev_set_drvdata(&pdev->xdev->dev, NULL); 86 pdev->xdev = NULL; 87 88 kfree(pdev); 89} 90 | 85 86 dev_set_drvdata(&pdev->xdev->dev, NULL); 87 pdev->xdev = NULL; 88 89 kfree(pdev); 90} 91 |
91static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref, | 92static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref, |
92 int remote_evtchn) 93{ 94 int err = 0; 95 void *vaddr; 96 97 dev_dbg(&pdev->xdev->dev, 98 "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n", 99 gnt_ref, remote_evtchn); --- 5 unchanged lines hidden (view full) --- 105 goto out; 106 } 107 108 spin_lock(&pdev->dev_lock); 109 pdev->sh_info = vaddr; 110 spin_unlock(&pdev->dev_lock); 111 112 err = bind_interdomain_evtchn_to_irqhandler( | 93 int remote_evtchn) 94{ 95 int err = 0; 96 void *vaddr; 97 98 dev_dbg(&pdev->xdev->dev, 99 "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n", 100 gnt_ref, remote_evtchn); --- 5 unchanged lines hidden (view full) --- 106 goto out; 107 } 108 109 spin_lock(&pdev->dev_lock); 110 pdev->sh_info = vaddr; 111 spin_unlock(&pdev->dev_lock); 112 113 err = bind_interdomain_evtchn_to_irqhandler( |
113 pdev->xdev->otherend_id, remote_evtchn, pciback_handle_event, 114 0, "pciback", pdev); | 114 pdev->xdev->otherend_id, remote_evtchn, xen_pcibk_handle_event, 115 0, DRV_NAME, pdev); |
115 if (err < 0) { 116 xenbus_dev_fatal(pdev->xdev, err, 117 "Error binding event channel to IRQ"); 118 goto out; 119 } 120 121 spin_lock(&pdev->dev_lock); 122 pdev->evtchn_irq = err; 123 spin_unlock(&pdev->dev_lock); 124 err = 0; 125 126 dev_dbg(&pdev->xdev->dev, "Attached!\n"); 127out: 128 return err; 129} 130 | 116 if (err < 0) { 117 xenbus_dev_fatal(pdev->xdev, err, 118 "Error binding event channel to IRQ"); 119 goto out; 120 } 121 122 spin_lock(&pdev->dev_lock); 123 pdev->evtchn_irq = err; 124 spin_unlock(&pdev->dev_lock); 125 err = 0; 126 127 dev_dbg(&pdev->xdev->dev, "Attached!\n"); 128out: 129 return err; 130} 131 |
131static int pciback_attach(struct pciback_device *pdev) | 132static int xen_pcibk_attach(struct xen_pcibk_device *pdev) |
132{ 133 int err = 0; 134 int gnt_ref, remote_evtchn; 135 char *magic = NULL; 136 137 138 /* Make sure we only do this setup once */ 139 if (xenbus_read_driver_state(pdev->xdev->nodename) != --- 16 unchanged lines hidden (view full) --- 156 xenbus_dev_fatal(pdev->xdev, err, 157 "Error reading configuration from frontend"); 158 goto out; 159 } 160 161 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) { 162 xenbus_dev_fatal(pdev->xdev, -EFAULT, 163 "version mismatch (%s/%s) with pcifront - " | 133{ 134 int err = 0; 135 int gnt_ref, remote_evtchn; 136 char *magic = NULL; 137 138 139 /* Make sure we only do this setup once */ 140 if (xenbus_read_driver_state(pdev->xdev->nodename) != --- 16 unchanged lines hidden (view full) --- 157 xenbus_dev_fatal(pdev->xdev, err, 158 "Error reading configuration from frontend"); 159 goto out; 160 } 161 162 if (magic == NULL || strcmp(magic, XEN_PCI_MAGIC) != 0) { 163 xenbus_dev_fatal(pdev->xdev, -EFAULT, 164 "version mismatch (%s/%s) with pcifront - " |
164 "halting pciback", | 165 "halting xen_pcibk", |
165 magic, XEN_PCI_MAGIC); 166 goto out; 167 } 168 | 166 magic, XEN_PCI_MAGIC); 167 goto out; 168 } 169 |
169 err = pciback_do_attach(pdev, gnt_ref, remote_evtchn); | 170 err = xen_pcibk_do_attach(pdev, gnt_ref, remote_evtchn); |
170 if (err) 171 goto out; 172 173 dev_dbg(&pdev->xdev->dev, "Connecting...\n"); 174 175 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); 176 if (err) 177 xenbus_dev_fatal(pdev->xdev, err, 178 "Error switching to connected state!"); 179 180 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err); 181out: 182 183 kfree(magic); 184 185 return err; 186} 187 | 171 if (err) 172 goto out; 173 174 dev_dbg(&pdev->xdev->dev, "Connecting...\n"); 175 176 err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); 177 if (err) 178 xenbus_dev_fatal(pdev->xdev, err, 179 "Error switching to connected state!"); 180 181 dev_dbg(&pdev->xdev->dev, "Connected? %d\n", err); 182out: 183 184 kfree(magic); 185 186 return err; 187} 188 |
188static int pciback_publish_pci_dev(struct pciback_device *pdev, | 189static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev, |
189 unsigned int domain, unsigned int bus, 190 unsigned int devfn, unsigned int devid) 191{ 192 int err; 193 int len; 194 char str[64]; 195 196 len = snprintf(str, sizeof(str), "vdev-%d", devid); --- 5 unchanged lines hidden (view full) --- 202 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str, 203 "%04x:%02x:%02x.%02x", domain, bus, 204 PCI_SLOT(devfn), PCI_FUNC(devfn)); 205 206out: 207 return err; 208} 209 | 190 unsigned int domain, unsigned int bus, 191 unsigned int devfn, unsigned int devid) 192{ 193 int err; 194 int len; 195 char str[64]; 196 197 len = snprintf(str, sizeof(str), "vdev-%d", devid); --- 5 unchanged lines hidden (view full) --- 203 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str, 204 "%04x:%02x:%02x.%02x", domain, bus, 205 PCI_SLOT(devfn), PCI_FUNC(devfn)); 206 207out: 208 return err; 209} 210 |
210static int pciback_export_device(struct pciback_device *pdev, | 211static int xen_pcibk_export_device(struct xen_pcibk_device *pdev, |
211 int domain, int bus, int slot, int func, 212 int devid) 213{ 214 struct pci_dev *dev; 215 int err = 0; 216 217 dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n", 218 domain, bus, slot, func); --- 4 unchanged lines hidden (view full) --- 223 xenbus_dev_fatal(pdev->xdev, err, 224 "Couldn't locate PCI device " 225 "(%04x:%02x:%02x.%01x)! " 226 "perhaps already in-use?", 227 domain, bus, slot, func); 228 goto out; 229 } 230 | 212 int domain, int bus, int slot, int func, 213 int devid) 214{ 215 struct pci_dev *dev; 216 int err = 0; 217 218 dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n", 219 domain, bus, slot, func); --- 4 unchanged lines hidden (view full) --- 224 xenbus_dev_fatal(pdev->xdev, err, 225 "Couldn't locate PCI device " 226 "(%04x:%02x:%02x.%01x)! " 227 "perhaps already in-use?", 228 domain, bus, slot, func); 229 goto out; 230 } 231 |
231 err = pciback_add_pci_dev(pdev, dev, devid, pciback_publish_pci_dev); | 232 err = xen_pcibk_add_pci_dev(pdev, dev, devid, 233 xen_pcibk_publish_pci_dev); |
232 if (err) 233 goto out; 234 235 dev_dbg(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id); 236 if (xen_register_device_domain_owner(dev, 237 pdev->xdev->otherend_id) != 0) { 238 dev_err(&dev->dev, "device has been assigned to another " \ 239 "domain! Over-writting the ownership, but beware.\n"); --- 8 unchanged lines hidden (view full) --- 248 * driver domain, that all devices under that bridge are not given 249 * to other driver domains (as he who controls the bridge can disable 250 * it and stop the other devices from working). 251 */ 252out: 253 return err; 254} 255 | 234 if (err) 235 goto out; 236 237 dev_dbg(&dev->dev, "registering for %d\n", pdev->xdev->otherend_id); 238 if (xen_register_device_domain_owner(dev, 239 pdev->xdev->otherend_id) != 0) { 240 dev_err(&dev->dev, "device has been assigned to another " \ 241 "domain! Over-writting the ownership, but beware.\n"); --- 8 unchanged lines hidden (view full) --- 250 * driver domain, that all devices under that bridge are not given 251 * to other driver domains (as he who controls the bridge can disable 252 * it and stop the other devices from working). 253 */ 254out: 255 return err; 256} 257 |
256static int pciback_remove_device(struct pciback_device *pdev, | 258static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev, |
257 int domain, int bus, int slot, int func) 258{ 259 int err = 0; 260 struct pci_dev *dev; 261 262 dev_dbg(&pdev->xdev->dev, "removing dom %x bus %x slot %x func %x\n", 263 domain, bus, slot, func); 264 | 259 int domain, int bus, int slot, int func) 260{ 261 int err = 0; 262 struct pci_dev *dev; 263 264 dev_dbg(&pdev->xdev->dev, "removing dom %x bus %x slot %x func %x\n", 265 domain, bus, slot, func); 266 |
265 dev = pciback_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func)); | 267 dev = xen_pcibk_get_pci_dev(pdev, domain, bus, PCI_DEVFN(slot, func)); |
266 if (!dev) { 267 err = -EINVAL; 268 dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device " 269 "(%04x:%02x:%02x.%01x)! not owned by this domain\n", 270 domain, bus, slot, func); 271 goto out; 272 } 273 274 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); 275 xen_unregister_device_domain_owner(dev); 276 | 268 if (!dev) { 269 err = -EINVAL; 270 dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device " 271 "(%04x:%02x:%02x.%01x)! not owned by this domain\n", 272 domain, bus, slot, func); 273 goto out; 274 } 275 276 dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); 277 xen_unregister_device_domain_owner(dev); 278 |
277 pciback_release_pci_dev(pdev, dev); | 279 xen_pcibk_release_pci_dev(pdev, dev); |
278 279out: 280 return err; 281} 282 | 280 281out: 282 return err; 283} 284 |
283static int pciback_publish_pci_root(struct pciback_device *pdev, | 285static int xen_pcibk_publish_pci_root(struct xen_pcibk_device *pdev, |
284 unsigned int domain, unsigned int bus) 285{ 286 unsigned int d, b; 287 int i, root_num, len, err; 288 char str[64]; 289 290 dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n"); 291 --- 43 unchanged lines hidden (view full) --- 335 336 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, 337 "root_num", "%d", (root_num + 1)); 338 339out: 340 return err; 341} 342 | 286 unsigned int domain, unsigned int bus) 287{ 288 unsigned int d, b; 289 int i, root_num, len, err; 290 char str[64]; 291 292 dev_dbg(&pdev->xdev->dev, "Publishing pci roots\n"); 293 --- 43 unchanged lines hidden (view full) --- 337 338 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, 339 "root_num", "%d", (root_num + 1)); 340 341out: 342 return err; 343} 344 |
343static int pciback_reconfigure(struct pciback_device *pdev) | 345static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) |
344{ 345 int err = 0; 346 int num_devs; 347 int domain, bus, slot, func; 348 int substate; 349 int i, len; 350 char state_str[64]; 351 char dev_str[64]; --- 54 unchanged lines hidden (view full) --- 406 if (err != 4) { 407 err = -EINVAL; 408 xenbus_dev_fatal(pdev->xdev, err, 409 "Error parsing pci device " 410 "configuration"); 411 goto out; 412 } 413 | 346{ 347 int err = 0; 348 int num_devs; 349 int domain, bus, slot, func; 350 int substate; 351 int i, len; 352 char state_str[64]; 353 char dev_str[64]; --- 54 unchanged lines hidden (view full) --- 408 if (err != 4) { 409 err = -EINVAL; 410 xenbus_dev_fatal(pdev->xdev, err, 411 "Error parsing pci device " 412 "configuration"); 413 goto out; 414 } 415 |
414 err = pciback_export_device(pdev, domain, bus, slot, | 416 err = xen_pcibk_export_device(pdev, domain, bus, slot, |
415 func, i); 416 if (err) 417 goto out; 418 419 /* Publish pci roots. */ | 417 func, i); 418 if (err) 419 goto out; 420 421 /* Publish pci roots. */ |
420 err = pciback_publish_pci_roots(pdev, 421 pciback_publish_pci_root); | 422 err = xen_pcibk_publish_pci_roots(pdev, 423 xen_pcibk_publish_pci_root); |
422 if (err) { 423 xenbus_dev_fatal(pdev->xdev, err, 424 "Error while publish PCI root" 425 "buses for frontend"); 426 goto out; 427 } 428 429 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, --- 30 unchanged lines hidden (view full) --- 460 if (err != 4) { 461 err = -EINVAL; 462 xenbus_dev_fatal(pdev->xdev, err, 463 "Error parsing pci device " 464 "configuration"); 465 goto out; 466 } 467 | 424 if (err) { 425 xenbus_dev_fatal(pdev->xdev, err, 426 "Error while publish PCI root" 427 "buses for frontend"); 428 goto out; 429 } 430 431 err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, --- 30 unchanged lines hidden (view full) --- 462 if (err != 4) { 463 err = -EINVAL; 464 xenbus_dev_fatal(pdev->xdev, err, 465 "Error parsing pci device " 466 "configuration"); 467 goto out; 468 } 469 |
468 err = pciback_remove_device(pdev, domain, bus, slot, | 470 err = xen_pcibk_remove_device(pdev, domain, bus, slot, |
469 func); 470 if (err) 471 goto out; 472 473 /* TODO: If at some point we implement support for pci 474 * root hot-remove on pcifront side, we'll need to 475 * remove unnecessary xenstore nodes of pci roots here. 476 */ --- 11 unchanged lines hidden (view full) --- 488 "Error switching to reconfigured state!"); 489 goto out; 490 } 491 492out: 493 return 0; 494} 495 | 471 func); 472 if (err) 473 goto out; 474 475 /* TODO: If at some point we implement support for pci 476 * root hot-remove on pcifront side, we'll need to 477 * remove unnecessary xenstore nodes of pci roots here. 478 */ --- 11 unchanged lines hidden (view full) --- 490 "Error switching to reconfigured state!"); 491 goto out; 492 } 493 494out: 495 return 0; 496} 497 |
496static void pciback_frontend_changed(struct xenbus_device *xdev, | 498static void xen_pcibk_frontend_changed(struct xenbus_device *xdev, |
497 enum xenbus_state fe_state) 498{ | 499 enum xenbus_state fe_state) 500{ |
499 struct pciback_device *pdev = dev_get_drvdata(&xdev->dev); | 501 struct xen_pcibk_device *pdev = dev_get_drvdata(&xdev->dev); |
500 501 dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state); 502 503 switch (fe_state) { 504 case XenbusStateInitialised: | 502 503 dev_dbg(&xdev->dev, "fe state changed %d\n", fe_state); 504 505 switch (fe_state) { 506 case XenbusStateInitialised: |
505 pciback_attach(pdev); | 507 xen_pcibk_attach(pdev); |
506 break; 507 508 case XenbusStateReconfiguring: | 508 break; 509 510 case XenbusStateReconfiguring: |
509 pciback_reconfigure(pdev); | 511 xen_pcibk_reconfigure(pdev); |
510 break; 511 512 case XenbusStateConnected: 513 /* pcifront switched its state from reconfiguring to connected. 514 * Then switch to connected state. 515 */ 516 xenbus_switch_state(xdev, XenbusStateConnected); 517 break; 518 519 case XenbusStateClosing: | 512 break; 513 514 case XenbusStateConnected: 515 /* pcifront switched its state from reconfiguring to connected. 516 * Then switch to connected state. 517 */ 518 xenbus_switch_state(xdev, XenbusStateConnected); 519 break; 520 521 case XenbusStateClosing: |
520 pciback_disconnect(pdev); | 522 xen_pcibk_disconnect(pdev); |
521 xenbus_switch_state(xdev, XenbusStateClosing); 522 break; 523 524 case XenbusStateClosed: | 523 xenbus_switch_state(xdev, XenbusStateClosing); 524 break; 525 526 case XenbusStateClosed: |
525 pciback_disconnect(pdev); | 527 xen_pcibk_disconnect(pdev); |
526 xenbus_switch_state(xdev, XenbusStateClosed); 527 if (xenbus_dev_is_online(xdev)) 528 break; 529 /* fall through if not online */ 530 case XenbusStateUnknown: 531 dev_dbg(&xdev->dev, "frontend is gone! unregister device\n"); 532 device_unregister(&xdev->dev); 533 break; 534 535 default: 536 break; 537 } 538} 539 | 528 xenbus_switch_state(xdev, XenbusStateClosed); 529 if (xenbus_dev_is_online(xdev)) 530 break; 531 /* fall through if not online */ 532 case XenbusStateUnknown: 533 dev_dbg(&xdev->dev, "frontend is gone! unregister device\n"); 534 device_unregister(&xdev->dev); 535 break; 536 537 default: 538 break; 539 } 540} 541 |
540static int pciback_setup_backend(struct pciback_device *pdev) | 542static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev) |
541{ 542 /* Get configuration from xend (if available now) */ 543 int domain, bus, slot, func; 544 int err = 0; 545 int i, num_devs; 546 char dev_str[64]; 547 char state_str[64]; 548 --- 36 unchanged lines hidden (view full) --- 585 if (err != 4) { 586 err = -EINVAL; 587 xenbus_dev_fatal(pdev->xdev, err, 588 "Error parsing pci device " 589 "configuration"); 590 goto out; 591 } 592 | 543{ 544 /* Get configuration from xend (if available now) */ 545 int domain, bus, slot, func; 546 int err = 0; 547 int i, num_devs; 548 char dev_str[64]; 549 char state_str[64]; 550 --- 36 unchanged lines hidden (view full) --- 587 if (err != 4) { 588 err = -EINVAL; 589 xenbus_dev_fatal(pdev->xdev, err, 590 "Error parsing pci device " 591 "configuration"); 592 goto out; 593 } 594 |
593 err = pciback_export_device(pdev, domain, bus, slot, func, i); | 595 err = xen_pcibk_export_device(pdev, domain, bus, slot, func, i); |
594 if (err) 595 goto out; 596 597 /* Switch substate of this device. */ 598 l = snprintf(state_str, sizeof(state_str), "state-%d", i); 599 if (unlikely(l >= (sizeof(state_str) - 1))) { 600 err = -ENOMEM; 601 xenbus_dev_fatal(pdev->xdev, err, --- 5 unchanged lines hidden (view full) --- 607 "%d", XenbusStateInitialised); 608 if (err) { 609 xenbus_dev_fatal(pdev->xdev, err, "Error switching " 610 "substate of dev-%d\n", i); 611 goto out; 612 } 613 } 614 | 596 if (err) 597 goto out; 598 599 /* Switch substate of this device. */ 600 l = snprintf(state_str, sizeof(state_str), "state-%d", i); 601 if (unlikely(l >= (sizeof(state_str) - 1))) { 602 err = -ENOMEM; 603 xenbus_dev_fatal(pdev->xdev, err, --- 5 unchanged lines hidden (view full) --- 609 "%d", XenbusStateInitialised); 610 if (err) { 611 xenbus_dev_fatal(pdev->xdev, err, "Error switching " 612 "substate of dev-%d\n", i); 613 goto out; 614 } 615 } 616 |
615 err = pciback_publish_pci_roots(pdev, pciback_publish_pci_root); | 617 err = xen_pcibk_publish_pci_roots(pdev, xen_pcibk_publish_pci_root); |
616 if (err) { 617 xenbus_dev_fatal(pdev->xdev, err, 618 "Error while publish PCI root buses " 619 "for frontend"); 620 goto out; 621 } 622 623 err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised); 624 if (err) 625 xenbus_dev_fatal(pdev->xdev, err, 626 "Error switching to initialised state!"); 627 628out: 629 if (!err) 630 /* see if pcifront is already configured (if not, we'll wait) */ | 618 if (err) { 619 xenbus_dev_fatal(pdev->xdev, err, 620 "Error while publish PCI root buses " 621 "for frontend"); 622 goto out; 623 } 624 625 err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised); 626 if (err) 627 xenbus_dev_fatal(pdev->xdev, err, 628 "Error switching to initialised state!"); 629 630out: 631 if (!err) 632 /* see if pcifront is already configured (if not, we'll wait) */ |
631 pciback_attach(pdev); | 633 xen_pcibk_attach(pdev); |
632 633 return err; 634} 635 | 634 635 return err; 636} 637 |
636static void pciback_be_watch(struct xenbus_watch *watch, | 638static void xen_pcibk_be_watch(struct xenbus_watch *watch, |
637 const char **vec, unsigned int len) 638{ | 639 const char **vec, unsigned int len) 640{ |
639 struct pciback_device *pdev = 640 container_of(watch, struct pciback_device, be_watch); | 641 struct xen_pcibk_device *pdev = 642 container_of(watch, struct xen_pcibk_device, be_watch); |
641 642 switch (xenbus_read_driver_state(pdev->xdev->nodename)) { 643 case XenbusStateInitWait: | 643 644 switch (xenbus_read_driver_state(pdev->xdev->nodename)) { 645 case XenbusStateInitWait: |
644 pciback_setup_backend(pdev); | 646 xen_pcibk_setup_backend(pdev); |
645 break; 646 647 default: 648 break; 649 } 650} 651 | 647 break; 648 649 default: 650 break; 651 } 652} 653 |
652static int pciback_xenbus_probe(struct xenbus_device *dev, | 654static int xen_pcibk_xenbus_probe(struct xenbus_device *dev, |
653 const struct xenbus_device_id *id) 654{ 655 int err = 0; | 655 const struct xenbus_device_id *id) 656{ 657 int err = 0; |
656 struct pciback_device *pdev = alloc_pdev(dev); | 658 struct xen_pcibk_device *pdev = alloc_pdev(dev); |
657 658 if (pdev == NULL) { 659 err = -ENOMEM; 660 xenbus_dev_fatal(dev, err, | 659 660 if (pdev == NULL) { 661 err = -ENOMEM; 662 xenbus_dev_fatal(dev, err, |
661 "Error allocating pciback_device struct"); | 663 "Error allocating xen_pcibk_device struct"); |
662 goto out; 663 } 664 665 /* wait for xend to configure us */ 666 err = xenbus_switch_state(dev, XenbusStateInitWait); 667 if (err) 668 goto out; 669 670 /* watch the backend node for backend configuration information */ 671 err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch, | 664 goto out; 665 } 666 667 /* wait for xend to configure us */ 668 err = xenbus_switch_state(dev, XenbusStateInitWait); 669 if (err) 670 goto out; 671 672 /* watch the backend node for backend configuration information */ 673 err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch, |
672 pciback_be_watch); | 674 xen_pcibk_be_watch); |
673 if (err) 674 goto out; 675 676 pdev->be_watching = 1; 677 678 /* We need to force a call to our callback here in case 679 * xend already configured us! 680 */ | 675 if (err) 676 goto out; 677 678 pdev->be_watching = 1; 679 680 /* We need to force a call to our callback here in case 681 * xend already configured us! 682 */ |
681 pciback_be_watch(&pdev->be_watch, NULL, 0); | 683 xen_pcibk_be_watch(&pdev->be_watch, NULL, 0); |
682 683out: 684 return err; 685} 686 | 684 685out: 686 return err; 687} 688 |
687static int pciback_xenbus_remove(struct xenbus_device *dev) | 689static int xen_pcibk_xenbus_remove(struct xenbus_device *dev) |
688{ | 690{ |
689 struct pciback_device *pdev = dev_get_drvdata(&dev->dev); | 691 struct xen_pcibk_device *pdev = dev_get_drvdata(&dev->dev); |
690 691 if (pdev != NULL) 692 free_pdev(pdev); 693 694 return 0; 695} 696 697static const struct xenbus_device_id xenpci_ids[] = { 698 {"pci"}, 699 {""}, 700}; 701 | 692 693 if (pdev != NULL) 694 free_pdev(pdev); 695 696 return 0; 697} 698 699static const struct xenbus_device_id xenpci_ids[] = { 700 {"pci"}, 701 {""}, 702}; 703 |
702static struct xenbus_driver xenbus_pciback_driver = { 703 .name = "pciback", | 704static struct xenbus_driver xenbus_xen_pcibk_driver = { 705 .name = DRV_NAME, |
704 .owner = THIS_MODULE, 705 .ids = xenpci_ids, | 706 .owner = THIS_MODULE, 707 .ids = xenpci_ids, |
706 .probe = pciback_xenbus_probe, 707 .remove = pciback_xenbus_remove, 708 .otherend_changed = pciback_frontend_changed, | 708 .probe = xen_pcibk_xenbus_probe, 709 .remove = xen_pcibk_xenbus_remove, 710 .otherend_changed = xen_pcibk_frontend_changed, |
709}; 710 | 711}; 712 |
711int __init pciback_xenbus_register(void) | 713int __init xen_pcibk_xenbus_register(void) |
712{ | 714{ |
713 pciback_wq = create_workqueue("pciback_workqueue"); 714 if (!pciback_wq) { | 715 xen_pcibk_wq = create_workqueue("xen_pciback_workqueue"); 716 if (!xen_pcibk_wq) { |
715 printk(KERN_ERR "%s: create" | 717 printk(KERN_ERR "%s: create" |
716 "pciback_workqueue failed\n", __func__); | 718 "xen_pciback_workqueue failed\n", __func__); |
717 return -EFAULT; 718 } | 719 return -EFAULT; 720 } |
719 return xenbus_register_backend(&xenbus_pciback_driver); | 721 return xenbus_register_backend(&xenbus_xen_pcibk_driver); |
720} 721 | 722} 723 |
722void __exit pciback_xenbus_unregister(void) | 724void __exit xen_pcibk_xenbus_unregister(void) |
723{ | 725{ |
724 destroy_workqueue(pciback_wq); 725 xenbus_unregister_driver(&xenbus_pciback_driver); | 726 destroy_workqueue(xen_pcibk_wq); 727 xenbus_unregister_driver(&xenbus_xen_pcibk_driver); |
726} | 728} |