1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Xen virtual device driver interfaces 29 */ 30 31 /* 32 * todo: 33 * + name space clean up: 34 * xvdi_* - public xen interfaces, for use by all leaf drivers 35 * xd_* - public xen data structures 36 * i_xvdi_* - implementation private functions 37 * xendev_* - xendev driver interfaces, both internal and in cb_ops/bus_ops 38 * + add mdb dcmds to dump ring status 39 * + implement xvdi_xxx to wrap xenbus_xxx read/write function 40 * + convert (xendev_ring_t *) into xvdi_ring_handle_t 41 */ 42 #include <sys/conf.h> 43 #include <sys/param.h> 44 #include <sys/kmem.h> 45 #include <vm/seg_kmem.h> 46 #include <sys/debug.h> 47 #include <sys/modctl.h> 48 #include <sys/autoconf.h> 49 #include <sys/ddi_impldefs.h> 50 #include <sys/ddi_subrdefs.h> 51 #include <sys/ddi.h> 52 #include <sys/sunddi.h> 53 #include <sys/sunndi.h> 54 #include <sys/sunldi.h> 55 #include <sys/fs/dv_node.h> 56 #include <sys/avintr.h> 57 #include <sys/psm.h> 58 #include <sys/spl.h> 59 #include <sys/promif.h> 60 #include <sys/list.h> 61 #include <sys/bootconf.h> 62 #include <sys/bootsvcs.h> 63 #include <sys/bootinfo.h> 64 #include <sys/note.h> 65 #include <sys/sysmacros.h> 66 #ifdef XPV_HVM_DRIVER 67 #include <sys/xpv_support.h> 68 #include <sys/hypervisor.h> 69 #include <public/grant_table.h> 70 #include <public/xen.h> 71 #include <public/io/xenbus.h> 72 #include <public/io/xs_wire.h> 73 #include <public/event_channel.h> 74 #include <public/io/xenbus.h> 75 #else /* XPV_HVM_DRIVER */ 76 #include <sys/hypervisor.h> 77 #include <sys/xen_mmu.h> 78 #include <xen/sys/xenbus_impl.h> 79 #include <sys/evtchn_impl.h> 80 #endif /* XPV_HVM_DRIVER */ 81 #include <sys/gnttab.h> 82 #include <xen/sys/xendev.h> 83 #include <vm/hat_i86.h> 84 #include <sys/scsi/generic/inquiry.h> 85 #include <util/sscanf.h> 86 #include <xen/public/io/xs_wire.h> 87 88 89 #define isdigit(ch) ((ch) >= '0' && (ch) <= '9') 90 #define isxdigit(ch) (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \ 91 ((ch) >= 'A' && (ch) <= 'F')) 92 93 static void xvdi_ring_init_sring(xendev_ring_t *); 94 static void xvdi_ring_init_front_ring(xendev_ring_t *, size_t, size_t); 95 #ifndef XPV_HVM_DRIVER 96 static void xvdi_ring_init_back_ring(xendev_ring_t *, size_t, size_t); 97 #endif 98 static void xvdi_reinit_ring(dev_info_t *, grant_ref_t *, xendev_ring_t *); 99 100 static int i_xvdi_add_watches(dev_info_t *); 101 static void i_xvdi_rem_watches(dev_info_t *); 102 103 static int i_xvdi_add_watch_oestate(dev_info_t *); 104 static void i_xvdi_rem_watch_oestate(dev_info_t *); 105 static void i_xvdi_oestate_cb(struct xenbus_device *, XenbusState); 106 static void i_xvdi_oestate_handler(void *); 107 108 static int i_xvdi_add_watch_hpstate(dev_info_t *); 109 static void i_xvdi_rem_watch_hpstate(dev_info_t *); 110 static void i_xvdi_hpstate_cb(struct xenbus_watch *, const char **, 111 unsigned int); 112 static void i_xvdi_hpstate_handler(void *); 113 114 static int i_xvdi_add_watch_bepath(dev_info_t *); 115 static void i_xvdi_rem_watch_bepath(dev_info_t *); 116 static void i_xvdi_bepath_cb(struct xenbus_watch *, const char **, 117 unsigned in); 118 119 static void xendev_offline_device(void *); 120 121 static void i_xvdi_probe_path_cb(struct xenbus_watch *, const char **, 122 unsigned int); 123 static void i_xvdi_probe_path_handler(void *); 124 125 typedef struct oestate_evt { 126 dev_info_t *dip; 127 XenbusState state; 128 } i_oestate_evt_t; 129 130 typedef struct xd_cfg { 131 xendev_devclass_t devclass; 132 char *xsdev; 133 char *xs_path_fe; 134 char *xs_path_be; 135 char *node_fe; 136 char *node_be; 137 char *device_type; 138 int xd_ipl; 139 int flags; 140 } i_xd_cfg_t; 141 142 #define XD_DOM_ZERO 0x01 /* dom0 only. */ 143 #define XD_DOM_GUEST 0x02 /* Guest domains (i.e. non-dom0). */ 144 #define XD_DOM_IO 0x04 /* IO domains. */ 145 146 #define XD_DOM_ALL (XD_DOM_ZERO | XD_DOM_GUEST) 147 148 static i_xd_cfg_t xdci[] = { 149 { XEN_CONSOLE, NULL, NULL, NULL, "xencons", NULL, 150 "console", IPL_CONS, XD_DOM_ALL, }, 151 152 { XEN_VNET, "vif", "device/vif", "backend/vif", "xnf", "xnb", 153 "network", IPL_VIF, XD_DOM_ALL, }, 154 155 { XEN_VBLK, "vbd", "device/vbd", "backend/vbd", "xdf", "xdb", 156 "block", IPL_VBD, XD_DOM_ALL, }, 157 158 { XEN_BLKTAP, "tap", NULL, "backend/tap", NULL, "xpvtap", 159 "block", IPL_VBD, XD_DOM_ALL, }, 160 161 { XEN_XENBUS, NULL, NULL, NULL, "xenbus", NULL, 162 NULL, 0, XD_DOM_ALL, }, 163 164 { XEN_DOMCAPS, NULL, NULL, NULL, "domcaps", NULL, 165 NULL, 0, XD_DOM_ALL, }, 166 167 { XEN_BALLOON, NULL, NULL, NULL, "balloon", NULL, 168 NULL, 0, XD_DOM_ALL, }, 169 170 { XEN_EVTCHN, NULL, NULL, NULL, "evtchn", NULL, 171 NULL, 0, XD_DOM_ZERO, }, 172 173 { XEN_PRIVCMD, NULL, NULL, NULL, "privcmd", NULL, 174 NULL, 0, XD_DOM_ZERO, }, 175 }; 176 #define NXDC (sizeof (xdci) / sizeof (xdci[0])) 177 178 static void i_xvdi_enum_fe(dev_info_t *, i_xd_cfg_t *); 179 static void i_xvdi_enum_be(dev_info_t *, i_xd_cfg_t *); 180 static void i_xvdi_enum_worker(dev_info_t *, i_xd_cfg_t *, char *); 181 182 /* 183 * Xen device channel device access and DMA attributes 184 */ 185 static ddi_device_acc_attr_t xendev_dc_accattr = { 186 DDI_DEVICE_ATTR_V0, DDI_NEVERSWAP_ACC, DDI_STRICTORDER_ACC 187 }; 188 189 static ddi_dma_attr_t xendev_dc_dmaattr = { 190 DMA_ATTR_V0, /* version of this structure */ 191 0, /* lowest usable address */ 192 0xffffffffffffffffULL, /* highest usable address */ 193 0x7fffffff, /* maximum DMAable byte count */ 194 MMU_PAGESIZE, /* alignment in bytes */ 195 0x7ff, /* bitmap of burst sizes */ 196 1, /* minimum transfer */ 197 0xffffffffU, /* maximum transfer */ 198 0xffffffffffffffffULL, /* maximum segment length */ 199 1, /* maximum number of segments */ 200 1, /* granularity */ 201 0, /* flags (reserved) */ 202 }; 203 204 static dev_info_t *xendev_dip = NULL; 205 206 #define XVDI_DBG_STATE 0x01 207 #define XVDI_DBG_PROBE 0x02 208 209 #ifdef DEBUG 210 int i_xvdi_debug = 0; 211 212 #define XVDI_DPRINTF(flag, format, ...) \ 213 { \ 214 if (i_xvdi_debug & (flag)) \ 215 prom_printf((format), __VA_ARGS__); \ 216 } 217 #else 218 #define XVDI_DPRINTF(flag, format, ...) 219 #endif /* DEBUG */ 220 221 static i_xd_cfg_t * 222 i_xvdi_devclass2cfg(xendev_devclass_t devclass) 223 { 224 i_xd_cfg_t *xdcp; 225 int i; 226 227 for (i = 0, xdcp = xdci; i < NXDC; i++, xdcp++) 228 if (xdcp->devclass == devclass) 229 return (xdcp); 230 231 return (NULL); 232 } 233 234 int 235 xvdi_init_dev(dev_info_t *dip) 236 { 237 xendev_devclass_t devcls; 238 int vdevnum; 239 domid_t domid; 240 struct xendev_ppd *pdp; 241 i_xd_cfg_t *xdcp; 242 boolean_t backend; 243 char xsnamebuf[TYPICALMAXPATHLEN]; 244 char *xsname; 245 void *prop_str; 246 unsigned int prop_len; 247 char unitaddr[8]; 248 249 devcls = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 250 DDI_PROP_DONTPASS, "devclass", XEN_INVAL); 251 vdevnum = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 252 DDI_PROP_DONTPASS, "vdev", VDEV_NOXS); 253 domid = (domid_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip, 254 DDI_PROP_DONTPASS, "domain", DOMID_SELF); 255 256 backend = (domid != DOMID_SELF); 257 xdcp = i_xvdi_devclass2cfg(devcls); 258 if (xdcp->device_type != NULL) 259 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 260 "device_type", xdcp->device_type); 261 262 pdp = kmem_zalloc(sizeof (*pdp), KM_SLEEP); 263 pdp->xd_domain = domid; 264 pdp->xd_vdevnum = vdevnum; 265 pdp->xd_devclass = devcls; 266 pdp->xd_evtchn = INVALID_EVTCHN; 267 list_create(&pdp->xd_xb_watches, sizeof (xd_xb_watches_t), 268 offsetof(xd_xb_watches_t, xxw_list)); 269 mutex_init(&pdp->xd_evt_lk, NULL, MUTEX_DRIVER, NULL); 270 mutex_init(&pdp->xd_ndi_lk, NULL, MUTEX_DRIVER, NULL); 271 ddi_set_parent_data(dip, pdp); 272 273 /* 274 * devices that do not need to interact with xenstore 275 */ 276 if (vdevnum == VDEV_NOXS) { 277 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 278 "unit-address", "0"); 279 if (devcls == XEN_CONSOLE) 280 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 281 "pm-hardware-state", "needs-suspend-resume"); 282 return (DDI_SUCCESS); 283 } 284 285 /* 286 * PV devices that need to probe xenstore 287 */ 288 289 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 290 "pm-hardware-state", "needs-suspend-resume"); 291 292 xsname = xsnamebuf; 293 if (!backend) 294 (void) snprintf(xsnamebuf, sizeof (xsnamebuf), 295 "%s/%d", xdcp->xs_path_fe, vdevnum); 296 else 297 (void) snprintf(xsnamebuf, sizeof (xsnamebuf), 298 "%s/%d/%d", xdcp->xs_path_be, domid, vdevnum); 299 if ((xenbus_read_driver_state(xsname) >= XenbusStateClosing)) { 300 /* Don't try to init a dev that may be closing */ 301 mutex_destroy(&pdp->xd_ndi_lk); 302 mutex_destroy(&pdp->xd_evt_lk); 303 kmem_free(pdp, sizeof (*pdp)); 304 ddi_set_parent_data(dip, NULL); 305 return (DDI_FAILURE); 306 } 307 308 pdp->xd_xsdev.nodename = i_ddi_strdup(xsname, KM_SLEEP); 309 pdp->xd_xsdev.devicetype = xdcp->xsdev; 310 pdp->xd_xsdev.frontend = (backend ? 0 : 1); 311 pdp->xd_xsdev.data = dip; 312 pdp->xd_xsdev.otherend_id = (backend ? domid : -1); 313 if (i_xvdi_add_watches(dip) != DDI_SUCCESS) { 314 cmn_err(CE_WARN, "xvdi_init_dev: " 315 "cannot add watches for %s", xsname); 316 xvdi_uninit_dev(dip); 317 return (DDI_FAILURE); 318 } 319 320 if (backend) 321 return (DDI_SUCCESS); 322 323 /* 324 * The unit-address for frontend devices is the name of the 325 * of the xenstore node containing the device configuration 326 * and is contained in the 'vdev' property. 327 * VIF devices are named using an incrementing integer. 328 * VBD devices are either named using the 16-bit dev_t value 329 * for linux 'hd' and 'xvd' devices, or a simple integer value 330 * in the range 0..767. 768 is the base value of the linux 331 * dev_t namespace, the dev_t value for 'hda'. 332 */ 333 (void) snprintf(unitaddr, sizeof (unitaddr), "%d", vdevnum); 334 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address", 335 unitaddr); 336 337 switch (devcls) { 338 case XEN_VNET: 339 if (xenbus_read(XBT_NULL, xsname, "mac", (void *)&prop_str, 340 &prop_len) != 0) 341 break; 342 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "mac", 343 prop_str); 344 kmem_free(prop_str, prop_len); 345 break; 346 case XEN_VBLK: 347 /* 348 * cache a copy of the otherend name 349 * for ease of observeability 350 */ 351 if (xenbus_read(XBT_NULL, pdp->xd_xsdev.otherend, "dev", 352 &prop_str, &prop_len) != 0) 353 break; 354 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 355 "dev-address", prop_str); 356 kmem_free(prop_str, prop_len); 357 break; 358 default: 359 break; 360 } 361 362 return (DDI_SUCCESS); 363 } 364 365 void 366 xvdi_uninit_dev(dev_info_t *dip) 367 { 368 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 369 370 if (pdp != NULL) { 371 /* Remove any registered callbacks. */ 372 xvdi_remove_event_handler(dip, NULL); 373 374 /* Remove any registered watches. */ 375 i_xvdi_rem_watches(dip); 376 377 /* tell other end to close */ 378 if (pdp->xd_xsdev.otherend_id != (domid_t)-1) 379 (void) xvdi_switch_state(dip, XBT_NULL, 380 XenbusStateClosed); 381 382 if (pdp->xd_xsdev.nodename != NULL) 383 kmem_free((char *)(pdp->xd_xsdev.nodename), 384 strlen(pdp->xd_xsdev.nodename) + 1); 385 386 ddi_set_parent_data(dip, NULL); 387 388 mutex_destroy(&pdp->xd_ndi_lk); 389 mutex_destroy(&pdp->xd_evt_lk); 390 kmem_free(pdp, sizeof (*pdp)); 391 } 392 } 393 394 /* 395 * Bind the event channel for this device instance. 396 * Currently we only support one evtchn per device instance. 397 */ 398 int 399 xvdi_bind_evtchn(dev_info_t *dip, evtchn_port_t evtchn) 400 { 401 struct xendev_ppd *pdp; 402 domid_t oeid; 403 int r; 404 405 pdp = ddi_get_parent_data(dip); 406 ASSERT(pdp != NULL); 407 ASSERT(pdp->xd_evtchn == INVALID_EVTCHN); 408 409 mutex_enter(&pdp->xd_evt_lk); 410 if (pdp->xd_devclass == XEN_CONSOLE) { 411 if (!DOMAIN_IS_INITDOMAIN(xen_info)) { 412 pdp->xd_evtchn = xen_info->console.domU.evtchn; 413 } else { 414 pdp->xd_evtchn = INVALID_EVTCHN; 415 mutex_exit(&pdp->xd_evt_lk); 416 return (DDI_SUCCESS); 417 } 418 } else { 419 oeid = pdp->xd_xsdev.otherend_id; 420 if (oeid == (domid_t)-1) { 421 mutex_exit(&pdp->xd_evt_lk); 422 return (DDI_FAILURE); 423 } 424 425 if ((r = xen_bind_interdomain(oeid, evtchn, &pdp->xd_evtchn))) { 426 xvdi_dev_error(dip, r, "bind event channel"); 427 mutex_exit(&pdp->xd_evt_lk); 428 return (DDI_FAILURE); 429 } 430 } 431 #ifndef XPV_HVM_DRIVER 432 pdp->xd_ispec.intrspec_vec = ec_bind_evtchn_to_irq(pdp->xd_evtchn); 433 #endif 434 mutex_exit(&pdp->xd_evt_lk); 435 436 return (DDI_SUCCESS); 437 } 438 439 /* 440 * Allocate an event channel for this device instance. 441 * Currently we only support one evtchn per device instance. 442 */ 443 int 444 xvdi_alloc_evtchn(dev_info_t *dip) 445 { 446 struct xendev_ppd *pdp; 447 domid_t oeid; 448 int rv; 449 450 pdp = ddi_get_parent_data(dip); 451 ASSERT(pdp != NULL); 452 ASSERT(pdp->xd_evtchn == INVALID_EVTCHN); 453 454 mutex_enter(&pdp->xd_evt_lk); 455 if (pdp->xd_devclass == XEN_CONSOLE) { 456 if (!DOMAIN_IS_INITDOMAIN(xen_info)) { 457 pdp->xd_evtchn = xen_info->console.domU.evtchn; 458 } else { 459 pdp->xd_evtchn = INVALID_EVTCHN; 460 mutex_exit(&pdp->xd_evt_lk); 461 return (DDI_SUCCESS); 462 } 463 } else { 464 oeid = pdp->xd_xsdev.otherend_id; 465 if (oeid == (domid_t)-1) { 466 mutex_exit(&pdp->xd_evt_lk); 467 return (DDI_FAILURE); 468 } 469 470 if ((rv = xen_alloc_unbound_evtchn(oeid, &pdp->xd_evtchn))) { 471 xvdi_dev_error(dip, rv, "bind event channel"); 472 mutex_exit(&pdp->xd_evt_lk); 473 return (DDI_FAILURE); 474 } 475 } 476 #ifndef XPV_HVM_DRIVER 477 pdp->xd_ispec.intrspec_vec = ec_bind_evtchn_to_irq(pdp->xd_evtchn); 478 #endif 479 mutex_exit(&pdp->xd_evt_lk); 480 481 return (DDI_SUCCESS); 482 } 483 484 /* 485 * Unbind the event channel for this device instance. 486 * Currently we only support one evtchn per device instance. 487 */ 488 void 489 xvdi_free_evtchn(dev_info_t *dip) 490 { 491 struct xendev_ppd *pdp; 492 493 pdp = ddi_get_parent_data(dip); 494 ASSERT(pdp != NULL); 495 496 mutex_enter(&pdp->xd_evt_lk); 497 if (pdp->xd_evtchn != INVALID_EVTCHN) { 498 #ifndef XPV_HVM_DRIVER 499 ec_unbind_irq(pdp->xd_ispec.intrspec_vec); 500 pdp->xd_ispec.intrspec_vec = 0; 501 #endif 502 pdp->xd_evtchn = INVALID_EVTCHN; 503 } 504 mutex_exit(&pdp->xd_evt_lk); 505 } 506 507 #ifndef XPV_HVM_DRIVER 508 /* 509 * Map an inter-domain communication ring for a virtual device. 510 * This is used by backend drivers. 511 */ 512 int 513 xvdi_map_ring(dev_info_t *dip, size_t nentry, size_t entrysize, 514 grant_ref_t gref, xendev_ring_t **ringpp) 515 { 516 domid_t oeid; 517 gnttab_map_grant_ref_t mapop; 518 gnttab_unmap_grant_ref_t unmapop; 519 caddr_t ringva; 520 ddi_acc_hdl_t *ap; 521 ddi_acc_impl_t *iap; 522 xendev_ring_t *ring; 523 int err; 524 char errstr[] = "mapping in ring buffer"; 525 526 ring = kmem_zalloc(sizeof (xendev_ring_t), KM_SLEEP); 527 oeid = xvdi_get_oeid(dip); 528 529 /* alloc va in backend dom for ring buffer */ 530 ringva = vmem_xalloc(heap_arena, PAGESIZE, PAGESIZE, 531 0, 0, 0, 0, VM_SLEEP); 532 533 /* map in ring page */ 534 hat_prepare_mapping(kas.a_hat, ringva, NULL); 535 mapop.host_addr = (uint64_t)(uintptr_t)ringva; 536 mapop.flags = GNTMAP_host_map; 537 mapop.ref = gref; 538 mapop.dom = oeid; 539 err = xen_map_gref(GNTTABOP_map_grant_ref, &mapop, 1, B_FALSE); 540 if (err) { 541 xvdi_fatal_error(dip, err, errstr); 542 goto errout1; 543 } 544 545 if (mapop.status != 0) { 546 xvdi_fatal_error(dip, err, errstr); 547 goto errout2; 548 } 549 ring->xr_vaddr = ringva; 550 ring->xr_grant_hdl = mapop.handle; 551 ring->xr_gref = gref; 552 553 /* 554 * init an acc handle and associate it w/ this ring 555 * this is only for backend drivers. we get the memory by calling 556 * vmem_xalloc(), instead of calling any ddi function, so we have 557 * to init an acc handle by ourselves 558 */ 559 ring->xr_acc_hdl = impl_acc_hdl_alloc(KM_SLEEP, NULL); 560 ap = impl_acc_hdl_get(ring->xr_acc_hdl); 561 ap->ah_vers = VERS_ACCHDL; 562 ap->ah_dip = dip; 563 ap->ah_xfermodes = DDI_DMA_CONSISTENT; 564 ap->ah_acc = xendev_dc_accattr; 565 iap = (ddi_acc_impl_t *)ap->ah_platform_private; 566 iap->ahi_acc_attr |= DDI_ACCATTR_CPU_VADDR; 567 impl_acc_hdl_init(ap); 568 ap->ah_offset = 0; 569 ap->ah_len = (off_t)PAGESIZE; 570 ap->ah_addr = ring->xr_vaddr; 571 572 /* init backend ring */ 573 xvdi_ring_init_back_ring(ring, nentry, entrysize); 574 575 *ringpp = ring; 576 577 return (DDI_SUCCESS); 578 579 errout2: 580 /* unmap ring page */ 581 unmapop.host_addr = (uint64_t)(uintptr_t)ringva; 582 unmapop.handle = ring->xr_grant_hdl; 583 unmapop.dev_bus_addr = NULL; 584 (void) HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &unmapop, 1); 585 hat_release_mapping(kas.a_hat, ringva); 586 errout1: 587 vmem_xfree(heap_arena, ringva, PAGESIZE); 588 kmem_free(ring, sizeof (xendev_ring_t)); 589 return (DDI_FAILURE); 590 } 591 592 /* 593 * Unmap a ring for a virtual device. 594 * This is used by backend drivers. 595 */ 596 void 597 xvdi_unmap_ring(xendev_ring_t *ring) 598 { 599 gnttab_unmap_grant_ref_t unmapop; 600 601 ASSERT((ring != NULL) && (ring->xr_vaddr != NULL)); 602 603 impl_acc_hdl_free(ring->xr_acc_hdl); 604 unmapop.host_addr = (uint64_t)(uintptr_t)ring->xr_vaddr; 605 unmapop.handle = ring->xr_grant_hdl; 606 unmapop.dev_bus_addr = NULL; 607 (void) HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &unmapop, 1); 608 hat_release_mapping(kas.a_hat, ring->xr_vaddr); 609 vmem_xfree(heap_arena, ring->xr_vaddr, PAGESIZE); 610 kmem_free(ring, sizeof (xendev_ring_t)); 611 } 612 #endif /* XPV_HVM_DRIVER */ 613 614 /* 615 * Re-initialise an inter-domain communications ring for the backend domain. 616 * ring will be re-initialized after re-grant succeed 617 * ring will be freed if fails to re-grant access to backend domain 618 * so, don't keep useful data in the ring 619 * used only in frontend driver 620 */ 621 static void 622 xvdi_reinit_ring(dev_info_t *dip, grant_ref_t *gref, xendev_ring_t *ringp) 623 { 624 paddr_t rpaddr; 625 maddr_t rmaddr; 626 627 ASSERT((ringp != NULL) && (ringp->xr_paddr != 0)); 628 rpaddr = ringp->xr_paddr; 629 630 rmaddr = DOMAIN_IS_INITDOMAIN(xen_info) ? rpaddr : pa_to_ma(rpaddr); 631 gnttab_grant_foreign_access_ref(ringp->xr_gref, xvdi_get_oeid(dip), 632 rmaddr >> PAGESHIFT, 0); 633 *gref = ringp->xr_gref; 634 635 /* init frontend ring */ 636 xvdi_ring_init_sring(ringp); 637 xvdi_ring_init_front_ring(ringp, ringp->xr_sring.fr.nr_ents, 638 ringp->xr_entry_size); 639 } 640 641 /* 642 * allocate Xen inter-domain communications ring for Xen virtual devices 643 * used only in frontend driver 644 * if *ringpp is not NULL, we'll simply re-init it 645 */ 646 int 647 xvdi_alloc_ring(dev_info_t *dip, size_t nentry, size_t entrysize, 648 grant_ref_t *gref, xendev_ring_t **ringpp) 649 { 650 size_t len; 651 xendev_ring_t *ring; 652 ddi_dma_cookie_t dma_cookie; 653 uint_t ncookies; 654 grant_ref_t ring_gref; 655 domid_t oeid; 656 maddr_t rmaddr; 657 658 if (*ringpp) { 659 xvdi_reinit_ring(dip, gref, *ringpp); 660 return (DDI_SUCCESS); 661 } 662 663 *ringpp = ring = kmem_zalloc(sizeof (xendev_ring_t), KM_SLEEP); 664 oeid = xvdi_get_oeid(dip); 665 666 /* 667 * Allocate page for this ring buffer 668 */ 669 if (ddi_dma_alloc_handle(dip, &xendev_dc_dmaattr, DDI_DMA_SLEEP, 670 0, &ring->xr_dma_hdl) != DDI_SUCCESS) 671 goto err; 672 673 if (ddi_dma_mem_alloc(ring->xr_dma_hdl, PAGESIZE, 674 &xendev_dc_accattr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 0, 675 &ring->xr_vaddr, &len, &ring->xr_acc_hdl) != DDI_SUCCESS) { 676 ddi_dma_free_handle(&ring->xr_dma_hdl); 677 goto err; 678 } 679 680 if (ddi_dma_addr_bind_handle(ring->xr_dma_hdl, NULL, 681 ring->xr_vaddr, len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 682 DDI_DMA_SLEEP, 0, &dma_cookie, &ncookies) != DDI_DMA_MAPPED) { 683 ddi_dma_mem_free(&ring->xr_acc_hdl); 684 ring->xr_vaddr = NULL; 685 ddi_dma_free_handle(&ring->xr_dma_hdl); 686 goto err; 687 } 688 ASSERT(ncookies == 1); 689 ring->xr_paddr = dma_cookie.dmac_laddress; 690 rmaddr = DOMAIN_IS_INITDOMAIN(xen_info) ? ring->xr_paddr : 691 pa_to_ma(ring->xr_paddr); 692 693 if ((ring_gref = gnttab_grant_foreign_access(oeid, 694 rmaddr >> PAGESHIFT, 0)) == (grant_ref_t)-1) { 695 (void) ddi_dma_unbind_handle(ring->xr_dma_hdl); 696 ddi_dma_mem_free(&ring->xr_acc_hdl); 697 ring->xr_vaddr = NULL; 698 ddi_dma_free_handle(&ring->xr_dma_hdl); 699 goto err; 700 } 701 *gref = ring->xr_gref = ring_gref; 702 703 /* init frontend ring */ 704 xvdi_ring_init_sring(ring); 705 xvdi_ring_init_front_ring(ring, nentry, entrysize); 706 707 return (DDI_SUCCESS); 708 709 err: 710 kmem_free(ring, sizeof (xendev_ring_t)); 711 return (DDI_FAILURE); 712 } 713 714 /* 715 * Release ring buffers allocated for Xen devices 716 * used for frontend driver 717 */ 718 void 719 xvdi_free_ring(xendev_ring_t *ring) 720 { 721 ASSERT((ring != NULL) && (ring->xr_vaddr != NULL)); 722 723 (void) gnttab_end_foreign_access_ref(ring->xr_gref, 0); 724 (void) ddi_dma_unbind_handle(ring->xr_dma_hdl); 725 ddi_dma_mem_free(&ring->xr_acc_hdl); 726 ddi_dma_free_handle(&ring->xr_dma_hdl); 727 kmem_free(ring, sizeof (xendev_ring_t)); 728 } 729 730 dev_info_t * 731 xvdi_create_dev(dev_info_t *parent, xendev_devclass_t devclass, 732 domid_t dom, int vdev) 733 { 734 dev_info_t *dip; 735 boolean_t backend; 736 i_xd_cfg_t *xdcp; 737 char xsnamebuf[TYPICALMAXPATHLEN]; 738 char *type, *node = NULL, *xsname = NULL; 739 unsigned int tlen; 740 int ret; 741 742 ASSERT(DEVI_BUSY_OWNED(parent)); 743 744 backend = (dom != DOMID_SELF); 745 xdcp = i_xvdi_devclass2cfg(devclass); 746 ASSERT(xdcp != NULL); 747 748 if (vdev != VDEV_NOXS) { 749 if (!backend) { 750 (void) snprintf(xsnamebuf, sizeof (xsnamebuf), 751 "%s/%d", xdcp->xs_path_fe, vdev); 752 xsname = xsnamebuf; 753 node = xdcp->node_fe; 754 } else { 755 (void) snprintf(xsnamebuf, sizeof (xsnamebuf), 756 "%s/%d/%d", xdcp->xs_path_be, dom, vdev); 757 xsname = xsnamebuf; 758 node = xdcp->node_be; 759 } 760 } else { 761 node = xdcp->node_fe; 762 } 763 764 /* Must have a driver to use. */ 765 if (node == NULL) 766 return (NULL); 767 768 /* 769 * We need to check the state of this device before we go 770 * further, otherwise we'll end up with a dead loop if 771 * anything goes wrong. 772 */ 773 if ((xsname != NULL) && 774 (xenbus_read_driver_state(xsname) >= XenbusStateClosing)) 775 return (NULL); 776 777 ndi_devi_alloc_sleep(parent, node, DEVI_SID_NODEID, &dip); 778 779 /* 780 * Driver binding uses the compatible property _before_ the 781 * node name, so we set the node name to the 'model' of the 782 * device (i.e. 'xnb' or 'xdb') and, if 'type' is present, 783 * encode both the model and the type in a compatible property 784 * (i.e. 'xnb,netfront' or 'xnb,SUNW_mac'). This allows a 785 * driver binding based on the <model,type> pair _before_ a 786 * binding based on the node name. 787 */ 788 if ((xsname != NULL) && 789 (xenbus_read(XBT_NULL, xsname, "type", (void *)&type, &tlen) 790 == 0)) { 791 size_t clen; 792 char *c[1]; 793 794 clen = strlen(node) + strlen(type) + 2; 795 c[0] = kmem_alloc(clen, KM_SLEEP); 796 (void) snprintf(c[0], clen, "%s,%s", node, type); 797 798 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, 799 dip, "compatible", (char **)c, 1); 800 801 kmem_free(c[0], clen); 802 kmem_free(type, tlen); 803 } 804 805 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "devclass", devclass); 806 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "domain", dom); 807 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vdev", vdev); 808 809 if (i_ddi_devi_attached(parent)) 810 ret = ndi_devi_online(dip, 0); 811 else 812 ret = ndi_devi_bind_driver(dip, 0); 813 if (ret != NDI_SUCCESS) 814 (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE); 815 816 return (dip); 817 } 818 819 /* 820 * xendev_enum_class() 821 */ 822 void 823 xendev_enum_class(dev_info_t *parent, xendev_devclass_t devclass) 824 { 825 boolean_t dom0 = DOMAIN_IS_INITDOMAIN(xen_info); 826 boolean_t domU = !dom0; 827 i_xd_cfg_t *xdcp; 828 829 xdcp = i_xvdi_devclass2cfg(devclass); 830 ASSERT(xdcp != NULL); 831 832 if (dom0 && !(xdcp->flags & XD_DOM_ZERO)) 833 return; 834 835 if (domU && !(xdcp->flags & XD_DOM_GUEST)) 836 return; 837 838 if (xdcp->xsdev == NULL) { 839 int circ; 840 841 /* 842 * Don't need to probe this kind of device from the 843 * store, just create one if it doesn't exist. 844 */ 845 846 ndi_devi_enter(parent, &circ); 847 if (xvdi_find_dev(parent, devclass, DOMID_SELF, VDEV_NOXS) 848 == NULL) 849 (void) xvdi_create_dev(parent, devclass, 850 DOMID_SELF, VDEV_NOXS); 851 ndi_devi_exit(parent, circ); 852 } else { 853 /* 854 * Probe this kind of device from the store, both 855 * frontend and backend. 856 */ 857 if (xdcp->node_fe != NULL) { 858 i_xvdi_enum_fe(parent, xdcp); 859 } 860 if (xdcp->node_be != NULL) { 861 i_xvdi_enum_be(parent, xdcp); 862 } 863 } 864 } 865 866 /* 867 * xendev_enum_all() 868 */ 869 void 870 xendev_enum_all(dev_info_t *parent, boolean_t store_unavailable) 871 { 872 int i; 873 i_xd_cfg_t *xdcp; 874 boolean_t dom0 = DOMAIN_IS_INITDOMAIN(xen_info); 875 876 for (i = 0, xdcp = xdci; i < NXDC; i++, xdcp++) { 877 /* 878 * Dom0 relies on watchpoints to create non-soft 879 * devices - don't attempt to iterate over the store. 880 */ 881 if (dom0 && (xdcp->xsdev != NULL)) 882 continue; 883 884 /* 885 * If the store is not yet available, don't attempt to 886 * iterate. 887 */ 888 if (store_unavailable && (xdcp->xsdev != NULL)) 889 continue; 890 891 xendev_enum_class(parent, xdcp->devclass); 892 } 893 } 894 895 xendev_devclass_t 896 xendev_nodename_to_devclass(char *nodename) 897 { 898 int i; 899 i_xd_cfg_t *xdcp; 900 901 /* 902 * This relies on the convention that variants of a base 903 * driver share the same prefix and that there are no drivers 904 * which share a common prefix with the name of any other base 905 * drivers. 906 * 907 * So for a base driver 'xnb' (which is the name listed in 908 * xdci) the variants all begin with the string 'xnb' (in fact 909 * they are 'xnbe', 'xnbo' and 'xnbu') and there are no other 910 * base drivers which have the prefix 'xnb'. 911 */ 912 ASSERT(nodename != NULL); 913 for (i = 0, xdcp = xdci; i < NXDC; i++, xdcp++) { 914 if (((xdcp->node_fe != NULL) && 915 (strncmp(nodename, xdcp->node_fe, 916 strlen(xdcp->node_fe)) == 0)) || 917 ((xdcp->node_be != NULL) && 918 (strncmp(nodename, xdcp->node_be, 919 strlen(xdcp->node_be)) == 0))) 920 921 return (xdcp->devclass); 922 } 923 return (XEN_INVAL); 924 } 925 926 int 927 xendev_devclass_ipl(xendev_devclass_t devclass) 928 { 929 i_xd_cfg_t *xdcp; 930 931 xdcp = i_xvdi_devclass2cfg(devclass); 932 ASSERT(xdcp != NULL); 933 934 return (xdcp->xd_ipl); 935 } 936 937 /* 938 * Determine if a devinfo instance exists of a particular device 939 * class, domain and xenstore virtual device number. 940 */ 941 dev_info_t * 942 xvdi_find_dev(dev_info_t *parent, xendev_devclass_t devclass, 943 domid_t dom, int vdev) 944 { 945 dev_info_t *dip; 946 947 ASSERT(DEVI_BUSY_OWNED(parent)); 948 949 switch (devclass) { 950 case XEN_CONSOLE: 951 case XEN_XENBUS: 952 case XEN_DOMCAPS: 953 case XEN_BALLOON: 954 case XEN_EVTCHN: 955 case XEN_PRIVCMD: 956 /* Console and soft devices have no vdev. */ 957 vdev = VDEV_NOXS; 958 break; 959 default: 960 break; 961 } 962 963 for (dip = ddi_get_child(parent); dip != NULL; 964 dip = ddi_get_next_sibling(dip)) { 965 int *vdevnump, *domidp, *devclsp, vdevnum; 966 uint_t ndomid, nvdevnum, ndevcls; 967 xendev_devclass_t devcls; 968 domid_t domid; 969 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 970 971 if (pdp == NULL) { 972 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 973 DDI_PROP_DONTPASS, "domain", &domidp, &ndomid) != 974 DDI_PROP_SUCCESS) 975 continue; 976 ASSERT(ndomid == 1); 977 domid = (domid_t)*domidp; 978 ddi_prop_free(domidp); 979 980 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 981 DDI_PROP_DONTPASS, "vdev", &vdevnump, &nvdevnum) != 982 DDI_PROP_SUCCESS) 983 continue; 984 ASSERT(nvdevnum == 1); 985 vdevnum = *vdevnump; 986 ddi_prop_free(vdevnump); 987 988 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 989 DDI_PROP_DONTPASS, "devclass", &devclsp, 990 &ndevcls) != DDI_PROP_SUCCESS) 991 continue; 992 ASSERT(ndevcls == 1); 993 devcls = (xendev_devclass_t)*devclsp; 994 ddi_prop_free(devclsp); 995 } else { 996 domid = pdp->xd_domain; 997 vdevnum = pdp->xd_vdevnum; 998 devcls = pdp->xd_devclass; 999 } 1000 1001 if ((domid == dom) && (vdevnum == vdev) && (devcls == devclass)) 1002 return (dip); 1003 } 1004 return (NULL); 1005 } 1006 1007 int 1008 xvdi_get_evtchn(dev_info_t *xdip) 1009 { 1010 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1011 1012 ASSERT(pdp != NULL); 1013 return (pdp->xd_evtchn); 1014 } 1015 1016 int 1017 xvdi_get_vdevnum(dev_info_t *xdip) 1018 { 1019 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1020 1021 ASSERT(pdp != NULL); 1022 return (pdp->xd_vdevnum); 1023 } 1024 1025 char * 1026 xvdi_get_xsname(dev_info_t *xdip) 1027 { 1028 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1029 1030 ASSERT(pdp != NULL); 1031 return ((char *)(pdp->xd_xsdev.nodename)); 1032 } 1033 1034 char * 1035 xvdi_get_oename(dev_info_t *xdip) 1036 { 1037 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1038 1039 ASSERT(pdp != NULL); 1040 if (pdp->xd_devclass == XEN_CONSOLE) 1041 return (NULL); 1042 return ((char *)(pdp->xd_xsdev.otherend)); 1043 } 1044 1045 struct xenbus_device * 1046 xvdi_get_xsd(dev_info_t *xdip) 1047 { 1048 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1049 1050 ASSERT(pdp != NULL); 1051 return (&pdp->xd_xsdev); 1052 } 1053 1054 domid_t 1055 xvdi_get_oeid(dev_info_t *xdip) 1056 { 1057 struct xendev_ppd *pdp = ddi_get_parent_data(xdip); 1058 1059 ASSERT(pdp != NULL); 1060 if (pdp->xd_devclass == XEN_CONSOLE) 1061 return ((domid_t)-1); 1062 return ((domid_t)(pdp->xd_xsdev.otherend_id)); 1063 } 1064 1065 void 1066 xvdi_dev_error(dev_info_t *dip, int errno, char *errstr) 1067 { 1068 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1069 1070 ASSERT(pdp != NULL); 1071 xenbus_dev_error(&pdp->xd_xsdev, errno, errstr); 1072 } 1073 1074 void 1075 xvdi_fatal_error(dev_info_t *dip, int errno, char *errstr) 1076 { 1077 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1078 1079 ASSERT(pdp != NULL); 1080 xenbus_dev_fatal(&pdp->xd_xsdev, errno, errstr); 1081 } 1082 1083 static void 1084 i_xvdi_oestate_handler(void *arg) 1085 { 1086 i_oestate_evt_t *evt = (i_oestate_evt_t *)arg; 1087 dev_info_t *dip = evt->dip; 1088 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1089 XenbusState oestate = pdp->xd_xsdev.otherend_state; 1090 XenbusState curr_oestate = evt->state; 1091 ddi_eventcookie_t evc; 1092 1093 /* evt is alloc'ed in i_xvdi_oestate_cb */ 1094 kmem_free(evt, sizeof (i_oestate_evt_t)); 1095 1096 /* 1097 * If the oestate we're handling is not the latest one, 1098 * it does not make any sense to continue handling it. 1099 */ 1100 if (curr_oestate != oestate) 1101 return; 1102 1103 mutex_enter(&pdp->xd_ndi_lk); 1104 1105 if (pdp->xd_oe_ehid != NULL) { 1106 /* send notification to driver */ 1107 if (ddi_get_eventcookie(dip, XS_OE_STATE, 1108 &evc) == DDI_SUCCESS) { 1109 mutex_exit(&pdp->xd_ndi_lk); 1110 (void) ndi_post_event(dip, dip, evc, &oestate); 1111 mutex_enter(&pdp->xd_ndi_lk); 1112 } 1113 } else { 1114 /* 1115 * take default action, if driver hasn't registered its 1116 * event handler yet 1117 */ 1118 if (oestate == XenbusStateClosing) { 1119 (void) xvdi_switch_state(dip, XBT_NULL, 1120 XenbusStateClosed); 1121 } else if (oestate == XenbusStateClosed) { 1122 (void) xvdi_switch_state(dip, XBT_NULL, 1123 XenbusStateClosed); 1124 (void) xvdi_post_event(dip, XEN_HP_REMOVE); 1125 } 1126 } 1127 1128 mutex_exit(&pdp->xd_ndi_lk); 1129 1130 /* 1131 * We'll try to remove the devinfo node of this device if the 1132 * other end has closed. 1133 */ 1134 if (oestate == XenbusStateClosed) 1135 (void) ddi_taskq_dispatch(DEVI(ddi_get_parent(dip))->devi_taskq, 1136 xendev_offline_device, dip, DDI_SLEEP); 1137 } 1138 1139 static void 1140 i_xvdi_hpstate_handler(void *arg) 1141 { 1142 dev_info_t *dip = (dev_info_t *)arg; 1143 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1144 ddi_eventcookie_t evc; 1145 char *hp_status; 1146 unsigned int hpl; 1147 1148 mutex_enter(&pdp->xd_ndi_lk); 1149 if ((ddi_get_eventcookie(dip, XS_HP_STATE, &evc) == DDI_SUCCESS) && 1150 (xenbus_read(XBT_NULL, pdp->xd_hp_watch.node, "", 1151 (void *)&hp_status, &hpl) == 0)) { 1152 1153 xendev_hotplug_state_t new_state = Unrecognized; 1154 1155 if (strcmp(hp_status, "connected") == 0) 1156 new_state = Connected; 1157 1158 mutex_exit(&pdp->xd_ndi_lk); 1159 1160 (void) ndi_post_event(dip, dip, evc, &new_state); 1161 kmem_free(hp_status, hpl); 1162 return; 1163 } 1164 mutex_exit(&pdp->xd_ndi_lk); 1165 } 1166 1167 void 1168 xvdi_notify_oe(dev_info_t *dip) 1169 { 1170 struct xendev_ppd *pdp; 1171 1172 pdp = ddi_get_parent_data(dip); 1173 ASSERT(pdp->xd_evtchn != INVALID_EVTCHN); 1174 ec_notify_via_evtchn(pdp->xd_evtchn); 1175 } 1176 1177 static void 1178 i_xvdi_bepath_cb(struct xenbus_watch *w, const char **vec, unsigned int len) 1179 { 1180 dev_info_t *dip = (dev_info_t *)w->dev; 1181 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1182 char *be = NULL; 1183 unsigned int bel; 1184 1185 ASSERT(len > XS_WATCH_PATH); 1186 ASSERT(vec[XS_WATCH_PATH] != NULL); 1187 1188 /* 1189 * If the backend is not the same as that we already stored, 1190 * re-set our watch for its' state. 1191 */ 1192 if ((xenbus_read(XBT_NULL, "", vec[XS_WATCH_PATH], (void *)be, &bel) 1193 == 0) && (strcmp(be, pdp->xd_xsdev.otherend) != 0)) 1194 (void) i_xvdi_add_watch_oestate(dip); 1195 1196 if (be != NULL) { 1197 ASSERT(bel > 0); 1198 kmem_free(be, bel); 1199 } 1200 } 1201 1202 static void 1203 i_xvdi_xb_watch_free(xd_xb_watches_t *xxwp) 1204 { 1205 ASSERT(xxwp->xxw_ref == 0); 1206 strfree((char *)xxwp->xxw_watch.node); 1207 kmem_free(xxwp, sizeof (*xxwp)); 1208 } 1209 1210 static void 1211 i_xvdi_xb_watch_release(xd_xb_watches_t *xxwp) 1212 { 1213 ASSERT(MUTEX_HELD(&xxwp->xxw_xppd->xd_ndi_lk)); 1214 ASSERT(xxwp->xxw_ref > 0); 1215 if (--xxwp->xxw_ref == 0) 1216 i_xvdi_xb_watch_free(xxwp); 1217 } 1218 1219 static void 1220 i_xvdi_xb_watch_hold(xd_xb_watches_t *xxwp) 1221 { 1222 ASSERT(MUTEX_HELD(&xxwp->xxw_xppd->xd_ndi_lk)); 1223 ASSERT(xxwp->xxw_ref > 0); 1224 xxwp->xxw_ref++; 1225 } 1226 1227 static void 1228 i_xvdi_xb_watch_cb_tq(void *arg) 1229 { 1230 xd_xb_watches_t *xxwp = (xd_xb_watches_t *)arg; 1231 dev_info_t *dip = (dev_info_t *)xxwp->xxw_watch.dev; 1232 struct xendev_ppd *pdp = xxwp->xxw_xppd; 1233 1234 xxwp->xxw_cb(dip, xxwp->xxw_watch.node, xxwp->xxw_arg); 1235 1236 mutex_enter(&pdp->xd_ndi_lk); 1237 i_xvdi_xb_watch_release(xxwp); 1238 mutex_exit(&pdp->xd_ndi_lk); 1239 } 1240 1241 static void 1242 i_xvdi_xb_watch_cb(struct xenbus_watch *w, const char **vec, unsigned int len) 1243 { 1244 dev_info_t *dip = (dev_info_t *)w->dev; 1245 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1246 xd_xb_watches_t *xxwp; 1247 1248 ASSERT(len > XS_WATCH_PATH); 1249 ASSERT(vec[XS_WATCH_PATH] != NULL); 1250 1251 mutex_enter(&pdp->xd_ndi_lk); 1252 for (xxwp = list_head(&pdp->xd_xb_watches); xxwp != NULL; 1253 xxwp = list_next(&pdp->xd_xb_watches, xxwp)) { 1254 if (w == &xxwp->xxw_watch) 1255 break; 1256 } 1257 1258 if (xxwp == NULL) { 1259 mutex_exit(&pdp->xd_ndi_lk); 1260 return; 1261 } 1262 1263 i_xvdi_xb_watch_hold(xxwp); 1264 (void) ddi_taskq_dispatch(pdp->xd_xb_watch_taskq, 1265 i_xvdi_xb_watch_cb_tq, xxwp, DDI_SLEEP); 1266 mutex_exit(&pdp->xd_ndi_lk); 1267 } 1268 1269 /* 1270 * Any watches registered with xvdi_add_xb_watch_handler() get torn down during 1271 * a suspend operation. So if a frontend driver want's to use these interfaces, 1272 * that driver is responsible for re-registering any watches it had before 1273 * the suspend operation. 1274 */ 1275 int 1276 xvdi_add_xb_watch_handler(dev_info_t *dip, const char *dir, const char *node, 1277 xvdi_xb_watch_cb_t cb, void *arg) 1278 { 1279 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1280 xd_xb_watches_t *xxw_new, *xxwp; 1281 char *path; 1282 int n; 1283 1284 ASSERT((dip != NULL) && (dir != NULL) && (node != NULL)); 1285 ASSERT(cb != NULL); 1286 1287 n = strlen(dir) + 1 + strlen(node) + 1; 1288 path = kmem_zalloc(n, KM_SLEEP); 1289 (void) strlcat(path, dir, n); 1290 (void) strlcat(path, "/", n); 1291 (void) strlcat(path, node, n); 1292 ASSERT((strlen(path) + 1) == n); 1293 1294 xxw_new = kmem_zalloc(sizeof (*xxw_new), KM_SLEEP); 1295 xxw_new->xxw_ref = 1; 1296 xxw_new->xxw_watch.node = path; 1297 xxw_new->xxw_watch.callback = i_xvdi_xb_watch_cb; 1298 xxw_new->xxw_watch.dev = (struct xenbus_device *)dip; 1299 xxw_new->xxw_xppd = pdp; 1300 xxw_new->xxw_cb = cb; 1301 xxw_new->xxw_arg = arg; 1302 1303 mutex_enter(&pdp->xd_ndi_lk); 1304 1305 /* 1306 * If this is the first watch we're setting up, create a taskq 1307 * to dispatch watch events and initialize the watch list. 1308 */ 1309 if (pdp->xd_xb_watch_taskq == NULL) { 1310 char tq_name[TASKQ_NAMELEN]; 1311 1312 ASSERT(list_is_empty(&pdp->xd_xb_watches)); 1313 1314 (void) snprintf(tq_name, sizeof (tq_name), 1315 "%s_xb_watch_tq", ddi_get_name(dip)); 1316 1317 if ((pdp->xd_xb_watch_taskq = ddi_taskq_create(dip, tq_name, 1318 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1319 i_xvdi_xb_watch_release(xxw_new); 1320 mutex_exit(&pdp->xd_ndi_lk); 1321 return (DDI_FAILURE); 1322 } 1323 } 1324 1325 /* Don't allow duplicate watches to be registered */ 1326 for (xxwp = list_head(&pdp->xd_xb_watches); xxwp != NULL; 1327 xxwp = list_next(&pdp->xd_xb_watches, xxwp)) { 1328 1329 ASSERT(strcmp(xxwp->xxw_watch.node, path) != 0); 1330 if (strcmp(xxwp->xxw_watch.node, path) != 0) 1331 continue; 1332 i_xvdi_xb_watch_release(xxw_new); 1333 mutex_exit(&pdp->xd_ndi_lk); 1334 return (DDI_FAILURE); 1335 } 1336 1337 if (register_xenbus_watch(&xxw_new->xxw_watch) != 0) { 1338 if (list_is_empty(&pdp->xd_xb_watches)) { 1339 ddi_taskq_destroy(pdp->xd_xb_watch_taskq); 1340 pdp->xd_xb_watch_taskq = NULL; 1341 } 1342 i_xvdi_xb_watch_release(xxw_new); 1343 mutex_exit(&pdp->xd_ndi_lk); 1344 return (DDI_FAILURE); 1345 } 1346 1347 list_insert_head(&pdp->xd_xb_watches, xxw_new); 1348 mutex_exit(&pdp->xd_ndi_lk); 1349 return (DDI_SUCCESS); 1350 } 1351 1352 /* 1353 * Tear down all xenbus watches registered by the specified dip. 1354 */ 1355 void 1356 xvdi_remove_xb_watch_handlers(dev_info_t *dip) 1357 { 1358 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1359 xd_xb_watches_t *xxwp; 1360 ddi_taskq_t *tq; 1361 1362 mutex_enter(&pdp->xd_ndi_lk); 1363 1364 while ((xxwp = list_remove_head(&pdp->xd_xb_watches)) != NULL) { 1365 mutex_exit(&pdp->xd_ndi_lk); 1366 unregister_xenbus_watch(&xxwp->xxw_watch); 1367 mutex_enter(&pdp->xd_ndi_lk); 1368 i_xvdi_xb_watch_release(xxwp); 1369 } 1370 ASSERT(list_is_empty(&pdp->xd_xb_watches)); 1371 1372 /* 1373 * We can't hold xd_ndi_lk while we destroy the xd_xb_watch_taskq. 1374 * This is because if there are currently any executing taskq threads, 1375 * we will block until they are finished, and to finish they need 1376 * to aquire xd_ndi_lk in i_xvdi_xb_watch_cb_tq() so they can release 1377 * their reference on their corresponding xxwp structure. 1378 */ 1379 tq = pdp->xd_xb_watch_taskq; 1380 pdp->xd_xb_watch_taskq = NULL; 1381 mutex_exit(&pdp->xd_ndi_lk); 1382 if (tq != NULL) 1383 ddi_taskq_destroy(tq); 1384 } 1385 1386 static int 1387 i_xvdi_add_watch_oestate(dev_info_t *dip) 1388 { 1389 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1390 1391 ASSERT(pdp != NULL); 1392 ASSERT(pdp->xd_xsdev.nodename != NULL); 1393 ASSERT(mutex_owned(&pdp->xd_ndi_lk)); 1394 1395 /* 1396 * Create taskq for delivering other end state change event to 1397 * this device later. 1398 * 1399 * Set nthreads to 1 to make sure that events can be delivered 1400 * in order. 1401 * 1402 * Note: It is _not_ guaranteed that driver can see every 1403 * xenstore change under the path that it is watching. If two 1404 * changes happen consecutively in a very short amount of 1405 * time, it is likely that the driver will see only the last 1406 * one. 1407 */ 1408 if (pdp->xd_oe_taskq == NULL) 1409 if ((pdp->xd_oe_taskq = ddi_taskq_create(dip, 1410 "xendev_oe_taskq", 1, TASKQ_DEFAULTPRI, 0)) == NULL) 1411 return (DDI_FAILURE); 1412 1413 /* 1414 * Watch for changes to the XenbusState of otherend. 1415 */ 1416 pdp->xd_xsdev.otherend_state = XenbusStateUnknown; 1417 pdp->xd_xsdev.otherend_changed = i_xvdi_oestate_cb; 1418 1419 if (talk_to_otherend(&pdp->xd_xsdev) != 0) { 1420 i_xvdi_rem_watch_oestate(dip); 1421 return (DDI_FAILURE); 1422 } 1423 1424 return (DDI_SUCCESS); 1425 } 1426 1427 static void 1428 i_xvdi_rem_watch_oestate(dev_info_t *dip) 1429 { 1430 struct xendev_ppd *pdp; 1431 struct xenbus_device *dev; 1432 1433 pdp = ddi_get_parent_data(dip); 1434 ASSERT(pdp != NULL); 1435 ASSERT(mutex_owned(&pdp->xd_ndi_lk)); 1436 1437 dev = &pdp->xd_xsdev; 1438 1439 /* Unwatch for changes to XenbusState of otherend */ 1440 if (dev->otherend_watch.node != NULL) { 1441 mutex_exit(&pdp->xd_ndi_lk); 1442 unregister_xenbus_watch(&dev->otherend_watch); 1443 mutex_enter(&pdp->xd_ndi_lk); 1444 } 1445 1446 /* make sure no event handler is running */ 1447 if (pdp->xd_oe_taskq != NULL) { 1448 mutex_exit(&pdp->xd_ndi_lk); 1449 ddi_taskq_destroy(pdp->xd_oe_taskq); 1450 mutex_enter(&pdp->xd_ndi_lk); 1451 pdp->xd_oe_taskq = NULL; 1452 } 1453 1454 /* clean up */ 1455 dev->otherend_state = XenbusStateUnknown; 1456 dev->otherend_id = (domid_t)-1; 1457 if (dev->otherend_watch.node != NULL) 1458 kmem_free((void *)dev->otherend_watch.node, 1459 strlen(dev->otherend_watch.node) + 1); 1460 dev->otherend_watch.node = NULL; 1461 if (dev->otherend != NULL) 1462 kmem_free((void *)dev->otherend, strlen(dev->otherend) + 1); 1463 dev->otherend = NULL; 1464 } 1465 1466 static int 1467 i_xvdi_add_watch_hpstate(dev_info_t *dip) 1468 { 1469 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1470 1471 ASSERT(pdp != NULL); 1472 ASSERT(pdp->xd_xsdev.frontend == 0); 1473 ASSERT(mutex_owned(&pdp->xd_ndi_lk)); 1474 1475 /* 1476 * Create taskq for delivering hotplug status change event to 1477 * this device later. 1478 * 1479 * Set nthreads to 1 to make sure that events can be delivered 1480 * in order. 1481 * 1482 * Note: It is _not_ guaranteed that driver can see every 1483 * hotplug status change under the path that it is 1484 * watching. If two changes happen consecutively in a very 1485 * short amount of time, it is likely that the driver only 1486 * sees the last one. 1487 */ 1488 if (pdp->xd_hp_taskq == NULL) 1489 if ((pdp->xd_hp_taskq = ddi_taskq_create(dip, 1490 "xendev_hp_taskq", 1, TASKQ_DEFAULTPRI, 0)) == NULL) 1491 return (DDI_FAILURE); 1492 1493 if (pdp->xd_hp_watch.node == NULL) { 1494 size_t len; 1495 char *path; 1496 1497 ASSERT(pdp->xd_xsdev.nodename != NULL); 1498 1499 len = strlen(pdp->xd_xsdev.nodename) + 1500 strlen("/hotplug-status") + 1; 1501 path = kmem_alloc(len, KM_SLEEP); 1502 (void) snprintf(path, len, "%s/hotplug-status", 1503 pdp->xd_xsdev.nodename); 1504 1505 pdp->xd_hp_watch.node = path; 1506 pdp->xd_hp_watch.callback = i_xvdi_hpstate_cb; 1507 pdp->xd_hp_watch.dev = (struct xenbus_device *)dip; /* yuck! */ 1508 if (register_xenbus_watch(&pdp->xd_hp_watch) != 0) { 1509 i_xvdi_rem_watch_hpstate(dip); 1510 return (DDI_FAILURE); 1511 } 1512 } 1513 1514 return (DDI_SUCCESS); 1515 } 1516 1517 static void 1518 i_xvdi_rem_watch_hpstate(dev_info_t *dip) 1519 { 1520 struct xendev_ppd *pdp; 1521 pdp = ddi_get_parent_data(dip); 1522 1523 ASSERT(pdp != NULL); 1524 ASSERT(pdp->xd_xsdev.frontend == 0); 1525 ASSERT(mutex_owned(&pdp->xd_ndi_lk)); 1526 1527 /* Unwatch for changes to "hotplug-status" node for backend device. */ 1528 if (pdp->xd_hp_watch.node != NULL) { 1529 mutex_exit(&pdp->xd_ndi_lk); 1530 unregister_xenbus_watch(&pdp->xd_hp_watch); 1531 mutex_enter(&pdp->xd_ndi_lk); 1532 } 1533 1534 /* Make sure no event handler is running. */ 1535 if (pdp->xd_hp_taskq != NULL) { 1536 mutex_exit(&pdp->xd_ndi_lk); 1537 ddi_taskq_destroy(pdp->xd_hp_taskq); 1538 mutex_enter(&pdp->xd_ndi_lk); 1539 pdp->xd_hp_taskq = NULL; 1540 } 1541 1542 /* Clean up. */ 1543 if (pdp->xd_hp_watch.node != NULL) { 1544 kmem_free((void *)pdp->xd_hp_watch.node, 1545 strlen(pdp->xd_hp_watch.node) + 1); 1546 pdp->xd_hp_watch.node = NULL; 1547 } 1548 } 1549 1550 static int 1551 i_xvdi_add_watches(dev_info_t *dip) 1552 { 1553 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1554 1555 ASSERT(pdp != NULL); 1556 1557 mutex_enter(&pdp->xd_ndi_lk); 1558 1559 if (i_xvdi_add_watch_oestate(dip) != DDI_SUCCESS) { 1560 mutex_exit(&pdp->xd_ndi_lk); 1561 return (DDI_FAILURE); 1562 } 1563 1564 if (pdp->xd_xsdev.frontend == 1) { 1565 /* 1566 * Frontend devices must watch for the backend path 1567 * changing. 1568 */ 1569 if (i_xvdi_add_watch_bepath(dip) != DDI_SUCCESS) 1570 goto unwatch_and_fail; 1571 } else { 1572 /* 1573 * Backend devices must watch for hotplug events. 1574 */ 1575 if (i_xvdi_add_watch_hpstate(dip) != DDI_SUCCESS) 1576 goto unwatch_and_fail; 1577 } 1578 1579 mutex_exit(&pdp->xd_ndi_lk); 1580 1581 return (DDI_SUCCESS); 1582 1583 unwatch_and_fail: 1584 i_xvdi_rem_watch_oestate(dip); 1585 mutex_exit(&pdp->xd_ndi_lk); 1586 1587 return (DDI_FAILURE); 1588 } 1589 1590 static void 1591 i_xvdi_rem_watches(dev_info_t *dip) 1592 { 1593 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1594 1595 ASSERT(pdp != NULL); 1596 1597 mutex_enter(&pdp->xd_ndi_lk); 1598 1599 i_xvdi_rem_watch_oestate(dip); 1600 1601 if (pdp->xd_xsdev.frontend == 1) 1602 i_xvdi_rem_watch_bepath(dip); 1603 else 1604 i_xvdi_rem_watch_hpstate(dip); 1605 1606 mutex_exit(&pdp->xd_ndi_lk); 1607 1608 xvdi_remove_xb_watch_handlers(dip); 1609 } 1610 1611 static int 1612 i_xvdi_add_watch_bepath(dev_info_t *dip) 1613 { 1614 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1615 1616 ASSERT(pdp != NULL); 1617 ASSERT(pdp->xd_xsdev.frontend == 1); 1618 1619 /* 1620 * Frontend devices need to watch for the backend path changing. 1621 */ 1622 if (pdp->xd_bepath_watch.node == NULL) { 1623 size_t len; 1624 char *path; 1625 1626 ASSERT(pdp->xd_xsdev.nodename != NULL); 1627 1628 len = strlen(pdp->xd_xsdev.nodename) + strlen("/backend") + 1; 1629 path = kmem_alloc(len, KM_SLEEP); 1630 (void) snprintf(path, len, "%s/backend", 1631 pdp->xd_xsdev.nodename); 1632 1633 pdp->xd_bepath_watch.node = path; 1634 pdp->xd_bepath_watch.callback = i_xvdi_bepath_cb; 1635 pdp->xd_bepath_watch.dev = (struct xenbus_device *)dip; 1636 if (register_xenbus_watch(&pdp->xd_bepath_watch) != 0) { 1637 kmem_free(path, len); 1638 pdp->xd_bepath_watch.node = NULL; 1639 return (DDI_FAILURE); 1640 } 1641 } 1642 1643 return (DDI_SUCCESS); 1644 } 1645 1646 static void 1647 i_xvdi_rem_watch_bepath(dev_info_t *dip) 1648 { 1649 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1650 1651 ASSERT(pdp != NULL); 1652 ASSERT(pdp->xd_xsdev.frontend == 1); 1653 ASSERT(mutex_owned(&pdp->xd_ndi_lk)); 1654 1655 if (pdp->xd_bepath_watch.node != NULL) { 1656 mutex_exit(&pdp->xd_ndi_lk); 1657 unregister_xenbus_watch(&pdp->xd_bepath_watch); 1658 mutex_enter(&pdp->xd_ndi_lk); 1659 1660 kmem_free((void *)(pdp->xd_bepath_watch.node), 1661 strlen(pdp->xd_bepath_watch.node) + 1); 1662 pdp->xd_bepath_watch.node = NULL; 1663 } 1664 } 1665 1666 int 1667 xvdi_switch_state(dev_info_t *dip, xenbus_transaction_t xbt, 1668 XenbusState newState) 1669 { 1670 int rv; 1671 struct xendev_ppd *pdp; 1672 1673 pdp = ddi_get_parent_data(dip); 1674 ASSERT(pdp != NULL); 1675 1676 XVDI_DPRINTF(XVDI_DBG_STATE, 1677 "xvdi_switch_state: %s@%s's xenbus state moves to %d\n", 1678 ddi_binding_name(dip) == NULL ? "null" : ddi_binding_name(dip), 1679 ddi_get_name_addr(dip) == NULL ? "null" : ddi_get_name_addr(dip), 1680 newState); 1681 1682 rv = xenbus_switch_state(&pdp->xd_xsdev, xbt, newState); 1683 if (rv > 0) 1684 cmn_err(CE_WARN, "xvdi_switch_state: change state failed"); 1685 1686 return (rv); 1687 } 1688 1689 /* 1690 * Notify hotplug script running in userland 1691 */ 1692 int 1693 xvdi_post_event(dev_info_t *dip, xendev_hotplug_cmd_t hpc) 1694 { 1695 struct xendev_ppd *pdp; 1696 nvlist_t *attr_list = NULL; 1697 i_xd_cfg_t *xdcp; 1698 sysevent_id_t eid; 1699 int err; 1700 char devname[256]; /* XXPV dme: ? */ 1701 1702 pdp = ddi_get_parent_data(dip); 1703 ASSERT(pdp != NULL); 1704 1705 xdcp = i_xvdi_devclass2cfg(pdp->xd_devclass); 1706 ASSERT(xdcp != NULL); 1707 1708 (void) snprintf(devname, sizeof (devname) - 1, "%s%d", 1709 ddi_driver_name(dip), ddi_get_instance(dip)); 1710 1711 err = nvlist_alloc(&attr_list, NV_UNIQUE_NAME, KM_NOSLEEP); 1712 if (err != DDI_SUCCESS) 1713 goto failure; 1714 1715 err = nvlist_add_int32(attr_list, "domain", pdp->xd_domain); 1716 if (err != DDI_SUCCESS) 1717 goto failure; 1718 err = nvlist_add_int32(attr_list, "vdev", pdp->xd_vdevnum); 1719 if (err != DDI_SUCCESS) 1720 goto failure; 1721 err = nvlist_add_string(attr_list, "devclass", xdcp->xsdev); 1722 if (err != DDI_SUCCESS) 1723 goto failure; 1724 err = nvlist_add_string(attr_list, "device", devname); 1725 if (err != DDI_SUCCESS) 1726 goto failure; 1727 err = nvlist_add_string(attr_list, "fob", 1728 ((pdp->xd_xsdev.frontend == 1) ? "frontend" : "backend")); 1729 if (err != DDI_SUCCESS) 1730 goto failure; 1731 1732 switch (hpc) { 1733 case XEN_HP_ADD: 1734 err = ddi_log_sysevent(dip, DDI_VENDOR_SUNW, "EC_xendev", 1735 "add", attr_list, &eid, DDI_NOSLEEP); 1736 break; 1737 case XEN_HP_REMOVE: 1738 err = ddi_log_sysevent(dip, DDI_VENDOR_SUNW, "EC_xendev", 1739 "remove", attr_list, &eid, DDI_NOSLEEP); 1740 break; 1741 default: 1742 err = DDI_FAILURE; 1743 goto failure; 1744 } 1745 1746 failure: 1747 if (attr_list != NULL) 1748 nvlist_free(attr_list); 1749 1750 return (err); 1751 } 1752 1753 /* ARGSUSED */ 1754 static void 1755 i_xvdi_probe_path_cb(struct xenbus_watch *w, const char **vec, 1756 unsigned int len) 1757 { 1758 char *path; 1759 1760 if (xendev_dip == NULL) 1761 xendev_dip = ddi_find_devinfo("xpvd", -1, 0); 1762 1763 path = i_ddi_strdup((char *)vec[XS_WATCH_PATH], KM_SLEEP); 1764 1765 (void) ddi_taskq_dispatch(DEVI(xendev_dip)->devi_taskq, 1766 i_xvdi_probe_path_handler, (void *)path, DDI_SLEEP); 1767 } 1768 1769 static void 1770 i_xvdi_watch_device(char *path) 1771 { 1772 struct xenbus_watch *w; 1773 1774 ASSERT(path != NULL); 1775 1776 w = kmem_zalloc(sizeof (*w), KM_SLEEP); 1777 w->node = path; 1778 w->callback = &i_xvdi_probe_path_cb; 1779 w->dev = NULL; 1780 1781 if (register_xenbus_watch(w) != 0) { 1782 cmn_err(CE_WARN, "i_xvdi_watch_device: " 1783 "cannot set watch on %s", path); 1784 kmem_free(w, sizeof (*w)); 1785 return; 1786 } 1787 } 1788 1789 void 1790 xvdi_watch_devices(int newstate) 1791 { 1792 int devclass; 1793 1794 /* 1795 * Watch for devices being created in the store. 1796 */ 1797 if (newstate == XENSTORE_DOWN) 1798 return; 1799 for (devclass = 0; devclass < NXDC; devclass++) { 1800 if (xdci[devclass].xs_path_fe != NULL) 1801 i_xvdi_watch_device(xdci[devclass].xs_path_fe); 1802 if (xdci[devclass].xs_path_be != NULL) 1803 i_xvdi_watch_device(xdci[devclass].xs_path_be); 1804 } 1805 } 1806 1807 /* 1808 * Iterate over the store looking for backend devices to create. 1809 */ 1810 static void 1811 i_xvdi_enum_be(dev_info_t *parent, i_xd_cfg_t *xdcp) 1812 { 1813 char **domains; 1814 unsigned int ndomains; 1815 int ldomains, i; 1816 1817 if ((domains = xenbus_directory(XBT_NULL, xdcp->xs_path_be, "", 1818 &ndomains)) == NULL) 1819 return; 1820 1821 for (i = 0, ldomains = 0; i < ndomains; i++) { 1822 ldomains += strlen(domains[i]) + 1 + sizeof (char *); 1823 1824 i_xvdi_enum_worker(parent, xdcp, domains[i]); 1825 } 1826 kmem_free(domains, ldomains); 1827 } 1828 1829 /* 1830 * Iterate over the store looking for frontend devices to create. 1831 */ 1832 static void 1833 i_xvdi_enum_fe(dev_info_t *parent, i_xd_cfg_t *xdcp) 1834 { 1835 i_xvdi_enum_worker(parent, xdcp, NULL); 1836 } 1837 1838 static void 1839 i_xvdi_enum_worker(dev_info_t *parent, i_xd_cfg_t *xdcp, 1840 char *domain) 1841 { 1842 char *path, *domain_path, *ep; 1843 char **devices; 1844 unsigned int ndevices; 1845 int ldevices, j, circ; 1846 domid_t dom; 1847 long tmplong; 1848 1849 if (domain == NULL) { 1850 dom = DOMID_SELF; 1851 path = xdcp->xs_path_fe; 1852 domain_path = ""; 1853 } else { 1854 (void) ddi_strtol(domain, &ep, 0, &tmplong); 1855 dom = tmplong; 1856 path = xdcp->xs_path_be; 1857 domain_path = domain; 1858 } 1859 1860 if ((devices = xenbus_directory(XBT_NULL, path, domain_path, 1861 &ndevices)) == NULL) 1862 return; 1863 1864 for (j = 0, ldevices = 0; j < ndevices; j++) { 1865 int vdev; 1866 1867 ldevices += strlen(devices[j]) + 1 + sizeof (char *); 1868 (void) ddi_strtol(devices[j], &ep, 0, &tmplong); 1869 vdev = tmplong; 1870 1871 ndi_devi_enter(parent, &circ); 1872 1873 if (xvdi_find_dev(parent, xdcp->devclass, dom, vdev) == NULL) 1874 (void) xvdi_create_dev(parent, xdcp->devclass, 1875 dom, vdev); 1876 1877 ndi_devi_exit(parent, circ); 1878 } 1879 kmem_free(devices, ldevices); 1880 } 1881 1882 /* 1883 * Leaf drivers should call this in their detach() routine during suspend. 1884 */ 1885 void 1886 xvdi_suspend(dev_info_t *dip) 1887 { 1888 i_xvdi_rem_watches(dip); 1889 } 1890 1891 /* 1892 * Leaf drivers should call this in their attach() routine during resume. 1893 */ 1894 int 1895 xvdi_resume(dev_info_t *dip) 1896 { 1897 return (i_xvdi_add_watches(dip)); 1898 } 1899 1900 /* 1901 * Add event handler for the leaf driver 1902 * to handle event triggered by the change in xenstore 1903 */ 1904 int 1905 xvdi_add_event_handler(dev_info_t *dip, char *name, 1906 void (*evthandler)(dev_info_t *, ddi_eventcookie_t, void *, void *), 1907 void *arg) 1908 { 1909 ddi_eventcookie_t ecv; 1910 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 1911 ddi_callback_id_t *cbid; 1912 boolean_t call_handler; 1913 i_oestate_evt_t *evt = NULL; 1914 XenbusState oestate; 1915 1916 ASSERT(pdp != NULL); 1917 1918 mutex_enter(&pdp->xd_ndi_lk); 1919 1920 if (strcmp(name, XS_OE_STATE) == 0) { 1921 ASSERT(pdp->xd_xsdev.otherend != NULL); 1922 1923 cbid = &pdp->xd_oe_ehid; 1924 } else if (strcmp(name, XS_HP_STATE) == 0) { 1925 if (pdp->xd_xsdev.frontend == 1) { 1926 mutex_exit(&pdp->xd_ndi_lk); 1927 return (DDI_FAILURE); 1928 } 1929 1930 ASSERT(pdp->xd_hp_watch.node != NULL); 1931 1932 cbid = &pdp->xd_hp_ehid; 1933 } else { 1934 /* Unsupported watch. */ 1935 mutex_exit(&pdp->xd_ndi_lk); 1936 return (DDI_FAILURE); 1937 } 1938 1939 /* 1940 * No event handler provided, take default action to handle 1941 * event. 1942 */ 1943 if (evthandler == NULL) { 1944 mutex_exit(&pdp->xd_ndi_lk); 1945 return (DDI_SUCCESS); 1946 } 1947 1948 ASSERT(*cbid == NULL); 1949 1950 if (ddi_get_eventcookie(dip, name, &ecv) != DDI_SUCCESS) { 1951 cmn_err(CE_WARN, "failed to find %s cookie for %s@%s", 1952 name, ddi_get_name(dip), ddi_get_name_addr(dip)); 1953 mutex_exit(&pdp->xd_ndi_lk); 1954 return (DDI_FAILURE); 1955 } 1956 if (ddi_add_event_handler(dip, ecv, evthandler, arg, cbid) 1957 != DDI_SUCCESS) { 1958 cmn_err(CE_WARN, "failed to add %s event handler for %s@%s", 1959 name, ddi_get_name(dip), ddi_get_name_addr(dip)); 1960 *cbid = NULL; 1961 mutex_exit(&pdp->xd_ndi_lk); 1962 return (DDI_FAILURE); 1963 } 1964 1965 /* 1966 * if we're adding an oe state callback, and the ring has already 1967 * transitioned out of Unknown, call the handler after we release 1968 * the mutex. 1969 */ 1970 call_handler = B_FALSE; 1971 if ((strcmp(name, XS_OE_STATE) == 0) && 1972 (pdp->xd_xsdev.otherend_state != XenbusStateUnknown)) { 1973 oestate = pdp->xd_xsdev.otherend_state; 1974 call_handler = B_TRUE; 1975 } 1976 1977 mutex_exit(&pdp->xd_ndi_lk); 1978 1979 if (call_handler) { 1980 evt = kmem_alloc(sizeof (i_oestate_evt_t), KM_SLEEP); 1981 evt->dip = dip; 1982 evt->state = oestate; 1983 (void) ddi_taskq_dispatch(pdp->xd_oe_taskq, 1984 i_xvdi_oestate_handler, (void *)evt, DDI_SLEEP); 1985 } 1986 1987 return (DDI_SUCCESS); 1988 } 1989 1990 /* 1991 * Remove event handler for the leaf driver and unwatch xenstore 1992 * so, driver will not be notified when xenstore entry changed later 1993 */ 1994 void 1995 xvdi_remove_event_handler(dev_info_t *dip, char *name) 1996 { 1997 struct xendev_ppd *pdp; 1998 boolean_t rem_oe = B_FALSE, rem_hp = B_FALSE; 1999 ddi_callback_id_t oeid = NULL, hpid = NULL; 2000 2001 pdp = ddi_get_parent_data(dip); 2002 ASSERT(pdp != NULL); 2003 2004 if (name == NULL) { 2005 rem_oe = B_TRUE; 2006 rem_hp = B_TRUE; 2007 } else if (strcmp(name, XS_OE_STATE) == 0) { 2008 rem_oe = B_TRUE; 2009 } else if (strcmp(name, XS_HP_STATE) == 0) { 2010 rem_hp = B_TRUE; 2011 } else { 2012 cmn_err(CE_WARN, "event %s not supported, cannot remove", name); 2013 return; 2014 } 2015 2016 mutex_enter(&pdp->xd_ndi_lk); 2017 2018 if (rem_oe && (pdp->xd_oe_ehid != NULL)) { 2019 oeid = pdp->xd_oe_ehid; 2020 pdp->xd_oe_ehid = NULL; 2021 } 2022 2023 if (rem_hp && (pdp->xd_hp_ehid != NULL)) { 2024 hpid = pdp->xd_hp_ehid; 2025 pdp->xd_hp_ehid = NULL; 2026 } 2027 2028 mutex_exit(&pdp->xd_ndi_lk); 2029 2030 if (oeid != NULL) 2031 (void) ddi_remove_event_handler(oeid); 2032 if (hpid != NULL) 2033 (void) ddi_remove_event_handler(hpid); 2034 } 2035 2036 2037 /* 2038 * common ring interfaces 2039 */ 2040 2041 #define FRONT_RING(_ringp) (&(_ringp)->xr_sring.fr) 2042 #define BACK_RING(_ringp) (&(_ringp)->xr_sring.br) 2043 #define GET_RING_SIZE(_ringp) RING_SIZE(FRONT_RING(ringp)) 2044 #define GET_RING_ENTRY_FE(_ringp, _idx) \ 2045 (FRONT_RING(_ringp)->sring->ring + \ 2046 (_ringp)->xr_entry_size * ((_idx) & (GET_RING_SIZE(_ringp) - 1))) 2047 #define GET_RING_ENTRY_BE(_ringp, _idx) \ 2048 (BACK_RING(_ringp)->sring->ring + \ 2049 (_ringp)->xr_entry_size * ((_idx) & (GET_RING_SIZE(_ringp) - 1))) 2050 2051 unsigned int 2052 xvdi_ring_avail_slots(xendev_ring_t *ringp) 2053 { 2054 comif_ring_fe_t *frp; 2055 comif_ring_be_t *brp; 2056 2057 if (ringp->xr_frontend) { 2058 frp = FRONT_RING(ringp); 2059 return (GET_RING_SIZE(ringp) - 2060 (frp->req_prod_pvt - frp->rsp_cons)); 2061 } else { 2062 brp = BACK_RING(ringp); 2063 return (GET_RING_SIZE(ringp) - 2064 (brp->rsp_prod_pvt - brp->req_cons)); 2065 } 2066 } 2067 2068 int 2069 xvdi_ring_has_unconsumed_requests(xendev_ring_t *ringp) 2070 { 2071 comif_ring_be_t *brp; 2072 2073 ASSERT(!ringp->xr_frontend); 2074 brp = BACK_RING(ringp); 2075 return ((brp->req_cons != 2076 ddi_get32(ringp->xr_acc_hdl, &brp->sring->req_prod)) && 2077 ((brp->req_cons - brp->rsp_prod_pvt) != RING_SIZE(brp))); 2078 } 2079 2080 int 2081 xvdi_ring_has_incomp_request(xendev_ring_t *ringp) 2082 { 2083 comif_ring_fe_t *frp; 2084 2085 ASSERT(ringp->xr_frontend); 2086 frp = FRONT_RING(ringp); 2087 return (frp->req_prod_pvt != 2088 ddi_get32(ringp->xr_acc_hdl, &frp->sring->rsp_prod)); 2089 } 2090 2091 int 2092 xvdi_ring_has_unconsumed_responses(xendev_ring_t *ringp) 2093 { 2094 comif_ring_fe_t *frp; 2095 2096 ASSERT(ringp->xr_frontend); 2097 frp = FRONT_RING(ringp); 2098 return (frp->rsp_cons != 2099 ddi_get32(ringp->xr_acc_hdl, &frp->sring->rsp_prod)); 2100 } 2101 2102 /* NOTE: req_event will be increased as needed */ 2103 void * 2104 xvdi_ring_get_request(xendev_ring_t *ringp) 2105 { 2106 comif_ring_fe_t *frp; 2107 comif_ring_be_t *brp; 2108 2109 if (ringp->xr_frontend) { 2110 /* for frontend ring */ 2111 frp = FRONT_RING(ringp); 2112 if (!RING_FULL(frp)) 2113 return (GET_RING_ENTRY_FE(ringp, frp->req_prod_pvt++)); 2114 else 2115 return (NULL); 2116 } else { 2117 /* for backend ring */ 2118 brp = BACK_RING(ringp); 2119 /* RING_FINAL_CHECK_FOR_REQUESTS() */ 2120 if (xvdi_ring_has_unconsumed_requests(ringp)) 2121 return (GET_RING_ENTRY_BE(ringp, brp->req_cons++)); 2122 else { 2123 ddi_put32(ringp->xr_acc_hdl, &brp->sring->req_event, 2124 brp->req_cons + 1); 2125 membar_enter(); 2126 if (xvdi_ring_has_unconsumed_requests(ringp)) 2127 return (GET_RING_ENTRY_BE(ringp, 2128 brp->req_cons++)); 2129 else 2130 return (NULL); 2131 } 2132 } 2133 } 2134 2135 int 2136 xvdi_ring_push_request(xendev_ring_t *ringp) 2137 { 2138 RING_IDX old, new, reqevt; 2139 comif_ring_fe_t *frp; 2140 2141 /* only frontend should be able to push request */ 2142 ASSERT(ringp->xr_frontend); 2143 2144 /* RING_PUSH_REQUEST_AND_CHECK_NOTIFY() */ 2145 frp = FRONT_RING(ringp); 2146 old = ddi_get32(ringp->xr_acc_hdl, &frp->sring->req_prod); 2147 new = frp->req_prod_pvt; 2148 ddi_put32(ringp->xr_acc_hdl, &frp->sring->req_prod, new); 2149 membar_enter(); 2150 reqevt = ddi_get32(ringp->xr_acc_hdl, &frp->sring->req_event); 2151 return ((RING_IDX)(new - reqevt) < (RING_IDX)(new - old)); 2152 } 2153 2154 /* NOTE: rsp_event will be increased as needed */ 2155 void * 2156 xvdi_ring_get_response(xendev_ring_t *ringp) 2157 { 2158 comif_ring_fe_t *frp; 2159 comif_ring_be_t *brp; 2160 2161 if (!ringp->xr_frontend) { 2162 /* for backend ring */ 2163 brp = BACK_RING(ringp); 2164 return (GET_RING_ENTRY_BE(ringp, brp->rsp_prod_pvt++)); 2165 } else { 2166 /* for frontend ring */ 2167 frp = FRONT_RING(ringp); 2168 /* RING_FINAL_CHECK_FOR_RESPONSES() */ 2169 if (xvdi_ring_has_unconsumed_responses(ringp)) 2170 return (GET_RING_ENTRY_FE(ringp, frp->rsp_cons++)); 2171 else { 2172 ddi_put32(ringp->xr_acc_hdl, &frp->sring->rsp_event, 2173 frp->rsp_cons + 1); 2174 membar_enter(); 2175 if (xvdi_ring_has_unconsumed_responses(ringp)) 2176 return (GET_RING_ENTRY_FE(ringp, 2177 frp->rsp_cons++)); 2178 else 2179 return (NULL); 2180 } 2181 } 2182 } 2183 2184 int 2185 xvdi_ring_push_response(xendev_ring_t *ringp) 2186 { 2187 RING_IDX old, new, rspevt; 2188 comif_ring_be_t *brp; 2189 2190 /* only backend should be able to push response */ 2191 ASSERT(!ringp->xr_frontend); 2192 2193 /* RING_PUSH_RESPONSE_AND_CHECK_NOTIFY() */ 2194 brp = BACK_RING(ringp); 2195 old = ddi_get32(ringp->xr_acc_hdl, &brp->sring->rsp_prod); 2196 new = brp->rsp_prod_pvt; 2197 ddi_put32(ringp->xr_acc_hdl, &brp->sring->rsp_prod, new); 2198 membar_enter(); 2199 rspevt = ddi_get32(ringp->xr_acc_hdl, &brp->sring->rsp_event); 2200 return ((RING_IDX)(new - rspevt) < (RING_IDX)(new - old)); 2201 } 2202 2203 static void 2204 xvdi_ring_init_sring(xendev_ring_t *ringp) 2205 { 2206 ddi_acc_handle_t acchdl; 2207 comif_sring_t *xsrp; 2208 int i; 2209 2210 xsrp = (comif_sring_t *)ringp->xr_vaddr; 2211 acchdl = ringp->xr_acc_hdl; 2212 2213 /* shared ring initialization */ 2214 ddi_put32(acchdl, &xsrp->req_prod, 0); 2215 ddi_put32(acchdl, &xsrp->rsp_prod, 0); 2216 ddi_put32(acchdl, &xsrp->req_event, 1); 2217 ddi_put32(acchdl, &xsrp->rsp_event, 1); 2218 for (i = 0; i < sizeof (xsrp->pad); i++) 2219 ddi_put8(acchdl, xsrp->pad + i, 0); 2220 } 2221 2222 static void 2223 xvdi_ring_init_front_ring(xendev_ring_t *ringp, size_t nentry, size_t entrysize) 2224 { 2225 comif_ring_fe_t *xfrp; 2226 2227 xfrp = &ringp->xr_sring.fr; 2228 xfrp->req_prod_pvt = 0; 2229 xfrp->rsp_cons = 0; 2230 xfrp->nr_ents = nentry; 2231 xfrp->sring = (comif_sring_t *)ringp->xr_vaddr; 2232 2233 ringp->xr_frontend = 1; 2234 ringp->xr_entry_size = entrysize; 2235 } 2236 2237 #ifndef XPV_HVM_DRIVER 2238 static void 2239 xvdi_ring_init_back_ring(xendev_ring_t *ringp, size_t nentry, size_t entrysize) 2240 { 2241 comif_ring_be_t *xbrp; 2242 2243 xbrp = &ringp->xr_sring.br; 2244 xbrp->rsp_prod_pvt = 0; 2245 xbrp->req_cons = 0; 2246 xbrp->nr_ents = nentry; 2247 xbrp->sring = (comif_sring_t *)ringp->xr_vaddr; 2248 2249 ringp->xr_frontend = 0; 2250 ringp->xr_entry_size = entrysize; 2251 } 2252 #endif /* XPV_HVM_DRIVER */ 2253 2254 static void 2255 xendev_offline_device(void *arg) 2256 { 2257 dev_info_t *dip = (dev_info_t *)arg; 2258 char devname[MAXNAMELEN] = {0}; 2259 2260 /* 2261 * This is currently the only chance to delete a devinfo node, which 2262 * is _not_ always successful. 2263 */ 2264 (void) ddi_deviname(dip, devname); 2265 (void) devfs_clean(ddi_get_parent(dip), devname + 1, DV_CLEAN_FORCE); 2266 (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE); 2267 } 2268 2269 static void 2270 i_xvdi_oestate_cb(struct xenbus_device *dev, XenbusState oestate) 2271 { 2272 dev_info_t *dip = (dev_info_t *)dev->data; 2273 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 2274 i_oestate_evt_t *evt = NULL; 2275 boolean_t call_handler; 2276 2277 XVDI_DPRINTF(XVDI_DBG_STATE, 2278 "i_xvdi_oestate_cb: %s@%s sees oestate change to %d\n", 2279 ddi_binding_name(dip) == NULL ? "null" : ddi_binding_name(dip), 2280 ddi_get_name_addr(dip) == NULL ? "null" : ddi_get_name_addr(dip), 2281 oestate); 2282 2283 /* only call the handler if our state has changed */ 2284 call_handler = B_FALSE; 2285 mutex_enter(&pdp->xd_ndi_lk); 2286 if (dev->otherend_state != oestate) { 2287 dev->otherend_state = oestate; 2288 call_handler = B_TRUE; 2289 } 2290 mutex_exit(&pdp->xd_ndi_lk); 2291 2292 if (call_handler) { 2293 /* 2294 * Try to deliver the oestate change event to the dip 2295 */ 2296 evt = kmem_alloc(sizeof (i_oestate_evt_t), KM_SLEEP); 2297 evt->dip = dip; 2298 evt->state = oestate; 2299 (void) ddi_taskq_dispatch(pdp->xd_oe_taskq, 2300 i_xvdi_oestate_handler, (void *)evt, DDI_SLEEP); 2301 } 2302 } 2303 2304 /*ARGSUSED*/ 2305 static void 2306 i_xvdi_hpstate_cb(struct xenbus_watch *w, const char **vec, 2307 unsigned int len) 2308 { 2309 dev_info_t *dip = (dev_info_t *)w->dev; 2310 struct xendev_ppd *pdp = ddi_get_parent_data(dip); 2311 2312 #ifdef DEBUG 2313 char *hp_status = NULL; 2314 unsigned int hpl = 0; 2315 2316 (void) xenbus_read(XBT_NULL, pdp->xd_hp_watch.node, "", 2317 (void *)&hp_status, &hpl); 2318 XVDI_DPRINTF(XVDI_DBG_STATE, 2319 "i_xvdi_hpstate_cb: %s@%s sees hpstate change to %s\n", 2320 ddi_binding_name(dip) == NULL ? "null" : ddi_binding_name(dip), 2321 ddi_get_name_addr(dip) == NULL ? "null" : ddi_get_name_addr(dip), 2322 hp_status == NULL ? "null" : hp_status); 2323 if (hp_status != NULL) 2324 kmem_free(hp_status, hpl); 2325 #endif /* DEBUG */ 2326 2327 (void) ddi_taskq_dispatch(pdp->xd_hp_taskq, 2328 i_xvdi_hpstate_handler, (void *)dip, DDI_SLEEP); 2329 } 2330 2331 static void 2332 i_xvdi_probe_path_handler(void *arg) 2333 { 2334 dev_info_t *parent; 2335 char *path = arg, *p = NULL; 2336 int i, vdev, circ; 2337 i_xd_cfg_t *xdcp; 2338 boolean_t frontend; 2339 domid_t dom; 2340 2341 for (i = 0, xdcp = &xdci[0]; i < NXDC; i++, xdcp++) { 2342 2343 if ((xdcp->xs_path_fe != NULL) && 2344 (strncmp(path, xdcp->xs_path_fe, strlen(xdcp->xs_path_fe)) 2345 == 0)) { 2346 2347 frontend = B_TRUE; 2348 p = path + strlen(xdcp->xs_path_fe); 2349 break; 2350 } 2351 2352 if ((xdcp->xs_path_be != NULL) && 2353 (strncmp(path, xdcp->xs_path_be, strlen(xdcp->xs_path_be)) 2354 == 0)) { 2355 2356 frontend = B_FALSE; 2357 p = path + strlen(xdcp->xs_path_be); 2358 break; 2359 } 2360 2361 } 2362 2363 if (p == NULL) { 2364 cmn_err(CE_WARN, "i_xvdi_probe_path_handler: " 2365 "unexpected path prefix in %s", path); 2366 goto done; 2367 } 2368 2369 if (frontend) { 2370 dom = DOMID_SELF; 2371 if (sscanf(p, "/%d/", &vdev) != 1) { 2372 XVDI_DPRINTF(XVDI_DBG_PROBE, 2373 "i_xvdi_probe_path_handler: " 2374 "cannot parse frontend path %s", 2375 path); 2376 goto done; 2377 } 2378 } else { 2379 if (sscanf(p, "/%hu/%d/", &dom, &vdev) != 2) { 2380 XVDI_DPRINTF(XVDI_DBG_PROBE, 2381 "i_xvdi_probe_path_handler: " 2382 "cannot parse backend path %s", 2383 path); 2384 goto done; 2385 } 2386 } 2387 2388 /* 2389 * This is an oxymoron, so indicates a bogus configuration we 2390 * must check for. 2391 */ 2392 if (vdev == VDEV_NOXS) { 2393 cmn_err(CE_WARN, "i_xvdi_probe_path_handler: " 2394 "invalid path %s", path); 2395 goto done; 2396 } 2397 2398 parent = xendev_dip; 2399 ASSERT(parent != NULL); 2400 2401 ndi_devi_enter(parent, &circ); 2402 2403 if (xvdi_find_dev(parent, xdcp->devclass, dom, vdev) == NULL) { 2404 XVDI_DPRINTF(XVDI_DBG_PROBE, 2405 "i_xvdi_probe_path_handler: create for %s", path); 2406 (void) xvdi_create_dev(parent, xdcp->devclass, dom, vdev); 2407 } else { 2408 XVDI_DPRINTF(XVDI_DBG_PROBE, 2409 "i_xvdi_probe_path_handler: %s already exists", path); 2410 } 2411 2412 ndi_devi_exit(parent, circ); 2413 2414 done: 2415 kmem_free(path, strlen(path) + 1); 2416 } 2417