Lines Matching refs:xbb
175 static void xbb_attach_failed(struct xbb_softc *xbb, int err, const char *fmt,
177 static int xbb_shutdown(struct xbb_softc *xbb);
193 struct xbb_softc *xbb; member
540 typedef int (*xbb_dispatch_t)(struct xbb_softc *xbb,
823 xbb_get_req(struct xbb_softc *xbb) in xbb_get_req() argument
829 mtx_assert(&xbb->lock, MA_OWNED); in xbb_get_req()
831 if ((req = STAILQ_FIRST(&xbb->request_free_stailq)) != NULL) { in xbb_get_req()
832 STAILQ_REMOVE_HEAD(&xbb->request_free_stailq, links); in xbb_get_req()
833 xbb->active_request_count++; in xbb_get_req()
846 xbb_release_req(struct xbb_softc *xbb, struct xbb_xen_req *req) in xbb_release_req() argument
848 mtx_assert(&xbb->lock, MA_OWNED); in xbb_release_req()
850 STAILQ_INSERT_HEAD(&xbb->request_free_stailq, req, links); in xbb_release_req()
851 xbb->active_request_count--; in xbb_release_req()
853 KASSERT(xbb->active_request_count >= 0, in xbb_release_req()
865 xbb_release_reqs(struct xbb_softc *xbb, struct xbb_xen_req_list *req_list, in xbb_release_reqs() argument
868 mtx_assert(&xbb->lock, MA_OWNED); in xbb_release_reqs()
870 STAILQ_CONCAT(&xbb->request_free_stailq, req_list); in xbb_release_reqs()
871 xbb->active_request_count -= nreqs; in xbb_release_reqs()
873 KASSERT(xbb->active_request_count >= 0, in xbb_release_reqs()
959 struct xbb_softc *xbb; in xbb_get_gntaddr() local
961 xbb = reqlist->xbb; in xbb_get_gntaddr()
963 return ((uintptr_t)(xbb->gnt_base_addr + in xbb_get_gntaddr()
964 (uintptr_t)(reqlist->kva - xbb->kva) + in xbb_get_gntaddr()
984 xbb_get_kva(struct xbb_softc *xbb, int nr_pages) in xbb_get_kva() argument
996 mtx_lock(&xbb->lock); in xbb_get_kva()
1001 bit_ffc(xbb->kva_free, xbb->reqlist_kva_pages, &first_clear); in xbb_get_kva()
1010 for (i = first_clear, num_clear = 0; i < xbb->reqlist_kva_pages; i++) { in xbb_get_kva()
1017 if (bit_test(xbb->kva_free, i)) { in xbb_get_kva()
1031 bit_nset(xbb->kva_free, first_clear, in xbb_get_kva()
1034 free_kva = xbb->kva + in xbb_get_kva()
1037 KASSERT(free_kva >= (uint8_t *)xbb->kva && in xbb_get_kva()
1039 (uint8_t *)xbb->ring_config.va, in xbb_get_kva()
1042 nr_pages * PAGE_SIZE, (uintmax_t)xbb->kva, in xbb_get_kva()
1043 (uintmax_t)xbb->ring_config.va)); in xbb_get_kva()
1051 xbb->flags |= XBBF_RESOURCE_SHORTAGE; in xbb_get_kva()
1052 xbb->kva_shortages++; in xbb_get_kva()
1055 mtx_unlock(&xbb->lock); in xbb_get_kva()
1068 xbb_free_kva(struct xbb_softc *xbb, uint8_t *kva_ptr, int nr_pages) in xbb_free_kva() argument
1072 mtx_assert(&xbb->lock, MA_OWNED); in xbb_free_kva()
1074 start_page = (intptr_t)(kva_ptr - xbb->kva) >> PAGE_SHIFT; in xbb_free_kva()
1075 bit_nclear(xbb->kva_free, start_page, start_page + nr_pages - 1); in xbb_free_kva()
1118 xbb_get_reqlist(struct xbb_softc *xbb) in xbb_get_reqlist() argument
1124 mtx_assert(&xbb->lock, MA_OWNED); in xbb_get_reqlist()
1126 if ((reqlist = STAILQ_FIRST(&xbb->reqlist_free_stailq)) != NULL) { in xbb_get_reqlist()
1127 STAILQ_REMOVE_HEAD(&xbb->reqlist_free_stailq, links); in xbb_get_reqlist()
1149 xbb_release_reqlist(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, in xbb_release_reqlist() argument
1153 mtx_assert(&xbb->lock, MA_OWNED); in xbb_release_reqlist()
1156 wakeup = xbb->flags & XBBF_RESOURCE_SHORTAGE; in xbb_release_reqlist()
1157 xbb->flags &= ~XBBF_RESOURCE_SHORTAGE; in xbb_release_reqlist()
1161 xbb_free_kva(xbb, reqlist->kva, reqlist->nr_segments); in xbb_release_reqlist()
1163 xbb_release_reqs(xbb, &reqlist->contig_req_list, reqlist->num_children); in xbb_release_reqlist()
1165 STAILQ_INSERT_TAIL(&xbb->reqlist_free_stailq, reqlist, links); in xbb_release_reqlist()
1167 if ((xbb->flags & XBBF_SHUTDOWN) != 0) { in xbb_release_reqlist()
1174 xbb_shutdown(xbb); in xbb_release_reqlist()
1178 taskqueue_enqueue(xbb->io_taskqueue, &xbb->io_task); in xbb_release_reqlist()
1192 xbb_get_resources(struct xbb_softc *xbb, struct xbb_xen_reqlist **reqlist, in xbb_get_resources() argument
1201 mtx_lock(&xbb->lock); in xbb_get_resources()
1207 if ((xbb->flags & XBBF_SHUTDOWN) != 0) { in xbb_get_resources()
1208 mtx_unlock(&xbb->lock); in xbb_get_resources()
1216 nreqlist = xbb_get_reqlist(xbb); in xbb_get_resources()
1222 nreq = xbb_get_req(xbb); in xbb_get_resources()
1226 mtx_unlock(&xbb->lock); in xbb_get_resources()
1232 STAILQ_INSERT_TAIL(&xbb->reqlist_pending_stailq, nreqlist, in xbb_get_resources()
1241 if (xbb->abi != BLKIF_PROTOCOL_NATIVE) { in xbb_get_resources()
1249 devstat_start_transaction(xbb->xbb_stats_in, &nreq->ds_t0); in xbb_get_resources()
1263 xbb->flags |= XBBF_RESOURCE_SHORTAGE; in xbb_get_resources()
1264 xbb->request_shortages++; in xbb_get_resources()
1267 xbb_release_req(xbb, nreq); in xbb_get_resources()
1270 xbb_release_reqlist(xbb, nreqlist, /*wakeup*/ 0); in xbb_get_resources()
1272 mtx_unlock(&xbb->lock); in xbb_get_resources()
1286 xbb_queue_response(struct xbb_softc *xbb, struct xbb_xen_req *req, int status) in xbb_queue_response() argument
1301 mtx_assert(&xbb->lock, MA_OWNED); in xbb_queue_response()
1308 switch (xbb->abi) { in xbb_queue_response()
1310 resp = RING_GET_RESPONSE(&xbb->rings.native, in xbb_queue_response()
1311 xbb->rings.native.rsp_prod_pvt); in xbb_queue_response()
1315 RING_GET_RESPONSE(&xbb->rings.x86_32, in xbb_queue_response()
1316 xbb->rings.x86_32.rsp_prod_pvt); in xbb_queue_response()
1320 RING_GET_RESPONSE(&xbb->rings.x86_64, in xbb_queue_response()
1321 xbb->rings.x86_64.rsp_prod_pvt); in xbb_queue_response()
1332 xbb->reqs_completed_with_error++; in xbb_queue_response()
1334 xbb->rings.common.rsp_prod_pvt++; in xbb_queue_response()
1336 xbb->reqs_queued_for_completion++; in xbb_queue_response()
1351 xbb_push_responses(struct xbb_softc *xbb, int *run_taskqueue, int *notify) in xbb_push_responses() argument
1358 mtx_assert(&xbb->lock, MA_OWNED); in xbb_push_responses()
1362 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&xbb->rings.common, *notify); in xbb_push_responses()
1364 if (xbb->rings.common.rsp_prod_pvt == xbb->rings.common.req_cons) { in xbb_push_responses()
1370 RING_FINAL_CHECK_FOR_REQUESTS(&xbb->rings.common, more_to_do); in xbb_push_responses()
1371 } else if (RING_HAS_UNCONSUMED_REQUESTS(&xbb->rings.common)) { in xbb_push_responses()
1375 xbb->reqs_completed += xbb->reqs_queued_for_completion; in xbb_push_responses()
1376 xbb->reqs_queued_for_completion = 0; in xbb_push_responses()
1388 xbb_complete_reqlist(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist) in xbb_complete_reqlist() argument
1399 mtx_lock(&xbb->lock); in xbb_complete_reqlist()
1414 xbb_queue_response(xbb, nreq, reqlist->status); in xbb_complete_reqlist()
1424 devstat_end_transaction(xbb->xbb_stats_in, in xbb_complete_reqlist()
1441 devstat_end_transaction(xbb->xbb_stats, in xbb_complete_reqlist()
1448 xbb_release_reqlist(xbb, reqlist, /*wakeup*/ 1); in xbb_complete_reqlist()
1450 xbb_push_responses(xbb, &run_taskqueue, ¬ify); in xbb_complete_reqlist()
1452 mtx_unlock(&xbb->lock); in xbb_complete_reqlist()
1455 taskqueue_enqueue(xbb->io_taskqueue, &xbb->io_task); in xbb_complete_reqlist()
1458 xen_intr_signal(xbb->xen_intr_handle); in xbb_complete_reqlist()
1471 struct xbb_softc *xbb; in xbb_bio_done() local
1475 xbb = reqlist->xbb; in xbb_bio_done()
1497 bio->bio_error, xbb->dev_name); in xbb_bio_done()
1501 && xenbus_get_state(xbb->dev) == XenbusStateConnected) { in xbb_bio_done()
1507 xenbus_set_state(xbb->dev, XenbusStateClosing); in xbb_bio_done()
1527 xbb_complete_reqlist(xbb, reqlist); in xbb_bio_done()
1547 xbb_dispatch_io(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist) in xbb_dispatch_io() argument
1575 reqlist->kva = xbb_get_kva(xbb, reqlist->nr_segments); in xbb_dispatch_io()
1585 devstat_start_transaction(xbb->xbb_stats, &reqlist->ds_t0); in xbb_dispatch_io()
1595 if ((xbb->flags & XBBF_READ_ONLY) != 0) { in xbb_dispatch_io()
1597 xbb->dev_name); in xbb_dispatch_io()
1612 if (xbb->disable_flush != 0) { in xbb_dispatch_io()
1622 if (xbb->flush_interval != 0) { in xbb_dispatch_io()
1623 if (++(xbb->flush_count) < xbb->flush_interval) { in xbb_dispatch_io()
1626 xbb->flush_count = 0; in xbb_dispatch_io()
1641 reqlist->xbb = xbb; in xbb_dispatch_io()
1642 xbb_sg = xbb->xbb_sgs; in xbb_dispatch_io()
1643 map = xbb->maps; in xbb_dispatch_io()
1662 || __predict_false(nseg > xbb->max_request_segments)) { in xbb_dispatch_io()
1696 xbb->ring_config.gnt_addr, in xbb_dispatch_io()
1700 (uintmax_t)xbb->ring_config.gnt_addr)); in xbb_dispatch_io()
1704 map->dom = xbb->otherend_id; in xbb_dispatch_io()
1716 nr_sects = (nr_sects << 9) >> xbb->sector_size_shift; in xbb_dispatch_io()
1720 ((xbb->sector_size >> 9) - 1)) != 0) { in xbb_dispatch_io()
1721 device_printf(xbb->dev, "%s: I/O size (%d) is not " in xbb_dispatch_io()
1725 xbb->sector_size); in xbb_dispatch_io()
1732 xbb->maps, reqlist->nr_segments); in xbb_dispatch_io()
1738 for (seg_idx = 0, map = xbb->maps; seg_idx < reqlist->nr_segments; in xbb_dispatch_io()
1754 xbb->media_num_sectors) { in xbb_dispatch_io()
1760 xbb->dev_name); in xbb_dispatch_io()
1767 error = xbb->dispatch_io(xbb, in xbb_dispatch_io()
1781 xbb_complete_reqlist(xbb, reqlist); in xbb_dispatch_io()
1818 struct xbb_softc *xbb; in xbb_run_queue() local
1825 xbb = (struct xbb_softc *)context; in xbb_run_queue()
1826 rings = &xbb->rings; in xbb_run_queue()
1847 reqlist = STAILQ_LAST(&xbb->reqlist_pending_stailq, in xbb_run_queue()
1882 switch (xbb->abi) { in xbb_run_queue()
1884 ring_req = RING_GET_REQUEST(&xbb->rings.native, in xbb_run_queue()
1892 &xbb->rings.x86_32, rings->common.req_cons); in xbb_run_queue()
1902 ring_req64 =RING_GET_REQUEST(&xbb->rings.x86_64, in xbb_run_queue()
1923 && ((xbb->no_coalesce_reqs != 0) in xbb_run_queue()
1924 || ((xbb->no_coalesce_reqs == 0) in xbb_run_queue()
1928 xbb->max_reqlist_segments))))) { in xbb_run_queue()
1938 retval = xbb_get_resources(xbb, &reqlist, ring_req, in xbb_run_queue()
1939 xbb->rings.common.req_cons); in xbb_run_queue()
1962 xbb->rings.common.req_cons++; in xbb_run_queue()
1963 xbb->reqs_received++; in xbb_run_queue()
1972 reqlist = STAILQ_FIRST(&xbb->reqlist_pending_stailq); in xbb_run_queue()
1985 STAILQ_REMOVE_HEAD(&xbb->reqlist_pending_stailq, links); in xbb_run_queue()
1987 retval = xbb_dispatch_io(xbb, reqlist); in xbb_run_queue()
1996 STAILQ_INSERT_HEAD(&xbb->reqlist_pending_stailq, in xbb_run_queue()
2011 reqlist = STAILQ_FIRST(&xbb->reqlist_pending_stailq); in xbb_run_queue()
2014 xbb->forced_dispatch++; in xbb_run_queue()
2016 xbb->normal_dispatch++; in xbb_run_queue()
2018 xbb->total_dispatch++; in xbb_run_queue()
2032 struct xbb_softc *xbb; in xbb_filter() local
2035 xbb = (struct xbb_softc *)arg; in xbb_filter()
2036 taskqueue_enqueue(xbb->io_taskqueue, &xbb->io_task); in xbb_filter()
2041 SDT_PROVIDER_DEFINE(xbb);
2042 SDT_PROBE_DEFINE1(xbb, kernel, xbb_dispatch_dev, flush, "int");
2043 SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_dev, read, "int", "uint64_t",
2045 SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_dev, write, "int",
2061 xbb_dispatch_dev(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, in xbb_dispatch_dev() argument
2075 dev_data = &xbb->backend.dev; in xbb_dispatch_dev()
2077 << xbb->sector_size_shift; in xbb_dispatch_dev()
2101 SDT_PROBE1(xbb, kernel, xbb_dispatch_dev, flush, in xbb_dispatch_dev()
2102 device_get_unit(xbb->dev)); in xbb_dispatch_dev()
2109 xbb_sg = xbb->xbb_sgs; in xbb_dispatch_dev()
2120 if ((bio->bio_length & (xbb->sector_size - 1)) != 0) { in xbb_dispatch_dev()
2124 __func__, xbb->otherend_id); in xbb_dispatch_dev()
2136 if ((bio_offset & (xbb->sector_size - 1)) != 0){ in xbb_dispatch_dev()
2139 xbb->otherend_id); in xbb_dispatch_dev()
2157 bio->bio_pblkno = bio_offset >> xbb->sector_size_shift; in xbb_dispatch_dev()
2165 if ((bio->bio_length & (xbb->sector_size - 1)) != 0) { in xbb_dispatch_dev()
2169 __func__, xbb->otherend_id); in xbb_dispatch_dev()
2197 SDT_PROBE3(xbb, kernel, xbb_dispatch_dev, read, in xbb_dispatch_dev()
2198 device_get_unit(xbb->dev), in xbb_dispatch_dev()
2202 SDT_PROBE3(xbb, kernel, xbb_dispatch_dev, write, in xbb_dispatch_dev()
2203 device_get_unit(xbb->dev), in xbb_dispatch_dev()
2219 SDT_PROBE_DEFINE1(xbb, kernel, xbb_dispatch_file, flush, "int");
2220 SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_file, read, "int", "uint64_t",
2222 SDT_PROBE_DEFINE3(xbb, kernel, xbb_dispatch_file, write, "int",
2237 xbb_dispatch_file(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist, in xbb_dispatch_file() argument
2252 file_data = &xbb->backend.file; in xbb_dispatch_file()
2266 SDT_PROBE1(xbb, kernel, xbb_dispatch_file, flush, in xbb_dispatch_file()
2267 device_get_unit(xbb->dev)); in xbb_dispatch_file()
2269 (void) vn_start_write(xbb->vn, &mountpoint, V_WAIT); in xbb_dispatch_file()
2271 vn_lock(xbb->vn, LK_EXCLUSIVE | LK_RETRY); in xbb_dispatch_file()
2272 error = VOP_FSYNC(xbb->vn, MNT_WAIT, curthread); in xbb_dispatch_file()
2273 VOP_UNLOCK(xbb->vn); in xbb_dispatch_file()
2285 << xbb->sector_size_shift; in xbb_dispatch_file()
2289 xbb_sg = xbb->xbb_sgs; in xbb_dispatch_file()
2361 SDT_PROBE3(xbb, kernel, xbb_dispatch_file, read, in xbb_dispatch_file()
2362 device_get_unit(xbb->dev), xuio.uio_offset, in xbb_dispatch_file()
2365 vn_lock(xbb->vn, LK_EXCLUSIVE | LK_RETRY); in xbb_dispatch_file()
2387 error = VOP_READ(xbb->vn, &xuio, (flags & BIO_ORDERED) ? in xbb_dispatch_file()
2390 VOP_UNLOCK(xbb->vn); in xbb_dispatch_file()
2395 SDT_PROBE3(xbb, kernel, xbb_dispatch_file, write, in xbb_dispatch_file()
2396 device_get_unit(xbb->dev), xuio.uio_offset, in xbb_dispatch_file()
2399 (void)vn_start_write(xbb->vn, &mountpoint, V_WAIT); in xbb_dispatch_file()
2401 vn_lock(xbb->vn, LK_EXCLUSIVE | LK_RETRY); in xbb_dispatch_file()
2421 error = VOP_WRITE(xbb->vn, &xuio, (flags & BIO_ORDERED) ? in xbb_dispatch_file()
2423 VOP_UNLOCK(xbb->vn); in xbb_dispatch_file()
2458 xbb_complete_reqlist(xbb, reqlist); in xbb_dispatch_file()
2471 xbb_close_backend(struct xbb_softc *xbb) in xbb_close_backend() argument
2474 DPRINTF("closing dev=%s\n", xbb->dev_name); in xbb_close_backend()
2475 if (xbb->vn) { in xbb_close_backend()
2478 if ((xbb->flags & XBBF_READ_ONLY) == 0) in xbb_close_backend()
2481 switch (xbb->device_type) { in xbb_close_backend()
2483 if (xbb->backend.dev.csw) { in xbb_close_backend()
2484 dev_relthread(xbb->backend.dev.cdev, in xbb_close_backend()
2485 xbb->backend.dev.dev_ref); in xbb_close_backend()
2486 xbb->backend.dev.csw = NULL; in xbb_close_backend()
2487 xbb->backend.dev.cdev = NULL; in xbb_close_backend()
2498 (void)vn_close(xbb->vn, flags, NOCRED, curthread); in xbb_close_backend()
2499 xbb->vn = NULL; in xbb_close_backend()
2501 switch (xbb->device_type) { in xbb_close_backend()
2505 if (xbb->backend.file.cred != NULL) { in xbb_close_backend()
2506 crfree(xbb->backend.file.cred); in xbb_close_backend()
2507 xbb->backend.file.cred = NULL; in xbb_close_backend()
2527 xbb_open_dev(struct xbb_softc *xbb) in xbb_open_dev() argument
2534 xbb->device_type = XBB_TYPE_DISK; in xbb_open_dev()
2535 xbb->dispatch_io = xbb_dispatch_dev; in xbb_open_dev()
2536 xbb->backend.dev.cdev = xbb->vn->v_rdev; in xbb_open_dev()
2537 xbb->backend.dev.csw = dev_refthread(xbb->backend.dev.cdev, in xbb_open_dev()
2538 &xbb->backend.dev.dev_ref); in xbb_open_dev()
2539 if (xbb->backend.dev.csw == NULL) in xbb_open_dev()
2542 error = VOP_GETATTR(xbb->vn, &vattr, NOCRED); in xbb_open_dev()
2544 xenbus_dev_fatal(xbb->dev, error, "error getting " in xbb_open_dev()
2546 xbb->dev_name); in xbb_open_dev()
2550 dev = xbb->vn->v_rdev; in xbb_open_dev()
2553 xenbus_dev_fatal(xbb->dev, ENODEV, "no d_ioctl for " in xbb_open_dev()
2554 "device %s!", xbb->dev_name); in xbb_open_dev()
2559 (caddr_t)&xbb->sector_size, FREAD, in xbb_open_dev()
2562 xenbus_dev_fatal(xbb->dev, error, in xbb_open_dev()
2564 "for device %s", xbb->dev_name); in xbb_open_dev()
2569 (caddr_t)&xbb->media_size, FREAD, in xbb_open_dev()
2572 xenbus_dev_fatal(xbb->dev, error, in xbb_open_dev()
2574 "for device %s", xbb->dev_name); in xbb_open_dev()
2589 xbb_open_file(struct xbb_softc *xbb) in xbb_open_file() argument
2595 file_data = &xbb->backend.file; in xbb_open_file()
2596 xbb->device_type = XBB_TYPE_FILE; in xbb_open_file()
2597 xbb->dispatch_io = xbb_dispatch_file; in xbb_open_file()
2598 error = VOP_GETATTR(xbb->vn, &vattr, curthread->td_ucred); in xbb_open_file()
2600 xenbus_dev_fatal(xbb->dev, error, in xbb_open_file()
2602 "for file %s", xbb->dev_name); in xbb_open_file()
2611 if (VOP_ISLOCKED(xbb->vn) != LK_EXCLUSIVE) { in xbb_open_file()
2612 vn_lock(xbb->vn, LK_UPGRADE | LK_RETRY); in xbb_open_file()
2613 if (VN_IS_DOOMED(xbb->vn)) { in xbb_open_file()
2615 xenbus_dev_fatal(xbb->dev, error, in xbb_open_file()
2617 xbb->dev_name); in xbb_open_file()
2624 xbb->media_size = vattr.va_size; in xbb_open_file()
2636 xbb->sector_size = vattr.va_blocksize; in xbb_open_file()
2638 xbb->sector_size = 512; in xbb_open_file()
2644 if (xbb->media_size < xbb->sector_size) { in xbb_open_file()
2646 xenbus_dev_fatal(xbb->dev, error, in xbb_open_file()
2648 xbb->dev_name, in xbb_open_file()
2649 (uintmax_t)xbb->media_size, in xbb_open_file()
2650 xbb->sector_size); in xbb_open_file()
2663 xbb_open_backend(struct xbb_softc *xbb) in xbb_open_backend() argument
2672 DPRINTF("opening dev=%s\n", xbb->dev_name); in xbb_open_backend()
2675 xenbus_dev_fatal(xbb->dev, ENOENT, in xbb_open_backend()
2680 if ((xbb->flags & XBBF_READ_ONLY) == 0) in xbb_open_backend()
2686 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, xbb->dev_name, curthread); in xbb_open_backend()
2695 if (xbb->dev_name[0] != '/') { in xbb_open_backend()
2700 dev_name = malloc(strlen(xbb->dev_name) in xbb_open_backend()
2705 xbb->dev_name); in xbb_open_backend()
2706 free(xbb->dev_name, M_XENBLOCKBACK); in xbb_open_backend()
2707 xbb->dev_name = dev_name; in xbb_open_backend()
2711 xenbus_dev_fatal(xbb->dev, error, "error opening device %s", in xbb_open_backend()
2712 xbb->dev_name); in xbb_open_backend()
2718 xbb->vn = nd.ni_vp; in xbb_open_backend()
2721 if (vn_isdisk_error(xbb->vn, &error)) { in xbb_open_backend()
2722 error = xbb_open_dev(xbb); in xbb_open_backend()
2723 } else if (xbb->vn->v_type == VREG) { in xbb_open_backend()
2724 error = xbb_open_file(xbb); in xbb_open_backend()
2727 xenbus_dev_fatal(xbb->dev, error, "%s is not a disk " in xbb_open_backend()
2728 "or file", xbb->dev_name); in xbb_open_backend()
2730 VOP_UNLOCK(xbb->vn); in xbb_open_backend()
2733 xbb_close_backend(xbb); in xbb_open_backend()
2737 xbb->sector_size_shift = fls(xbb->sector_size) - 1; in xbb_open_backend()
2738 xbb->media_num_sectors = xbb->media_size >> xbb->sector_size_shift; in xbb_open_backend()
2741 (xbb->device_type == XBB_TYPE_DISK) ? "dev" : "file", in xbb_open_backend()
2742 xbb->dev_name, xbb->sector_size, xbb->media_size); in xbb_open_backend()
2754 xbb_free_communication_mem(struct xbb_softc *xbb) in xbb_free_communication_mem() argument
2756 if (xbb->kva != 0) { in xbb_free_communication_mem()
2757 if (xbb->pseudo_phys_res != NULL) { in xbb_free_communication_mem()
2758 xenmem_free(xbb->dev, xbb->pseudo_phys_res_id, in xbb_free_communication_mem()
2759 xbb->pseudo_phys_res); in xbb_free_communication_mem()
2760 xbb->pseudo_phys_res = NULL; in xbb_free_communication_mem()
2763 xbb->kva = 0; in xbb_free_communication_mem()
2764 xbb->gnt_base_addr = 0; in xbb_free_communication_mem()
2765 if (xbb->kva_free != NULL) { in xbb_free_communication_mem()
2766 free(xbb->kva_free, M_XENBLOCKBACK); in xbb_free_communication_mem()
2767 xbb->kva_free = NULL; in xbb_free_communication_mem()
2777 xbb_disconnect(struct xbb_softc *xbb) in xbb_disconnect() argument
2786 if ((xbb->flags & XBBF_RING_CONNECTED) == 0) in xbb_disconnect()
2789 mtx_unlock(&xbb->lock); in xbb_disconnect()
2790 xen_intr_unbind(&xbb->xen_intr_handle); in xbb_disconnect()
2791 taskqueue_drain(xbb->io_taskqueue, &xbb->io_task); in xbb_disconnect()
2792 mtx_lock(&xbb->lock); in xbb_disconnect()
2798 if (xbb->active_request_count != 0) in xbb_disconnect()
2802 ring_idx < xbb->ring_config.ring_pages; in xbb_disconnect()
2804 op->host_addr = xbb->ring_config.gnt_addr in xbb_disconnect()
2806 op->dev_bus_addr = xbb->ring_config.bus_addr[ring_idx]; in xbb_disconnect()
2807 op->handle = xbb->ring_config.handle[ring_idx]; in xbb_disconnect()
2811 xbb->ring_config.ring_pages); in xbb_disconnect()
2815 xbb_free_communication_mem(xbb); in xbb_disconnect()
2817 if (xbb->requests != NULL) { in xbb_disconnect()
2818 free(xbb->requests, M_XENBLOCKBACK); in xbb_disconnect()
2819 xbb->requests = NULL; in xbb_disconnect()
2822 if (xbb->request_lists != NULL) { in xbb_disconnect()
2827 for (i = 0, reqlist = xbb->request_lists; in xbb_disconnect()
2828 i < xbb->max_requests; i++, reqlist++){ in xbb_disconnect()
2840 free(xbb->request_lists, M_XENBLOCKBACK); in xbb_disconnect()
2841 xbb->request_lists = NULL; in xbb_disconnect()
2844 xbb->flags &= ~XBBF_RING_CONNECTED; in xbb_disconnect()
2856 xbb_connect_ring(struct xbb_softc *xbb) in xbb_connect_ring() argument
2863 if ((xbb->flags & XBBF_RING_CONNECTED) != 0) in xbb_connect_ring()
2870 xbb->ring_config.va = xbb->kva in xbb_connect_ring()
2871 + (xbb->kva_size in xbb_connect_ring()
2872 - (xbb->ring_config.ring_pages * PAGE_SIZE)); in xbb_connect_ring()
2873 xbb->ring_config.gnt_addr = xbb->gnt_base_addr in xbb_connect_ring()
2874 + (xbb->kva_size in xbb_connect_ring()
2875 - (xbb->ring_config.ring_pages * PAGE_SIZE)); in xbb_connect_ring()
2878 ring_idx < xbb->ring_config.ring_pages; in xbb_connect_ring()
2880 gnt->host_addr = xbb->ring_config.gnt_addr in xbb_connect_ring()
2883 gnt->ref = xbb->ring_config.ring_ref[ring_idx]; in xbb_connect_ring()
2884 gnt->dom = xbb->otherend_id; in xbb_connect_ring()
2888 xbb->ring_config.ring_pages); in xbb_connect_ring()
2893 ring_idx < xbb->ring_config.ring_pages; in xbb_connect_ring()
2899 xbb->ring_config.va = 0; in xbb_connect_ring()
2900 xenbus_dev_fatal(xbb->dev, EACCES, in xbb_connect_ring()
2905 for (i = 0, j = 0; i < xbb->ring_config.ring_pages; in xbb_connect_ring()
2923 xbb->ring_config.handle[ring_idx] = gnt->handle; in xbb_connect_ring()
2924 xbb->ring_config.bus_addr[ring_idx] = gnt->dev_bus_addr; in xbb_connect_ring()
2928 switch (xbb->abi) { in xbb_connect_ring()
2932 sring = (blkif_sring_t *)xbb->ring_config.va; in xbb_connect_ring()
2933 BACK_RING_INIT(&xbb->rings.native, sring, in xbb_connect_ring()
2934 xbb->ring_config.ring_pages * PAGE_SIZE); in xbb_connect_ring()
2940 sring_x86_32 = (blkif_x86_32_sring_t *)xbb->ring_config.va; in xbb_connect_ring()
2941 BACK_RING_INIT(&xbb->rings.x86_32, sring_x86_32, in xbb_connect_ring()
2942 xbb->ring_config.ring_pages * PAGE_SIZE); in xbb_connect_ring()
2948 sring_x86_64 = (blkif_x86_64_sring_t *)xbb->ring_config.va; in xbb_connect_ring()
2949 BACK_RING_INIT(&xbb->rings.x86_64, sring_x86_64, in xbb_connect_ring()
2950 xbb->ring_config.ring_pages * PAGE_SIZE); in xbb_connect_ring()
2957 xbb->flags |= XBBF_RING_CONNECTED; in xbb_connect_ring()
2959 error = xen_intr_bind_remote_port(xbb->dev, in xbb_connect_ring()
2960 xbb->otherend_id, in xbb_connect_ring()
2961 xbb->ring_config.evtchn, in xbb_connect_ring()
2964 /*arg*/xbb, in xbb_connect_ring()
2966 &xbb->xen_intr_handle); in xbb_connect_ring()
2968 (void)xbb_disconnect(xbb); in xbb_connect_ring()
2969 xenbus_dev_fatal(xbb->dev, error, "binding event channel"); in xbb_connect_ring()
2989 xbb_alloc_communication_mem(struct xbb_softc *xbb) in xbb_alloc_communication_mem() argument
2991 xbb->reqlist_kva_pages = xbb->max_requests * xbb->max_request_segments; in xbb_alloc_communication_mem()
2992 xbb->reqlist_kva_size = xbb->reqlist_kva_pages * PAGE_SIZE; in xbb_alloc_communication_mem()
2993 xbb->kva_size = xbb->reqlist_kva_size + in xbb_alloc_communication_mem()
2994 (xbb->ring_config.ring_pages * PAGE_SIZE); in xbb_alloc_communication_mem()
2996 xbb->kva_free = bit_alloc(xbb->reqlist_kva_pages, M_XENBLOCKBACK, M_NOWAIT); in xbb_alloc_communication_mem()
2997 if (xbb->kva_free == NULL) in xbb_alloc_communication_mem()
3001 device_get_nameunit(xbb->dev), xbb->kva_size, in xbb_alloc_communication_mem()
3002 xbb->reqlist_kva_size); in xbb_alloc_communication_mem()
3009 xbb->pseudo_phys_res_id = 0; in xbb_alloc_communication_mem()
3010 xbb->pseudo_phys_res = xenmem_alloc(xbb->dev, &xbb->pseudo_phys_res_id, in xbb_alloc_communication_mem()
3011 xbb->kva_size); in xbb_alloc_communication_mem()
3012 if (xbb->pseudo_phys_res == NULL) { in xbb_alloc_communication_mem()
3013 xbb->kva = 0; in xbb_alloc_communication_mem()
3016 xbb->kva = (vm_offset_t)rman_get_virtual(xbb->pseudo_phys_res); in xbb_alloc_communication_mem()
3017 xbb->gnt_base_addr = rman_get_start(xbb->pseudo_phys_res); in xbb_alloc_communication_mem()
3020 device_get_nameunit(xbb->dev), (uintmax_t)xbb->kva, in xbb_alloc_communication_mem()
3021 (uintmax_t)xbb->gnt_base_addr); in xbb_alloc_communication_mem()
3031 xbb_collect_frontend_info(struct xbb_softc *xbb) in xbb_collect_frontend_info() argument
3040 otherend_path = xenbus_get_otherend_path(xbb->dev); in xbb_collect_frontend_info()
3045 xbb->ring_config.ring_pages = 1; in xbb_collect_frontend_info()
3046 xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST; in xbb_collect_frontend_info()
3047 xbb->max_request_size = xbb->max_request_segments * PAGE_SIZE; in xbb_collect_frontend_info()
3054 &xbb->ring_config.evtchn); in xbb_collect_frontend_info()
3056 xenbus_dev_fatal(xbb->dev, error, in xbb_collect_frontend_info()
3059 xenbus_get_otherend_path(xbb->dev)); in xbb_collect_frontend_info()
3077 xbb->max_requests = 32; in xbb_collect_frontend_info()
3082 xbb->ring_config.ring_pages = 1 << ring_page_order; in xbb_collect_frontend_info()
3083 ring_size = PAGE_SIZE * xbb->ring_config.ring_pages; in xbb_collect_frontend_info()
3084 xbb->max_requests = BLKIF_MAX_RING_REQUESTS(ring_size); in xbb_collect_frontend_info()
3086 if (xbb->ring_config.ring_pages > XBB_MAX_RING_PAGES) { in xbb_collect_frontend_info()
3087 xenbus_dev_fatal(xbb->dev, EINVAL, in xbb_collect_frontend_info()
3091 xbb->ring_config.ring_pages, in xbb_collect_frontend_info()
3096 if (xbb->ring_config.ring_pages == 1) { in xbb_collect_frontend_info()
3099 &xbb->ring_config.ring_ref[0], in xbb_collect_frontend_info()
3102 xenbus_dev_fatal(xbb->dev, error, in xbb_collect_frontend_info()
3106 xenbus_get_otherend_path(xbb->dev)); in xbb_collect_frontend_info()
3111 for (ring_idx = 0; ring_idx < xbb->ring_config.ring_pages; in xbb_collect_frontend_info()
3119 &xbb->ring_config.ring_ref[ring_idx]); in xbb_collect_frontend_info()
3121 xenbus_dev_fatal(xbb->dev, error, in xbb_collect_frontend_info()
3141 xbb->abi = BLKIF_PROTOCOL_NATIVE; in xbb_collect_frontend_info()
3143 xbb->abi = BLKIF_PROTOCOL_X86_32; in xbb_collect_frontend_info()
3145 xbb->abi = BLKIF_PROTOCOL_X86_64; in xbb_collect_frontend_info()
3147 xenbus_dev_fatal(xbb->dev, EINVAL, in xbb_collect_frontend_info()
3162 xbb_alloc_requests(struct xbb_softc *xbb) in xbb_alloc_requests() argument
3170 xbb->requests = malloc(xbb->max_requests * sizeof(*xbb->requests), in xbb_alloc_requests()
3172 if (xbb->requests == NULL) { in xbb_alloc_requests()
3173 xenbus_dev_fatal(xbb->dev, ENOMEM, in xbb_alloc_requests()
3178 req = xbb->requests; in xbb_alloc_requests()
3179 last_req = &xbb->requests[xbb->max_requests - 1]; in xbb_alloc_requests()
3180 STAILQ_INIT(&xbb->request_free_stailq); in xbb_alloc_requests()
3182 STAILQ_INSERT_TAIL(&xbb->request_free_stailq, req, links); in xbb_alloc_requests()
3189 xbb_alloc_request_lists(struct xbb_softc *xbb) in xbb_alloc_request_lists() argument
3198 xbb->request_lists = malloc(xbb->max_requests * in xbb_alloc_request_lists()
3199 sizeof(*xbb->request_lists), M_XENBLOCKBACK, M_NOWAIT|M_ZERO); in xbb_alloc_request_lists()
3200 if (xbb->request_lists == NULL) { in xbb_alloc_request_lists()
3201 xenbus_dev_fatal(xbb->dev, ENOMEM, in xbb_alloc_request_lists()
3206 STAILQ_INIT(&xbb->reqlist_free_stailq); in xbb_alloc_request_lists()
3207 STAILQ_INIT(&xbb->reqlist_pending_stailq); in xbb_alloc_request_lists()
3208 for (i = 0; i < xbb->max_requests; i++) { in xbb_alloc_request_lists()
3211 reqlist = &xbb->request_lists[i]; in xbb_alloc_request_lists()
3213 reqlist->xbb = xbb; in xbb_alloc_request_lists()
3216 reqlist->bounce = malloc(xbb->max_reqlist_size, in xbb_alloc_request_lists()
3219 xenbus_dev_fatal(xbb->dev, ENOMEM, in xbb_alloc_request_lists()
3226 reqlist->gnt_handles = malloc(xbb->max_reqlist_segments * in xbb_alloc_request_lists()
3230 xenbus_dev_fatal(xbb->dev, ENOMEM, in xbb_alloc_request_lists()
3236 for (seg = 0; seg < xbb->max_reqlist_segments; seg++) in xbb_alloc_request_lists()
3239 STAILQ_INSERT_TAIL(&xbb->reqlist_free_stailq, reqlist, links); in xbb_alloc_request_lists()
3251 xbb_publish_backend_info(struct xbb_softc *xbb) in xbb_publish_backend_info() argument
3258 our_path = xenbus_get_node(xbb->dev); in xbb_publish_backend_info()
3262 xenbus_dev_fatal(xbb->dev, error, in xbb_publish_backend_info()
3270 "%"PRIu64, xbb->media_num_sectors); in xbb_publish_backend_info()
3277 xbb->flags & XBBF_READ_ONLY in xbb_publish_backend_info()
3284 xbb->sector_size); in xbb_publish_backend_info()
3292 xenbus_dev_fatal(xbb->dev, error, "ending transaction"); in xbb_publish_backend_info()
3297 xenbus_dev_fatal(xbb->dev, error, "writing %s/%s", in xbb_publish_backend_info()
3310 xbb_connect(struct xbb_softc *xbb) in xbb_connect() argument
3314 if (!xbb->hotplug_done || in xbb_connect()
3315 (xenbus_get_state(xbb->dev) != XenbusStateInitWait) || in xbb_connect()
3316 (xbb_collect_frontend_info(xbb) != 0)) in xbb_connect()
3319 xbb->flags &= ~XBBF_SHUTDOWN; in xbb_connect()
3326 xbb->max_reqlist_segments = MIN(xbb->max_request_segments * in xbb_connect()
3327 xbb->max_requests, XBB_MAX_SEGMENTS_PER_REQLIST); in xbb_connect()
3333 xbb->max_reqlist_size = xbb->max_reqlist_segments * PAGE_SIZE; in xbb_connect()
3336 error = xbb_alloc_communication_mem(xbb); in xbb_connect()
3338 xenbus_dev_fatal(xbb->dev, error, in xbb_connect()
3343 error = xbb_alloc_requests(xbb); in xbb_connect()
3349 error = xbb_alloc_request_lists(xbb); in xbb_connect()
3358 error = xbb_connect_ring(xbb); in xbb_connect()
3364 if (xbb_publish_backend_info(xbb) != 0) { in xbb_connect()
3370 (void)xbb_disconnect(xbb); in xbb_connect()
3375 xenbus_set_state(xbb->dev, XenbusStateConnected); in xbb_connect()
3390 xbb_shutdown(struct xbb_softc *xbb) in xbb_shutdown() argument
3404 if ((xbb->flags & XBBF_IN_SHUTDOWN) != 0) in xbb_shutdown()
3407 xbb->flags |= XBBF_IN_SHUTDOWN; in xbb_shutdown()
3408 mtx_unlock(&xbb->lock); in xbb_shutdown()
3410 if (xbb->hotplug_watch.node != NULL) { in xbb_shutdown()
3411 xs_unregister_watch(&xbb->hotplug_watch); in xbb_shutdown()
3412 free(xbb->hotplug_watch.node, M_XENBLOCKBACK); in xbb_shutdown()
3413 xbb->hotplug_watch.node = NULL; in xbb_shutdown()
3415 xbb->hotplug_done = false; in xbb_shutdown()
3417 if (xenbus_get_state(xbb->dev) < XenbusStateClosing) in xbb_shutdown()
3418 xenbus_set_state(xbb->dev, XenbusStateClosing); in xbb_shutdown()
3420 frontState = xenbus_get_otherend_state(xbb->dev); in xbb_shutdown()
3421 mtx_lock(&xbb->lock); in xbb_shutdown()
3422 xbb->flags &= ~XBBF_IN_SHUTDOWN; in xbb_shutdown()
3431 xbb->flags |= XBBF_SHUTDOWN; in xbb_shutdown()
3434 error = xbb_disconnect(xbb); in xbb_shutdown()
3450 wakeup(xbb); in xbb_shutdown()
3464 xbb_attach_failed(struct xbb_softc *xbb, int err, const char *fmt, ...) in xbb_attach_failed() argument
3471 xs_vprintf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach_failed()
3474 xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach_failed()
3477 xenbus_dev_vfatal(xbb->dev, err, fmt, ap); in xbb_attach_failed()
3480 xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach_failed()
3482 mtx_lock(&xbb->lock); in xbb_attach_failed()
3483 xbb_shutdown(xbb); in xbb_attach_failed()
3484 mtx_unlock(&xbb->lock); in xbb_attach_failed()
3515 xbb_setup_sysctl(struct xbb_softc *xbb) in xbb_setup_sysctl() argument
3520 sysctl_ctx = device_get_sysctl_ctx(xbb->dev); in xbb_setup_sysctl()
3524 sysctl_tree = device_get_sysctl_tree(xbb->dev); in xbb_setup_sysctl()
3529 "disable_flush", CTLFLAG_RW, &xbb->disable_flush, 0, in xbb_setup_sysctl()
3533 "flush_interval", CTLFLAG_RW, &xbb->flush_interval, 0, in xbb_setup_sysctl()
3537 "no_coalesce_reqs", CTLFLAG_RW, &xbb->no_coalesce_reqs,0, in xbb_setup_sysctl()
3541 "reqs_received", CTLFLAG_RW, &xbb->reqs_received, in xbb_setup_sysctl()
3545 "reqs_completed", CTLFLAG_RW, &xbb->reqs_completed, in xbb_setup_sysctl()
3550 &xbb->reqs_queued_for_completion, in xbb_setup_sysctl()
3555 &xbb->reqs_completed_with_error, in xbb_setup_sysctl()
3559 "forced_dispatch", CTLFLAG_RW, &xbb->forced_dispatch, in xbb_setup_sysctl()
3563 "normal_dispatch", CTLFLAG_RW, &xbb->normal_dispatch, in xbb_setup_sysctl()
3567 "total_dispatch", CTLFLAG_RW, &xbb->total_dispatch, in xbb_setup_sysctl()
3571 "kva_shortages", CTLFLAG_RW, &xbb->kva_shortages, in xbb_setup_sysctl()
3576 &xbb->request_shortages, in xbb_setup_sysctl()
3580 "max_requests", CTLFLAG_RD, &xbb->max_requests, 0, in xbb_setup_sysctl()
3585 &xbb->max_request_segments, 0, in xbb_setup_sysctl()
3590 &xbb->max_request_size, 0, in xbb_setup_sysctl()
3595 &xbb->ring_config.ring_pages, 0, in xbb_setup_sysctl()
3603 struct xbb_softc *xbb; in xbb_attach_disk() local
3607 xbb = device_get_softc(dev); in xbb_attach_disk()
3610 NULL, &xbb->dev_name, NULL); in xbb_attach_disk()
3619 error = xs_gather(XST_NIL, xenbus_get_otherend_path(xbb->dev), in xbb_attach_disk()
3620 "device-type", NULL, &xbb->dev_type, in xbb_attach_disk()
3623 xbb->dev_type = NULL; in xbb_attach_disk()
3626 "mode", NULL, &xbb->dev_mode, in xbb_attach_disk()
3629 xbb_attach_failed(xbb, error, "reading backend fields at %s", in xbb_attach_disk()
3635 if (strchr(xbb->dev_mode, 'w') == NULL) in xbb_attach_disk()
3636 xbb->flags |= XBBF_READ_ONLY; in xbb_attach_disk()
3642 error = xbb_open_backend(xbb); in xbb_attach_disk()
3644 xbb_attach_failed(xbb, error, "Unable to open %s", in xbb_attach_disk()
3645 xbb->dev_name); in xbb_attach_disk()
3650 xbb->xbb_stats = devstat_new_entry("xbb", device_get_unit(xbb->dev), in xbb_attach_disk()
3651 xbb->sector_size, in xbb_attach_disk()
3657 xbb->xbb_stats_in = devstat_new_entry("xbbi", device_get_unit(xbb->dev), in xbb_attach_disk()
3658 xbb->sector_size, in xbb_attach_disk()
3666 xbb_setup_sysctl(xbb); in xbb_attach_disk()
3672 xbb->io_taskqueue = taskqueue_create_fast(device_get_nameunit(dev), in xbb_attach_disk()
3675 /*contxt*/&xbb->io_taskqueue); in xbb_attach_disk()
3676 if (xbb->io_taskqueue == NULL) { in xbb_attach_disk()
3677 xbb_attach_failed(xbb, error, "Unable to create taskqueue"); in xbb_attach_disk()
3681 taskqueue_start_threads(&xbb->io_taskqueue, in xbb_attach_disk()
3688 error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach_disk()
3691 xbb_attach_failed(xbb, error, "writing %s/hotplug-status", in xbb_attach_disk()
3692 xenbus_get_node(xbb->dev)); in xbb_attach_disk()
3696 xbb->hotplug_done = true; in xbb_attach_disk()
3699 if (xenbus_get_otherend_state(xbb->dev) == XenbusStateInitialised) in xbb_attach_disk()
3700 xbb_connect(xbb); in xbb_attach_disk()
3713 struct xbb_softc *xbb; in xbb_attach() local
3725 xbb = device_get_softc(dev); in xbb_attach()
3726 xbb->dev = dev; in xbb_attach()
3727 xbb->otherend_id = xenbus_get_otherend_id(dev); in xbb_attach()
3728 TASK_INIT(&xbb->io_task, /*priority*/0, xbb_run_queue, xbb); in xbb_attach()
3729 mtx_init(&xbb->lock, device_get_nameunit(dev), NULL, MTX_DEF); in xbb_attach()
3735 error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach()
3738 xbb_attach_failed(xbb, error, "writing %s/feature-barrier", in xbb_attach()
3739 xenbus_get_node(xbb->dev)); in xbb_attach()
3743 error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach()
3746 xbb_attach_failed(xbb, error, "writing %s/feature-flush-cache", in xbb_attach()
3747 xenbus_get_node(xbb->dev)); in xbb_attach()
3752 error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev), in xbb_attach()
3755 xbb_attach_failed(xbb, error, "writing %s/max-ring-page-order", in xbb_attach()
3756 xenbus_get_node(xbb->dev)); in xbb_attach()
3764 KASSERT(!xbb->hotplug_done, ("Hotplug scripts already executed")); in xbb_attach()
3765 watch_path = xs_join(xenbus_get_node(xbb->dev), "physical-device-path"); in xbb_attach()
3766 xbb->hotplug_watch.callback_data = (uintptr_t)dev; in xbb_attach()
3767 xbb->hotplug_watch.callback = xbb_attach_disk; in xbb_attach()
3768 KASSERT(xbb->hotplug_watch.node == NULL, ("watch node already setup")); in xbb_attach()
3769 xbb->hotplug_watch.node = strdup(sbuf_data(watch_path), M_XENBLOCKBACK); in xbb_attach()
3775 xbb->hotplug_watch.max_pending = 1; in xbb_attach()
3777 error = xs_register_watch(&xbb->hotplug_watch); in xbb_attach()
3779 xbb_attach_failed(xbb, error, "failed to create watch on %s", in xbb_attach()
3780 xbb->hotplug_watch.node); in xbb_attach()
3781 free(xbb->hotplug_watch.node, M_XENBLOCKBACK); in xbb_attach()
3807 struct xbb_softc *xbb; in xbb_detach() local
3811 xbb = device_get_softc(dev); in xbb_detach()
3812 mtx_lock(&xbb->lock); in xbb_detach()
3813 while (xbb_shutdown(xbb) == EAGAIN) { in xbb_detach()
3814 msleep(xbb, &xbb->lock, /*wakeup prio unchanged*/0, in xbb_detach()
3817 mtx_unlock(&xbb->lock); in xbb_detach()
3821 if (xbb->io_taskqueue != NULL) in xbb_detach()
3822 taskqueue_free(xbb->io_taskqueue); in xbb_detach()
3824 if (xbb->xbb_stats != NULL) in xbb_detach()
3825 devstat_remove_entry(xbb->xbb_stats); in xbb_detach()
3827 if (xbb->xbb_stats_in != NULL) in xbb_detach()
3828 devstat_remove_entry(xbb->xbb_stats_in); in xbb_detach()
3830 xbb_close_backend(xbb); in xbb_detach()
3832 if (xbb->dev_mode != NULL) { in xbb_detach()
3833 free(xbb->dev_mode, M_XENSTORE); in xbb_detach()
3834 xbb->dev_mode = NULL; in xbb_detach()
3837 if (xbb->dev_type != NULL) { in xbb_detach()
3838 free(xbb->dev_type, M_XENSTORE); in xbb_detach()
3839 xbb->dev_type = NULL; in xbb_detach()
3842 if (xbb->dev_name != NULL) { in xbb_detach()
3843 free(xbb->dev_name, M_XENSTORE); in xbb_detach()
3844 xbb->dev_name = NULL; in xbb_detach()
3847 mtx_destroy(&xbb->lock); in xbb_detach()
3898 struct xbb_softc *xbb = device_get_softc(dev); in xbb_frontend_changed() local
3902 xenbus_strstate(xenbus_get_state(xbb->dev))); in xbb_frontend_changed()
3909 xbb_connect(xbb); in xbb_frontend_changed()
3913 mtx_lock(&xbb->lock); in xbb_frontend_changed()
3914 xbb_shutdown(xbb); in xbb_frontend_changed()
3915 mtx_unlock(&xbb->lock); in xbb_frontend_changed()
3917 xenbus_set_state(xbb->dev, XenbusStateClosed); in xbb_frontend_changed()
3920 xenbus_dev_fatal(xbb->dev, EINVAL, "saw state %d at frontend", in xbb_frontend_changed()