17756SMark.Johnson@Sun.COM /*
27756SMark.Johnson@Sun.COM * CDDL HEADER START
37756SMark.Johnson@Sun.COM *
47756SMark.Johnson@Sun.COM * The contents of this file are subject to the terms of the
57756SMark.Johnson@Sun.COM * Common Development and Distribution License (the "License").
67756SMark.Johnson@Sun.COM * You may not use this file except in compliance with the License.
77756SMark.Johnson@Sun.COM *
87756SMark.Johnson@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97756SMark.Johnson@Sun.COM * or http://www.opensolaris.org/os/licensing.
107756SMark.Johnson@Sun.COM * See the License for the specific language governing permissions
117756SMark.Johnson@Sun.COM * and limitations under the License.
127756SMark.Johnson@Sun.COM *
137756SMark.Johnson@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147756SMark.Johnson@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157756SMark.Johnson@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167756SMark.Johnson@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177756SMark.Johnson@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187756SMark.Johnson@Sun.COM *
197756SMark.Johnson@Sun.COM * CDDL HEADER END
207756SMark.Johnson@Sun.COM */
217756SMark.Johnson@Sun.COM
227756SMark.Johnson@Sun.COM /*
2310175SStuart.Maybee@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
247756SMark.Johnson@Sun.COM * Use is subject to license terms.
257756SMark.Johnson@Sun.COM */
267756SMark.Johnson@Sun.COM
277756SMark.Johnson@Sun.COM
287756SMark.Johnson@Sun.COM #include <sys/errno.h>
297756SMark.Johnson@Sun.COM #include <sys/types.h>
307756SMark.Johnson@Sun.COM #include <sys/conf.h>
317756SMark.Johnson@Sun.COM #include <sys/kmem.h>
327756SMark.Johnson@Sun.COM #include <sys/ddi.h>
337756SMark.Johnson@Sun.COM #include <sys/stat.h>
347756SMark.Johnson@Sun.COM #include <sys/sunddi.h>
357756SMark.Johnson@Sun.COM #include <sys/file.h>
367756SMark.Johnson@Sun.COM #include <sys/open.h>
377756SMark.Johnson@Sun.COM #include <sys/modctl.h>
387756SMark.Johnson@Sun.COM #include <sys/ddi_impldefs.h>
397756SMark.Johnson@Sun.COM #include <sys/sysmacros.h>
407756SMark.Johnson@Sun.COM #include <sys/ddidevmap.h>
417756SMark.Johnson@Sun.COM #include <sys/xendev.h>
427756SMark.Johnson@Sun.COM #include <public/io/protocols.h>
437756SMark.Johnson@Sun.COM #include <xen/io/blkif_impl.h>
447756SMark.Johnson@Sun.COM
457756SMark.Johnson@Sun.COM #include "blk_common.h"
467756SMark.Johnson@Sun.COM
477756SMark.Johnson@Sun.COM
487756SMark.Johnson@Sun.COM /* blk interface status */
497756SMark.Johnson@Sun.COM enum blk_if_state {
507756SMark.Johnson@Sun.COM /*
517756SMark.Johnson@Sun.COM * initial state
527756SMark.Johnson@Sun.COM */
537756SMark.Johnson@Sun.COM BLK_IF_UNKNOWN = 0,
547756SMark.Johnson@Sun.COM /*
557756SMark.Johnson@Sun.COM * frontend xenbus state changed to XenbusStateConnected,
567756SMark.Johnson@Sun.COM * we finally connect
577756SMark.Johnson@Sun.COM */
587756SMark.Johnson@Sun.COM BLK_IF_CONNECTED,
597756SMark.Johnson@Sun.COM /*
607756SMark.Johnson@Sun.COM * frontend xenbus state changed to XenbusStateClosed,
617756SMark.Johnson@Sun.COM * interface disconnected
627756SMark.Johnson@Sun.COM */
637756SMark.Johnson@Sun.COM BLK_IF_DISCONNECTED
647756SMark.Johnson@Sun.COM };
657756SMark.Johnson@Sun.COM
667756SMark.Johnson@Sun.COM /* backend device status */
677756SMark.Johnson@Sun.COM enum blk_be_state {
687756SMark.Johnson@Sun.COM /* initial state */
697756SMark.Johnson@Sun.COM BLK_BE_UNKNOWN = 0,
707756SMark.Johnson@Sun.COM /* backend device is ready (hotplug script finishes successfully) */
717756SMark.Johnson@Sun.COM BLK_BE_READY
727756SMark.Johnson@Sun.COM };
737756SMark.Johnson@Sun.COM
747756SMark.Johnson@Sun.COM /* frontend status */
757756SMark.Johnson@Sun.COM enum blk_fe_state {
767756SMark.Johnson@Sun.COM /* initial state */
777756SMark.Johnson@Sun.COM BLK_FE_UNKNOWN = 0,
787756SMark.Johnson@Sun.COM /*
797756SMark.Johnson@Sun.COM * frontend's xenbus state has changed to
807756SMark.Johnson@Sun.COM * XenbusStateInitialised, is ready for connecting
817756SMark.Johnson@Sun.COM */
827756SMark.Johnson@Sun.COM BLK_FE_READY
837756SMark.Johnson@Sun.COM };
847756SMark.Johnson@Sun.COM
857756SMark.Johnson@Sun.COM typedef struct blk_ring_state_s {
867756SMark.Johnson@Sun.COM kmutex_t rs_mutex;
877756SMark.Johnson@Sun.COM boolean_t rs_sleeping_on_ring;
887756SMark.Johnson@Sun.COM boolean_t rs_ring_up;
897756SMark.Johnson@Sun.COM kcondvar_t rs_cv;
907756SMark.Johnson@Sun.COM } blk_ring_state_t;
917756SMark.Johnson@Sun.COM
927756SMark.Johnson@Sun.COM /* Disk Statistics */
937756SMark.Johnson@Sun.COM static char *blk_stats[] = {
947756SMark.Johnson@Sun.COM "rd_reqs",
957756SMark.Johnson@Sun.COM "wr_reqs",
967756SMark.Johnson@Sun.COM "br_reqs",
977756SMark.Johnson@Sun.COM "fl_reqs",
987756SMark.Johnson@Sun.COM "oo_reqs"
997756SMark.Johnson@Sun.COM };
1007756SMark.Johnson@Sun.COM
1017756SMark.Johnson@Sun.COM typedef struct blk_stats_s {
1027756SMark.Johnson@Sun.COM uint64_t bs_req_reads;
1037756SMark.Johnson@Sun.COM uint64_t bs_req_writes;
1047756SMark.Johnson@Sun.COM uint64_t bs_req_barriers;
1057756SMark.Johnson@Sun.COM uint64_t bs_req_flushes;
1067756SMark.Johnson@Sun.COM } blk_stats_t;
1077756SMark.Johnson@Sun.COM
1087756SMark.Johnson@Sun.COM struct blk_ring_s {
1097756SMark.Johnson@Sun.COM kmutex_t ri_mutex;
1107756SMark.Johnson@Sun.COM dev_info_t *ri_dip;
1117756SMark.Johnson@Sun.COM
1127756SMark.Johnson@Sun.COM kstat_t *ri_kstats;
1137756SMark.Johnson@Sun.COM blk_stats_t ri_stats;
1147756SMark.Johnson@Sun.COM
1157756SMark.Johnson@Sun.COM blk_intr_t ri_intr;
1167756SMark.Johnson@Sun.COM caddr_t ri_intr_arg;
1177756SMark.Johnson@Sun.COM blk_ring_cb_t ri_ringup;
1187756SMark.Johnson@Sun.COM caddr_t ri_ringup_arg;
1197756SMark.Johnson@Sun.COM blk_ring_cb_t ri_ringdown;
1207756SMark.Johnson@Sun.COM caddr_t ri_ringdown_arg;
1217756SMark.Johnson@Sun.COM
1227756SMark.Johnson@Sun.COM /* blk interface, backend, and frontend status */
1237756SMark.Johnson@Sun.COM enum blk_if_state ri_if_status;
1247756SMark.Johnson@Sun.COM enum blk_be_state ri_be_status;
1257756SMark.Johnson@Sun.COM enum blk_fe_state ri_fe_status;
1267756SMark.Johnson@Sun.COM
1277756SMark.Johnson@Sun.COM domid_t ri_fe;
1287756SMark.Johnson@Sun.COM
1297756SMark.Johnson@Sun.COM enum blkif_protocol ri_protocol;
1307756SMark.Johnson@Sun.COM size_t ri_nentry;
1317756SMark.Johnson@Sun.COM size_t ri_entrysize;
1327756SMark.Johnson@Sun.COM
1337756SMark.Johnson@Sun.COM xendev_ring_t *ri_ring;
1347756SMark.Johnson@Sun.COM blk_ring_state_t ri_state;
1357756SMark.Johnson@Sun.COM };
1367756SMark.Johnson@Sun.COM
1377756SMark.Johnson@Sun.COM
1387756SMark.Johnson@Sun.COM static void blk_oe_state_change(dev_info_t *dip, ddi_eventcookie_t id,
1397756SMark.Johnson@Sun.COM void *arg, void *impl_data);
1407756SMark.Johnson@Sun.COM static void blk_hp_state_change(dev_info_t *dip, ddi_eventcookie_t id,
1417756SMark.Johnson@Sun.COM void *arg, void *impl_data);
1427756SMark.Johnson@Sun.COM static int blk_check_state_transition(blk_ring_t ring, XenbusState oestate);
1437756SMark.Johnson@Sun.COM static int blk_start_connect(blk_ring_t ring);
1447756SMark.Johnson@Sun.COM static void blk_start_disconnect(blk_ring_t ring);
1457756SMark.Johnson@Sun.COM static void blk_ring_close(blk_ring_t ring);
1467756SMark.Johnson@Sun.COM static int blk_bindto_frontend(blk_ring_t ring);
1477756SMark.Johnson@Sun.COM static void blk_unbindfrom_frontend(blk_ring_t ring);
1487756SMark.Johnson@Sun.COM static uint_t blk_intr(caddr_t arg);
1497756SMark.Johnson@Sun.COM
1507756SMark.Johnson@Sun.COM static int blk_kstat_init(blk_ring_t ring);
1517756SMark.Johnson@Sun.COM static void blk_kstat_fini(blk_ring_t ring);
1527756SMark.Johnson@Sun.COM static int blk_kstat_update(kstat_t *ksp, int flag);
1537756SMark.Johnson@Sun.COM
1547756SMark.Johnson@Sun.COM static void blk_ring_request_32(blkif_request_t *dst,
1557756SMark.Johnson@Sun.COM blkif_x86_32_request_t *src);
1567756SMark.Johnson@Sun.COM static void blk_ring_request_64(blkif_request_t *dst,
1577756SMark.Johnson@Sun.COM blkif_x86_64_request_t *src);
1587756SMark.Johnson@Sun.COM
1597756SMark.Johnson@Sun.COM static void blk_ring_response_32(blkif_x86_32_response_t *dst,
1607756SMark.Johnson@Sun.COM blkif_response_t *src);
1617756SMark.Johnson@Sun.COM static void blk_ring_response_64(blkif_x86_64_response_t *dst,
1627756SMark.Johnson@Sun.COM blkif_response_t *src);
1637756SMark.Johnson@Sun.COM
1647756SMark.Johnson@Sun.COM
1657756SMark.Johnson@Sun.COM /*
1667756SMark.Johnson@Sun.COM * blk_ring_init()
1677756SMark.Johnson@Sun.COM */
1687756SMark.Johnson@Sun.COM int
blk_ring_init(blk_ringinit_args_t * args,blk_ring_t * ringp)1697756SMark.Johnson@Sun.COM blk_ring_init(blk_ringinit_args_t *args, blk_ring_t *ringp)
1707756SMark.Johnson@Sun.COM {
1717756SMark.Johnson@Sun.COM blk_ring_t ring;
1727756SMark.Johnson@Sun.COM int e;
1737756SMark.Johnson@Sun.COM
1747756SMark.Johnson@Sun.COM
1757756SMark.Johnson@Sun.COM ring = kmem_zalloc(sizeof (struct blk_ring_s), KM_SLEEP);
1767756SMark.Johnson@Sun.COM mutex_init(&ring->ri_mutex, NULL, MUTEX_DRIVER, NULL);
1777756SMark.Johnson@Sun.COM ring->ri_dip = args->ar_dip;
1787756SMark.Johnson@Sun.COM ring->ri_intr = args->ar_intr;
1797756SMark.Johnson@Sun.COM ring->ri_intr_arg = args->ar_intr_arg;
1807756SMark.Johnson@Sun.COM ring->ri_ringup = args->ar_ringup;
1817756SMark.Johnson@Sun.COM ring->ri_ringup_arg = args->ar_ringup_arg;
1827756SMark.Johnson@Sun.COM ring->ri_ringdown = args->ar_ringdown;
1837756SMark.Johnson@Sun.COM ring->ri_ringdown_arg = args->ar_ringdown_arg;
1847756SMark.Johnson@Sun.COM
1857756SMark.Johnson@Sun.COM ring->ri_if_status = BLK_IF_UNKNOWN;
1867756SMark.Johnson@Sun.COM ring->ri_be_status = BLK_BE_UNKNOWN;
1877756SMark.Johnson@Sun.COM ring->ri_fe_status = BLK_FE_UNKNOWN;
1887756SMark.Johnson@Sun.COM ring->ri_state.rs_sleeping_on_ring = B_FALSE;
1897756SMark.Johnson@Sun.COM ring->ri_state.rs_ring_up = B_FALSE;
1907756SMark.Johnson@Sun.COM
1917756SMark.Johnson@Sun.COM mutex_init(&ring->ri_state.rs_mutex, NULL, MUTEX_DRIVER, NULL);
1927756SMark.Johnson@Sun.COM cv_init(&ring->ri_state.rs_cv, NULL, CV_DRIVER, NULL);
1937756SMark.Johnson@Sun.COM
1947756SMark.Johnson@Sun.COM e = blk_kstat_init(ring);
1957756SMark.Johnson@Sun.COM if (e != DDI_SUCCESS) {
1967756SMark.Johnson@Sun.COM goto ringinitfail_kstat;
1977756SMark.Johnson@Sun.COM }
1987756SMark.Johnson@Sun.COM
1997756SMark.Johnson@Sun.COM /* Watch frontend and hotplug state change */
2007756SMark.Johnson@Sun.COM if (xvdi_add_event_handler(ring->ri_dip, XS_OE_STATE,
2017756SMark.Johnson@Sun.COM blk_oe_state_change, ring) != DDI_SUCCESS) {
2027756SMark.Johnson@Sun.COM goto ringinitfail_oestate;
2037756SMark.Johnson@Sun.COM }
2047756SMark.Johnson@Sun.COM if (xvdi_add_event_handler(ring->ri_dip, XS_HP_STATE,
2057756SMark.Johnson@Sun.COM blk_hp_state_change, ring) != DDI_SUCCESS) {
2067756SMark.Johnson@Sun.COM goto ringinitfail_hpstate;
2077756SMark.Johnson@Sun.COM }
2087756SMark.Johnson@Sun.COM
2097756SMark.Johnson@Sun.COM /*
2107756SMark.Johnson@Sun.COM * Kick-off hotplug script
2117756SMark.Johnson@Sun.COM */
2127756SMark.Johnson@Sun.COM if (xvdi_post_event(ring->ri_dip, XEN_HP_ADD) != DDI_SUCCESS) {
2137756SMark.Johnson@Sun.COM cmn_err(CE_WARN, "blk@%s: failed to start hotplug script",
2147756SMark.Johnson@Sun.COM ddi_get_name_addr(ring->ri_dip));
2157756SMark.Johnson@Sun.COM goto ringinitfail_postevent;
2167756SMark.Johnson@Sun.COM }
2177756SMark.Johnson@Sun.COM
2187756SMark.Johnson@Sun.COM /*
2197756SMark.Johnson@Sun.COM * start waiting for hotplug event and otherend state event
2207756SMark.Johnson@Sun.COM * mainly for debugging, frontend will not take any op seeing this
2217756SMark.Johnson@Sun.COM */
2227756SMark.Johnson@Sun.COM (void) xvdi_switch_state(ring->ri_dip, XBT_NULL, XenbusStateInitWait);
2237756SMark.Johnson@Sun.COM
2247756SMark.Johnson@Sun.COM *ringp = ring;
2257756SMark.Johnson@Sun.COM return (DDI_SUCCESS);
2267756SMark.Johnson@Sun.COM
2277756SMark.Johnson@Sun.COM ringinitfail_postevent:
2287756SMark.Johnson@Sun.COM xvdi_remove_event_handler(ring->ri_dip, XS_HP_STATE);
2297756SMark.Johnson@Sun.COM ringinitfail_hpstate:
2307756SMark.Johnson@Sun.COM xvdi_remove_event_handler(ring->ri_dip, XS_OE_STATE);
2317756SMark.Johnson@Sun.COM ringinitfail_oestate:
2327756SMark.Johnson@Sun.COM blk_kstat_fini(ring);
2337756SMark.Johnson@Sun.COM ringinitfail_kstat:
2347756SMark.Johnson@Sun.COM cv_destroy(&ring->ri_state.rs_cv);
2357756SMark.Johnson@Sun.COM mutex_destroy(&ring->ri_state.rs_mutex);
2367756SMark.Johnson@Sun.COM mutex_destroy(&ring->ri_mutex);
2377756SMark.Johnson@Sun.COM kmem_free(ring, sizeof (struct blk_ring_s));
2387756SMark.Johnson@Sun.COM return (DDI_FAILURE);
2397756SMark.Johnson@Sun.COM }
2407756SMark.Johnson@Sun.COM
2417756SMark.Johnson@Sun.COM
2427756SMark.Johnson@Sun.COM /*
2437756SMark.Johnson@Sun.COM * blk_ring_fini()
2447756SMark.Johnson@Sun.COM */
2457756SMark.Johnson@Sun.COM void
blk_ring_fini(blk_ring_t * ringp)2467756SMark.Johnson@Sun.COM blk_ring_fini(blk_ring_t *ringp)
2477756SMark.Johnson@Sun.COM {
2487756SMark.Johnson@Sun.COM blk_ring_t ring;
2497756SMark.Johnson@Sun.COM
2507756SMark.Johnson@Sun.COM
2517756SMark.Johnson@Sun.COM ring = *ringp;
2527756SMark.Johnson@Sun.COM
2537756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
2547756SMark.Johnson@Sun.COM if (ring->ri_if_status != BLK_IF_DISCONNECTED) {
2557756SMark.Johnson@Sun.COM blk_ring_close(ring);
2567756SMark.Johnson@Sun.COM }
2577756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
2587756SMark.Johnson@Sun.COM
2597756SMark.Johnson@Sun.COM xvdi_remove_event_handler(ring->ri_dip, NULL);
2607756SMark.Johnson@Sun.COM blk_kstat_fini(ring);
2617756SMark.Johnson@Sun.COM cv_destroy(&ring->ri_state.rs_cv);
2627756SMark.Johnson@Sun.COM mutex_destroy(&ring->ri_state.rs_mutex);
2637756SMark.Johnson@Sun.COM mutex_destroy(&ring->ri_mutex);
2647756SMark.Johnson@Sun.COM kmem_free(ring, sizeof (struct blk_ring_s));
2657756SMark.Johnson@Sun.COM
2667756SMark.Johnson@Sun.COM *ringp = NULL;
2677756SMark.Johnson@Sun.COM }
2687756SMark.Johnson@Sun.COM
2697756SMark.Johnson@Sun.COM
2707756SMark.Johnson@Sun.COM /*
2717756SMark.Johnson@Sun.COM * blk_kstat_init()
2727756SMark.Johnson@Sun.COM */
2737756SMark.Johnson@Sun.COM static int
blk_kstat_init(blk_ring_t ring)2747756SMark.Johnson@Sun.COM blk_kstat_init(blk_ring_t ring)
2757756SMark.Johnson@Sun.COM {
2767756SMark.Johnson@Sun.COM int nstat = sizeof (blk_stats) / sizeof (blk_stats[0]);
2777756SMark.Johnson@Sun.COM char **cp = blk_stats;
2787756SMark.Johnson@Sun.COM kstat_named_t *knp;
2797756SMark.Johnson@Sun.COM
2807756SMark.Johnson@Sun.COM ring->ri_kstats = kstat_create(ddi_get_name(ring->ri_dip),
2817756SMark.Johnson@Sun.COM ddi_get_instance(ring->ri_dip), "req_statistics", "block",
2827756SMark.Johnson@Sun.COM KSTAT_TYPE_NAMED, nstat, 0);
2837756SMark.Johnson@Sun.COM if (ring->ri_kstats == NULL) {
2847756SMark.Johnson@Sun.COM return (DDI_FAILURE);
2857756SMark.Johnson@Sun.COM }
2867756SMark.Johnson@Sun.COM
2877756SMark.Johnson@Sun.COM ring->ri_kstats->ks_private = ring;
2887756SMark.Johnson@Sun.COM ring->ri_kstats->ks_update = blk_kstat_update;
2897756SMark.Johnson@Sun.COM
2907756SMark.Johnson@Sun.COM knp = ring->ri_kstats->ks_data;
2917756SMark.Johnson@Sun.COM while (nstat > 0) {
2927756SMark.Johnson@Sun.COM kstat_named_init(knp, *cp, KSTAT_DATA_UINT64);
2937756SMark.Johnson@Sun.COM knp++;
2947756SMark.Johnson@Sun.COM cp++;
2957756SMark.Johnson@Sun.COM nstat--;
2967756SMark.Johnson@Sun.COM }
2977756SMark.Johnson@Sun.COM
2987756SMark.Johnson@Sun.COM kstat_install(ring->ri_kstats);
2997756SMark.Johnson@Sun.COM
3007756SMark.Johnson@Sun.COM return (DDI_SUCCESS);
3017756SMark.Johnson@Sun.COM }
3027756SMark.Johnson@Sun.COM
3037756SMark.Johnson@Sun.COM
3047756SMark.Johnson@Sun.COM /*
3057756SMark.Johnson@Sun.COM * blk_kstat_fini()
3067756SMark.Johnson@Sun.COM */
3077756SMark.Johnson@Sun.COM static void
blk_kstat_fini(blk_ring_t ring)3087756SMark.Johnson@Sun.COM blk_kstat_fini(blk_ring_t ring)
3097756SMark.Johnson@Sun.COM {
3107756SMark.Johnson@Sun.COM kstat_delete(ring->ri_kstats);
3117756SMark.Johnson@Sun.COM }
3127756SMark.Johnson@Sun.COM
3137756SMark.Johnson@Sun.COM
3147756SMark.Johnson@Sun.COM /*
3157756SMark.Johnson@Sun.COM * blk_kstat_update()
3167756SMark.Johnson@Sun.COM */
3177756SMark.Johnson@Sun.COM static int
blk_kstat_update(kstat_t * ksp,int flag)3187756SMark.Johnson@Sun.COM blk_kstat_update(kstat_t *ksp, int flag)
3197756SMark.Johnson@Sun.COM {
3207756SMark.Johnson@Sun.COM kstat_named_t *knp;
3217756SMark.Johnson@Sun.COM blk_stats_t *stats;
3227756SMark.Johnson@Sun.COM blk_ring_t ring;
3237756SMark.Johnson@Sun.COM
3247756SMark.Johnson@Sun.COM
3257756SMark.Johnson@Sun.COM if (flag != KSTAT_READ) {
3267756SMark.Johnson@Sun.COM return (EACCES);
3277756SMark.Johnson@Sun.COM }
3287756SMark.Johnson@Sun.COM
3297756SMark.Johnson@Sun.COM ring = ksp->ks_private;
3307756SMark.Johnson@Sun.COM stats = &ring->ri_stats;
3317756SMark.Johnson@Sun.COM knp = ksp->ks_data;
3327756SMark.Johnson@Sun.COM
3337756SMark.Johnson@Sun.COM /*
3347756SMark.Johnson@Sun.COM * Assignment order should match that of the names in
3357756SMark.Johnson@Sun.COM * blk_stats.
3367756SMark.Johnson@Sun.COM */
3377756SMark.Johnson@Sun.COM (knp++)->value.ui64 = stats->bs_req_reads;
3387756SMark.Johnson@Sun.COM (knp++)->value.ui64 = stats->bs_req_writes;
3397756SMark.Johnson@Sun.COM (knp++)->value.ui64 = stats->bs_req_barriers;
3407756SMark.Johnson@Sun.COM (knp++)->value.ui64 = stats->bs_req_flushes;
3417756SMark.Johnson@Sun.COM (knp++)->value.ui64 = 0; /* oo_req */
3427756SMark.Johnson@Sun.COM
3437756SMark.Johnson@Sun.COM return (0);
3447756SMark.Johnson@Sun.COM }
3457756SMark.Johnson@Sun.COM
3467756SMark.Johnson@Sun.COM
3477756SMark.Johnson@Sun.COM /*
3487756SMark.Johnson@Sun.COM * blk_oe_state_change()
3497756SMark.Johnson@Sun.COM */
3507756SMark.Johnson@Sun.COM /*ARGSUSED*/
3517756SMark.Johnson@Sun.COM static void
blk_oe_state_change(dev_info_t * dip,ddi_eventcookie_t id,void * arg,void * impl_data)3527756SMark.Johnson@Sun.COM blk_oe_state_change(dev_info_t *dip, ddi_eventcookie_t id, void *arg,
3537756SMark.Johnson@Sun.COM void *impl_data)
3547756SMark.Johnson@Sun.COM {
3557756SMark.Johnson@Sun.COM XenbusState new_state;
3567756SMark.Johnson@Sun.COM blk_ring_t ring;
3577756SMark.Johnson@Sun.COM
3587756SMark.Johnson@Sun.COM
3597756SMark.Johnson@Sun.COM ring = (blk_ring_t)arg;
3607756SMark.Johnson@Sun.COM new_state = *(XenbusState *)impl_data;
3617756SMark.Johnson@Sun.COM
3627756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
3637756SMark.Johnson@Sun.COM
3647756SMark.Johnson@Sun.COM if (blk_check_state_transition(ring, new_state) == DDI_FAILURE) {
3657756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
3667756SMark.Johnson@Sun.COM return;
3677756SMark.Johnson@Sun.COM }
3687756SMark.Johnson@Sun.COM
3697756SMark.Johnson@Sun.COM switch (new_state) {
3707756SMark.Johnson@Sun.COM case XenbusStateInitialised:
3717756SMark.Johnson@Sun.COM ASSERT(ring->ri_if_status == BLK_IF_UNKNOWN);
3727756SMark.Johnson@Sun.COM
3737756SMark.Johnson@Sun.COM /* frontend is ready for connecting */
3747756SMark.Johnson@Sun.COM ring->ri_fe_status = BLK_FE_READY;
3757756SMark.Johnson@Sun.COM
3767756SMark.Johnson@Sun.COM if (ring->ri_be_status == BLK_BE_READY) {
3777756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
3787756SMark.Johnson@Sun.COM if (blk_start_connect(ring) != DDI_SUCCESS)
3797756SMark.Johnson@Sun.COM (void) blk_start_disconnect(ring);
3807756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
3817756SMark.Johnson@Sun.COM }
3827756SMark.Johnson@Sun.COM break;
3837756SMark.Johnson@Sun.COM case XenbusStateClosing:
3847756SMark.Johnson@Sun.COM (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosing);
3857756SMark.Johnson@Sun.COM break;
3867756SMark.Johnson@Sun.COM case XenbusStateClosed:
3877756SMark.Johnson@Sun.COM /* clean up */
3887756SMark.Johnson@Sun.COM (void) xvdi_post_event(ring->ri_dip, XEN_HP_REMOVE);
3897756SMark.Johnson@Sun.COM if (ring->ri_ringdown != NULL) {
3907756SMark.Johnson@Sun.COM (*(ring->ri_ringdown))(ring->ri_ringdown_arg);
3917756SMark.Johnson@Sun.COM }
3927756SMark.Johnson@Sun.COM blk_ring_close(ring);
3937756SMark.Johnson@Sun.COM
3947756SMark.Johnson@Sun.COM /* reset state in case of reconnect */
3957756SMark.Johnson@Sun.COM ring->ri_if_status = BLK_IF_UNKNOWN;
3967756SMark.Johnson@Sun.COM ring->ri_be_status = BLK_BE_UNKNOWN;
3977756SMark.Johnson@Sun.COM ring->ri_fe_status = BLK_FE_UNKNOWN;
3987756SMark.Johnson@Sun.COM ring->ri_state.rs_sleeping_on_ring = B_FALSE;
3997756SMark.Johnson@Sun.COM ring->ri_state.rs_ring_up = B_FALSE;
4007756SMark.Johnson@Sun.COM
4017756SMark.Johnson@Sun.COM break;
4027756SMark.Johnson@Sun.COM default:
4037756SMark.Johnson@Sun.COM ASSERT(0);
4047756SMark.Johnson@Sun.COM }
4057756SMark.Johnson@Sun.COM
4067756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
4077756SMark.Johnson@Sun.COM }
4087756SMark.Johnson@Sun.COM
4097756SMark.Johnson@Sun.COM
4107756SMark.Johnson@Sun.COM /*
4117756SMark.Johnson@Sun.COM * blk_hp_state_change()
4127756SMark.Johnson@Sun.COM */
4137756SMark.Johnson@Sun.COM /*ARGSUSED*/
4147756SMark.Johnson@Sun.COM static void
blk_hp_state_change(dev_info_t * dip,ddi_eventcookie_t id,void * arg,void * impl_data)4157756SMark.Johnson@Sun.COM blk_hp_state_change(dev_info_t *dip, ddi_eventcookie_t id, void *arg,
4167756SMark.Johnson@Sun.COM void *impl_data)
4177756SMark.Johnson@Sun.COM {
4187756SMark.Johnson@Sun.COM xendev_hotplug_state_t hpstate;
4197756SMark.Johnson@Sun.COM blk_ring_t ring;
4207756SMark.Johnson@Sun.COM
4217756SMark.Johnson@Sun.COM
4227756SMark.Johnson@Sun.COM ring = (blk_ring_t)arg;
4237756SMark.Johnson@Sun.COM hpstate = *(xendev_hotplug_state_t *)impl_data;
4247756SMark.Johnson@Sun.COM
4257756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
4267756SMark.Johnson@Sun.COM if (hpstate == Connected) {
4277756SMark.Johnson@Sun.COM /* Hotplug script has completed successfully */
4287756SMark.Johnson@Sun.COM if (ring->ri_be_status == BLK_BE_UNKNOWN) {
4297756SMark.Johnson@Sun.COM ring->ri_be_status = BLK_BE_READY;
4307756SMark.Johnson@Sun.COM if (ring->ri_fe_status == BLK_FE_READY) {
4317756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
4327756SMark.Johnson@Sun.COM /* try to connect to frontend */
4337756SMark.Johnson@Sun.COM if (blk_start_connect(ring) != DDI_SUCCESS)
4347756SMark.Johnson@Sun.COM (void) blk_start_disconnect(ring);
4357756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
4367756SMark.Johnson@Sun.COM }
4377756SMark.Johnson@Sun.COM }
4387756SMark.Johnson@Sun.COM }
4397756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
4407756SMark.Johnson@Sun.COM }
4417756SMark.Johnson@Sun.COM
4427756SMark.Johnson@Sun.COM
4437756SMark.Johnson@Sun.COM /*
4447756SMark.Johnson@Sun.COM * blk_check_state_transition()
4457756SMark.Johnson@Sun.COM * check the XenbusState change to see if the change is a valid transition
4467756SMark.Johnson@Sun.COM * or not. The new state is written by frontend domain, or by running
4477756SMark.Johnson@Sun.COM * xenstore-write to change it manually in dom0.
4487756SMark.Johnson@Sun.COM */
4497756SMark.Johnson@Sun.COM static int
blk_check_state_transition(blk_ring_t ring,XenbusState oestate)4507756SMark.Johnson@Sun.COM blk_check_state_transition(blk_ring_t ring, XenbusState oestate)
4517756SMark.Johnson@Sun.COM {
4527756SMark.Johnson@Sun.COM switch (ring->ri_if_status) {
4537756SMark.Johnson@Sun.COM case BLK_IF_UNKNOWN:
4547756SMark.Johnson@Sun.COM if (ring->ri_fe_status == BLK_FE_UNKNOWN) {
4557756SMark.Johnson@Sun.COM if ((oestate == XenbusStateUnknown) ||
4567756SMark.Johnson@Sun.COM (oestate == XenbusStateConnected))
4577756SMark.Johnson@Sun.COM goto statechkfail_bug;
4587756SMark.Johnson@Sun.COM else if ((oestate == XenbusStateInitialising) ||
4597756SMark.Johnson@Sun.COM (oestate == XenbusStateInitWait))
4607756SMark.Johnson@Sun.COM goto statechkfail_nop;
4617756SMark.Johnson@Sun.COM } else {
4627756SMark.Johnson@Sun.COM if ((oestate == XenbusStateUnknown) ||
4637756SMark.Johnson@Sun.COM (oestate == XenbusStateInitialising) ||
4647756SMark.Johnson@Sun.COM (oestate == XenbusStateInitWait) ||
4657756SMark.Johnson@Sun.COM (oestate == XenbusStateConnected))
4667756SMark.Johnson@Sun.COM goto statechkfail_bug;
4677756SMark.Johnson@Sun.COM else if (oestate == XenbusStateInitialised)
4687756SMark.Johnson@Sun.COM goto statechkfail_nop;
4697756SMark.Johnson@Sun.COM }
4707756SMark.Johnson@Sun.COM break;
4717756SMark.Johnson@Sun.COM
4727756SMark.Johnson@Sun.COM case BLK_IF_CONNECTED:
4737756SMark.Johnson@Sun.COM if ((oestate == XenbusStateUnknown) ||
4747756SMark.Johnson@Sun.COM (oestate == XenbusStateInitialising) ||
4757756SMark.Johnson@Sun.COM (oestate == XenbusStateInitWait) ||
4767756SMark.Johnson@Sun.COM (oestate == XenbusStateInitialised))
4777756SMark.Johnson@Sun.COM goto statechkfail_bug;
4787756SMark.Johnson@Sun.COM else if (oestate == XenbusStateConnected)
4797756SMark.Johnson@Sun.COM goto statechkfail_nop;
4807756SMark.Johnson@Sun.COM break;
4817756SMark.Johnson@Sun.COM
4827756SMark.Johnson@Sun.COM case BLK_IF_DISCONNECTED:
4837756SMark.Johnson@Sun.COM default:
4847756SMark.Johnson@Sun.COM goto statechkfail_bug;
4857756SMark.Johnson@Sun.COM }
4867756SMark.Johnson@Sun.COM
4877756SMark.Johnson@Sun.COM return (DDI_SUCCESS);
4887756SMark.Johnson@Sun.COM
4897756SMark.Johnson@Sun.COM statechkfail_bug:
4907756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, "blk@%s: unexpected otherend "
4917756SMark.Johnson@Sun.COM "state change to %d!, when status is %d",
4927756SMark.Johnson@Sun.COM ddi_get_name_addr(ring->ri_dip), oestate,
4937756SMark.Johnson@Sun.COM ring->ri_if_status);
4947756SMark.Johnson@Sun.COM
4957756SMark.Johnson@Sun.COM statechkfail_nop:
4967756SMark.Johnson@Sun.COM return (DDI_FAILURE);
4977756SMark.Johnson@Sun.COM }
4987756SMark.Johnson@Sun.COM
4997756SMark.Johnson@Sun.COM
5007756SMark.Johnson@Sun.COM /*
5017756SMark.Johnson@Sun.COM * blk_start_connect()
5027756SMark.Johnson@Sun.COM * Kick-off connect process
5037756SMark.Johnson@Sun.COM * If ri_fe_status == BLK_FE_READY and ri_be_status == BLK_BE_READY
5047756SMark.Johnson@Sun.COM * the ri_if_status will be changed to BLK_IF_CONNECTED on success,
5057756SMark.Johnson@Sun.COM * otherwise, ri_if_status will not be changed
5067756SMark.Johnson@Sun.COM */
5077756SMark.Johnson@Sun.COM static int
blk_start_connect(blk_ring_t ring)5087756SMark.Johnson@Sun.COM blk_start_connect(blk_ring_t ring)
5097756SMark.Johnson@Sun.COM {
5107756SMark.Johnson@Sun.COM xenbus_transaction_t xbt;
5117756SMark.Johnson@Sun.COM dev_info_t *dip;
5127756SMark.Johnson@Sun.COM char *barrier;
5137756SMark.Johnson@Sun.COM char *xsnode;
5147756SMark.Johnson@Sun.COM uint_t len;
5157756SMark.Johnson@Sun.COM int e;
5167756SMark.Johnson@Sun.COM
5177756SMark.Johnson@Sun.COM
5187756SMark.Johnson@Sun.COM dip = ring->ri_dip;
5197756SMark.Johnson@Sun.COM
5207756SMark.Johnson@Sun.COM /*
5217756SMark.Johnson@Sun.COM * Start connect to frontend only when backend device are ready
5227756SMark.Johnson@Sun.COM * and frontend has moved to XenbusStateInitialised, which means
5237756SMark.Johnson@Sun.COM * ready to connect
5247756SMark.Johnson@Sun.COM */
5257756SMark.Johnson@Sun.COM ASSERT(ring->ri_fe_status == BLK_FE_READY);
5267756SMark.Johnson@Sun.COM ASSERT(ring->ri_be_status == BLK_BE_READY);
5277756SMark.Johnson@Sun.COM
5287756SMark.Johnson@Sun.COM xsnode = xvdi_get_xsname(dip);
5297756SMark.Johnson@Sun.COM if (xsnode == NULL) {
5307756SMark.Johnson@Sun.COM goto startconnectfail_get_xsname;
5317756SMark.Johnson@Sun.COM }
5327756SMark.Johnson@Sun.COM
5337756SMark.Johnson@Sun.COM ring->ri_fe = xvdi_get_oeid(dip);
5347756SMark.Johnson@Sun.COM if (ring->ri_fe == (domid_t)-1) {
5357756SMark.Johnson@Sun.COM goto startconnectfail_get_oeid;
5367756SMark.Johnson@Sun.COM }
5377756SMark.Johnson@Sun.COM
5387756SMark.Johnson@Sun.COM e = xvdi_switch_state(dip, XBT_NULL, XenbusStateInitialised);
5397756SMark.Johnson@Sun.COM if (e > 0) {
5407756SMark.Johnson@Sun.COM goto startconnectfail_switch_init;
5417756SMark.Johnson@Sun.COM }
5427756SMark.Johnson@Sun.COM
5437756SMark.Johnson@Sun.COM e = blk_bindto_frontend(ring);
5447756SMark.Johnson@Sun.COM if (e != DDI_SUCCESS) {
5457756SMark.Johnson@Sun.COM goto startconnectfail_bindto_frontend;
5467756SMark.Johnson@Sun.COM }
5477756SMark.Johnson@Sun.COM ring->ri_if_status = BLK_IF_CONNECTED;
5487756SMark.Johnson@Sun.COM
5497756SMark.Johnson@Sun.COM e = ddi_add_intr(dip, 0, NULL, NULL, blk_intr, (caddr_t)ring);
5507756SMark.Johnson@Sun.COM if (e != DDI_SUCCESS) {
5517756SMark.Johnson@Sun.COM goto startconnectfail_add_intr;
5527756SMark.Johnson@Sun.COM }
5537756SMark.Johnson@Sun.COM
5547756SMark.Johnson@Sun.COM trans_retry:
5557756SMark.Johnson@Sun.COM e = xenbus_transaction_start(&xbt);
5567756SMark.Johnson@Sun.COM if (e != 0) {
5577756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "transaction start");
5587756SMark.Johnson@Sun.COM goto startconnectfail_transaction_start;
5597756SMark.Johnson@Sun.COM }
5607756SMark.Johnson@Sun.COM
561*10581SMark.Johnson@Sun.COM /* xentop requires the instance in xenstore */
562*10581SMark.Johnson@Sun.COM e = xenbus_printf(xbt, xsnode, "instance", "%d",
563*10581SMark.Johnson@Sun.COM ddi_get_instance(ring->ri_dip));
564*10581SMark.Johnson@Sun.COM if (e != 0) {
565*10581SMark.Johnson@Sun.COM cmn_err(CE_WARN, "xdb@%s: failed to write 'instance'",
566*10581SMark.Johnson@Sun.COM ddi_get_name_addr(dip));
567*10581SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "writing 'instance'");
568*10581SMark.Johnson@Sun.COM (void) xenbus_transaction_end(xbt, 1);
569*10581SMark.Johnson@Sun.COM goto startconnectfail_xenbus_printf;
570*10581SMark.Johnson@Sun.COM }
571*10581SMark.Johnson@Sun.COM
5727756SMark.Johnson@Sun.COM /* If feature-barrier isn't present in xenstore, add it */
5737756SMark.Johnson@Sun.COM e = xenbus_read(xbt, xsnode, "feature-barrier", (void **)&barrier,
5747756SMark.Johnson@Sun.COM &len);
5757756SMark.Johnson@Sun.COM if (e != 0) {
5767756SMark.Johnson@Sun.COM e = xenbus_printf(xbt, xsnode, "feature-barrier", "%d", 1);
5777756SMark.Johnson@Sun.COM if (e != 0) {
5787756SMark.Johnson@Sun.COM cmn_err(CE_WARN, "xdb@%s: failed to write "
5797756SMark.Johnson@Sun.COM "'feature-barrier'", ddi_get_name_addr(dip));
5807756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "writing 'feature-barrier'");
5817756SMark.Johnson@Sun.COM (void) xenbus_transaction_end(xbt, 1);
5827756SMark.Johnson@Sun.COM goto startconnectfail_xenbus_printf;
5837756SMark.Johnson@Sun.COM }
5847756SMark.Johnson@Sun.COM } else {
5857756SMark.Johnson@Sun.COM kmem_free(barrier, len);
5867756SMark.Johnson@Sun.COM }
5877756SMark.Johnson@Sun.COM
5887756SMark.Johnson@Sun.COM e = xvdi_switch_state(dip, xbt, XenbusStateConnected);
5897756SMark.Johnson@Sun.COM if (e > 0) {
5907756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "writing 'state'");
5917756SMark.Johnson@Sun.COM (void) xenbus_transaction_end(xbt, 1);
5927756SMark.Johnson@Sun.COM goto startconnectfail_switch_connected;
5937756SMark.Johnson@Sun.COM }
5947756SMark.Johnson@Sun.COM
5957756SMark.Johnson@Sun.COM e = xenbus_transaction_end(xbt, 0);
5967756SMark.Johnson@Sun.COM if (e != 0) {
5977756SMark.Johnson@Sun.COM if (e == EAGAIN) {
5987756SMark.Johnson@Sun.COM /* transaction is ended, don't need to abort it */
5997756SMark.Johnson@Sun.COM goto trans_retry;
6007756SMark.Johnson@Sun.COM }
6017756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "completing transaction");
6027756SMark.Johnson@Sun.COM goto startconnectfail_transaction_end;
6037756SMark.Johnson@Sun.COM }
6047756SMark.Johnson@Sun.COM
6057756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_state.rs_mutex);
6067756SMark.Johnson@Sun.COM ring->ri_state.rs_ring_up = B_TRUE;
6077756SMark.Johnson@Sun.COM if (ring->ri_state.rs_sleeping_on_ring) {
6087756SMark.Johnson@Sun.COM ring->ri_state.rs_sleeping_on_ring = B_FALSE;
6097756SMark.Johnson@Sun.COM cv_signal(&ring->ri_state.rs_cv);
6107756SMark.Johnson@Sun.COM }
6117756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_state.rs_mutex);
6127756SMark.Johnson@Sun.COM
6137756SMark.Johnson@Sun.COM if (ring->ri_ringup != NULL) {
6147756SMark.Johnson@Sun.COM (*(ring->ri_ringup))(ring->ri_ringup_arg);
6157756SMark.Johnson@Sun.COM }
6167756SMark.Johnson@Sun.COM
6177756SMark.Johnson@Sun.COM return (DDI_SUCCESS);
6187756SMark.Johnson@Sun.COM
6197756SMark.Johnson@Sun.COM
6207756SMark.Johnson@Sun.COM startconnectfail_transaction_end:
6217756SMark.Johnson@Sun.COM startconnectfail_switch_connected:
6227756SMark.Johnson@Sun.COM startconnectfail_xenbus_printf:
6237756SMark.Johnson@Sun.COM startconnectfail_transaction_start:
6247756SMark.Johnson@Sun.COM ddi_remove_intr(dip, 0, NULL);
6257756SMark.Johnson@Sun.COM startconnectfail_add_intr:
6267756SMark.Johnson@Sun.COM blk_unbindfrom_frontend(ring);
6277756SMark.Johnson@Sun.COM ring->ri_fe = (domid_t)-1;
6287756SMark.Johnson@Sun.COM startconnectfail_bindto_frontend:
6297756SMark.Johnson@Sun.COM (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosed);
6307756SMark.Johnson@Sun.COM startconnectfail_switch_init:
6317756SMark.Johnson@Sun.COM startconnectfail_get_oeid:
6327756SMark.Johnson@Sun.COM startconnectfail_get_xsname:
6337756SMark.Johnson@Sun.COM return (DDI_FAILURE);
6347756SMark.Johnson@Sun.COM }
6357756SMark.Johnson@Sun.COM
6367756SMark.Johnson@Sun.COM
6377756SMark.Johnson@Sun.COM /*
6387756SMark.Johnson@Sun.COM * blk_start_disconnect()
6397756SMark.Johnson@Sun.COM * Kick-off disconnect process. ri_if_status will not be changed
6407756SMark.Johnson@Sun.COM */
6417756SMark.Johnson@Sun.COM static void
blk_start_disconnect(blk_ring_t ring)6427756SMark.Johnson@Sun.COM blk_start_disconnect(blk_ring_t ring)
6437756SMark.Johnson@Sun.COM {
6447756SMark.Johnson@Sun.COM /* Kick-off disconnect process */
6457756SMark.Johnson@Sun.COM (void) xvdi_switch_state(ring->ri_dip, XBT_NULL, XenbusStateClosing);
6467756SMark.Johnson@Sun.COM }
6477756SMark.Johnson@Sun.COM
6487756SMark.Johnson@Sun.COM
6497756SMark.Johnson@Sun.COM /*
6507756SMark.Johnson@Sun.COM * blk_ring_close()
6517756SMark.Johnson@Sun.COM * Disconnect from frontend and close backend device
6527756SMark.Johnson@Sun.COM * ifstatus will be changed to BLK_DISCONNECTED
6537756SMark.Johnson@Sun.COM * Xenbus state will be changed to XenbusStateClosed
6547756SMark.Johnson@Sun.COM */
6557756SMark.Johnson@Sun.COM static void
blk_ring_close(blk_ring_t ring)6567756SMark.Johnson@Sun.COM blk_ring_close(blk_ring_t ring)
6577756SMark.Johnson@Sun.COM {
6587756SMark.Johnson@Sun.COM dev_info_t *dip;
6597756SMark.Johnson@Sun.COM
6607756SMark.Johnson@Sun.COM
6617756SMark.Johnson@Sun.COM /* mutex protect ri_if_status only here */
6627756SMark.Johnson@Sun.COM ASSERT(MUTEX_HELD(&ring->ri_mutex));
6637756SMark.Johnson@Sun.COM
6647756SMark.Johnson@Sun.COM dip = ring->ri_dip;
6657756SMark.Johnson@Sun.COM
6667756SMark.Johnson@Sun.COM if (ring->ri_if_status != BLK_IF_CONNECTED) {
6677756SMark.Johnson@Sun.COM return;
6687756SMark.Johnson@Sun.COM }
6697756SMark.Johnson@Sun.COM
6707756SMark.Johnson@Sun.COM ring->ri_if_status = BLK_IF_DISCONNECTED;
6717756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
6727756SMark.Johnson@Sun.COM
6737756SMark.Johnson@Sun.COM /* stop accepting I/O request from frontend */
6747756SMark.Johnson@Sun.COM ddi_remove_intr(dip, 0, NULL);
6757756SMark.Johnson@Sun.COM
6767756SMark.Johnson@Sun.COM blk_unbindfrom_frontend(ring);
6777756SMark.Johnson@Sun.COM ring->ri_fe = (domid_t)-1;
6787756SMark.Johnson@Sun.COM (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosed);
6797756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
6807756SMark.Johnson@Sun.COM }
6817756SMark.Johnson@Sun.COM
6827756SMark.Johnson@Sun.COM
6837756SMark.Johnson@Sun.COM /*
6847756SMark.Johnson@Sun.COM * blk_bindto_frontend()
6857756SMark.Johnson@Sun.COM */
6867756SMark.Johnson@Sun.COM static int
blk_bindto_frontend(blk_ring_t ring)6877756SMark.Johnson@Sun.COM blk_bindto_frontend(blk_ring_t ring)
6887756SMark.Johnson@Sun.COM {
6897756SMark.Johnson@Sun.COM evtchn_port_t evtchn;
6907756SMark.Johnson@Sun.COM char protocol[64];
6917756SMark.Johnson@Sun.COM grant_ref_t gref;
6927756SMark.Johnson@Sun.COM dev_info_t *dip;
6937756SMark.Johnson@Sun.COM char *oename;
6947756SMark.Johnson@Sun.COM int e;
6957756SMark.Johnson@Sun.COM
6967756SMark.Johnson@Sun.COM
6977756SMark.Johnson@Sun.COM dip = ring->ri_dip;
6987756SMark.Johnson@Sun.COM protocol[0] = 0x0;
6997756SMark.Johnson@Sun.COM
7007756SMark.Johnson@Sun.COM /*
7017756SMark.Johnson@Sun.COM * Gather info from frontend
7027756SMark.Johnson@Sun.COM */
7037756SMark.Johnson@Sun.COM oename = xvdi_get_oename(dip);
7047756SMark.Johnson@Sun.COM if (oename == NULL) {
7057756SMark.Johnson@Sun.COM return (DDI_FAILURE);
7067756SMark.Johnson@Sun.COM }
7077756SMark.Johnson@Sun.COM
7087756SMark.Johnson@Sun.COM e = xenbus_gather(XBT_NULL, oename, "ring-ref", "%lu", &gref,
7097756SMark.Johnson@Sun.COM "event-channel", "%u", &evtchn, NULL);
7107756SMark.Johnson@Sun.COM if (e != 0) {
7117756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e,
7127756SMark.Johnson@Sun.COM "Getting ring-ref and evtchn from frontend");
7137756SMark.Johnson@Sun.COM return (DDI_FAILURE);
7147756SMark.Johnson@Sun.COM }
7157756SMark.Johnson@Sun.COM
7167756SMark.Johnson@Sun.COM e = xenbus_gather(XBT_NULL, oename, "protocol", "%63s",
7177756SMark.Johnson@Sun.COM protocol, NULL);
7187756SMark.Johnson@Sun.COM if (e != 0) {
7197756SMark.Johnson@Sun.COM (void) strcpy(protocol, "unspecified, assuming native");
7207756SMark.Johnson@Sun.COM } else if (strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
7217756SMark.Johnson@Sun.COM ring->ri_protocol = BLKIF_PROTOCOL_NATIVE;
7227756SMark.Johnson@Sun.COM ring->ri_nentry = BLKIF_RING_SIZE;
7237756SMark.Johnson@Sun.COM ring->ri_entrysize = sizeof (union blkif_sring_entry);
7247756SMark.Johnson@Sun.COM } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
7257756SMark.Johnson@Sun.COM ring->ri_protocol = BLKIF_PROTOCOL_X86_32;
7267756SMark.Johnson@Sun.COM ring->ri_nentry = BLKIF_X86_32_RING_SIZE;
7277756SMark.Johnson@Sun.COM ring->ri_entrysize = sizeof (union blkif_x86_32_sring_entry);
7287756SMark.Johnson@Sun.COM } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
7297756SMark.Johnson@Sun.COM ring->ri_protocol = BLKIF_PROTOCOL_X86_64;
7307756SMark.Johnson@Sun.COM ring->ri_nentry = BLKIF_X86_64_RING_SIZE;
7317756SMark.Johnson@Sun.COM ring->ri_entrysize = sizeof (union blkif_x86_64_sring_entry);
7327756SMark.Johnson@Sun.COM } else {
7337756SMark.Johnson@Sun.COM xvdi_fatal_error(dip, e, "unknown fe protocol");
7347756SMark.Johnson@Sun.COM return (DDI_FAILURE);
7357756SMark.Johnson@Sun.COM }
7367756SMark.Johnson@Sun.COM
7377756SMark.Johnson@Sun.COM /*
7387756SMark.Johnson@Sun.COM * map and init ring
7397756SMark.Johnson@Sun.COM */
7407756SMark.Johnson@Sun.COM e = xvdi_map_ring(dip, ring->ri_nentry, ring->ri_entrysize, gref,
7417756SMark.Johnson@Sun.COM &ring->ri_ring);
7427756SMark.Johnson@Sun.COM if (e != DDI_SUCCESS) {
7437756SMark.Johnson@Sun.COM return (DDI_FAILURE);
7447756SMark.Johnson@Sun.COM }
7457756SMark.Johnson@Sun.COM
7467756SMark.Johnson@Sun.COM /*
7477756SMark.Johnson@Sun.COM * bind event channel
7487756SMark.Johnson@Sun.COM */
7497756SMark.Johnson@Sun.COM e = xvdi_bind_evtchn(dip, evtchn);
7507756SMark.Johnson@Sun.COM if (e != DDI_SUCCESS) {
7517756SMark.Johnson@Sun.COM xvdi_unmap_ring(ring->ri_ring);
7527756SMark.Johnson@Sun.COM return (DDI_FAILURE);
7537756SMark.Johnson@Sun.COM }
7547756SMark.Johnson@Sun.COM
7557756SMark.Johnson@Sun.COM
7567756SMark.Johnson@Sun.COM return (DDI_SUCCESS);
7577756SMark.Johnson@Sun.COM }
7587756SMark.Johnson@Sun.COM
7597756SMark.Johnson@Sun.COM
7607756SMark.Johnson@Sun.COM /*
7617756SMark.Johnson@Sun.COM * blk_unbindfrom_frontend()
7627756SMark.Johnson@Sun.COM */
7637756SMark.Johnson@Sun.COM static void
blk_unbindfrom_frontend(blk_ring_t ring)7647756SMark.Johnson@Sun.COM blk_unbindfrom_frontend(blk_ring_t ring)
7657756SMark.Johnson@Sun.COM {
7667756SMark.Johnson@Sun.COM xvdi_free_evtchn(ring->ri_dip);
7677756SMark.Johnson@Sun.COM xvdi_unmap_ring(ring->ri_ring);
7687756SMark.Johnson@Sun.COM }
7697756SMark.Johnson@Sun.COM
7707756SMark.Johnson@Sun.COM
7717756SMark.Johnson@Sun.COM /*
7727756SMark.Johnson@Sun.COM * blk_intr()
7737756SMark.Johnson@Sun.COM */
7747756SMark.Johnson@Sun.COM static uint_t
blk_intr(caddr_t arg)7757756SMark.Johnson@Sun.COM blk_intr(caddr_t arg)
7767756SMark.Johnson@Sun.COM {
7777756SMark.Johnson@Sun.COM blk_ring_t ring;
7787756SMark.Johnson@Sun.COM
7797756SMark.Johnson@Sun.COM ring = (blk_ring_t)arg;
7807756SMark.Johnson@Sun.COM if (ring->ri_if_status != BLK_IF_CONNECTED) {
7817756SMark.Johnson@Sun.COM return (DDI_INTR_CLAIMED);
7827756SMark.Johnson@Sun.COM }
7837756SMark.Johnson@Sun.COM
7847756SMark.Johnson@Sun.COM (void) (*ring->ri_intr)(ring->ri_intr_arg);
7857756SMark.Johnson@Sun.COM return (DDI_INTR_CLAIMED);
7867756SMark.Johnson@Sun.COM }
7877756SMark.Johnson@Sun.COM
7887756SMark.Johnson@Sun.COM
7897756SMark.Johnson@Sun.COM /*
7907756SMark.Johnson@Sun.COM * blk_ring_request_get()
7917756SMark.Johnson@Sun.COM */
7927756SMark.Johnson@Sun.COM boolean_t
blk_ring_request_get(blk_ring_t ring,blkif_request_t * req)7937756SMark.Johnson@Sun.COM blk_ring_request_get(blk_ring_t ring, blkif_request_t *req)
7947756SMark.Johnson@Sun.COM {
7957756SMark.Johnson@Sun.COM blkif_request_t *src;
7967756SMark.Johnson@Sun.COM blk_stats_t *stats;
7977756SMark.Johnson@Sun.COM
7987756SMark.Johnson@Sun.COM
7997756SMark.Johnson@Sun.COM mutex_enter(&ring->ri_mutex);
80010175SStuart.Maybee@Sun.COM
80110175SStuart.Maybee@Sun.COM if (ring->ri_if_status != BLK_IF_CONNECTED) {
80210175SStuart.Maybee@Sun.COM mutex_exit(&ring->ri_mutex);
80310175SStuart.Maybee@Sun.COM return (B_FALSE);
80410175SStuart.Maybee@Sun.COM }
80510175SStuart.Maybee@Sun.COM
8067756SMark.Johnson@Sun.COM src = xvdi_ring_get_request(ring->ri_ring);
8077756SMark.Johnson@Sun.COM if (src == NULL) {
8087756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
8097756SMark.Johnson@Sun.COM return (B_FALSE);
8107756SMark.Johnson@Sun.COM }
8117756SMark.Johnson@Sun.COM
8127756SMark.Johnson@Sun.COM switch (ring->ri_protocol) {
8137756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_NATIVE:
8147756SMark.Johnson@Sun.COM bcopy(src, req, sizeof (*req));
8157756SMark.Johnson@Sun.COM break;
8167756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_X86_32:
8177756SMark.Johnson@Sun.COM blk_ring_request_32(req, (blkif_x86_32_request_t *)src);
8187756SMark.Johnson@Sun.COM break;
8197756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_X86_64:
8207756SMark.Johnson@Sun.COM blk_ring_request_64(req, (blkif_x86_64_request_t *)src);
8217756SMark.Johnson@Sun.COM break;
8227756SMark.Johnson@Sun.COM default:
8237756SMark.Johnson@Sun.COM cmn_err(CE_WARN, "blkif@%s: unrecognised protocol: %d",
8247756SMark.Johnson@Sun.COM ddi_get_name_addr(ring->ri_dip),
8257756SMark.Johnson@Sun.COM ring->ri_protocol);
8267756SMark.Johnson@Sun.COM }
8277756SMark.Johnson@Sun.COM mutex_exit(&ring->ri_mutex);
8287756SMark.Johnson@Sun.COM
8297756SMark.Johnson@Sun.COM stats = &ring->ri_stats;
8307756SMark.Johnson@Sun.COM switch (req->operation) {
8317756SMark.Johnson@Sun.COM case BLKIF_OP_READ:
8327756SMark.Johnson@Sun.COM stats->bs_req_reads++;
8337756SMark.Johnson@Sun.COM break;
8347756SMark.Johnson@Sun.COM case BLKIF_OP_WRITE:
8357756SMark.Johnson@Sun.COM stats->bs_req_writes++;
8367756SMark.Johnson@Sun.COM break;
8377756SMark.Johnson@Sun.COM case BLKIF_OP_WRITE_BARRIER:
8387756SMark.Johnson@Sun.COM stats->bs_req_barriers++;
8397756SMark.Johnson@Sun.COM break;
8407756SMark.Johnson@Sun.COM case BLKIF_OP_FLUSH_DISKCACHE:
8417756SMark.Johnson@Sun.COM stats->bs_req_flushes++;
8427756SMark.Johnson@Sun.COM break;
8437756SMark.Johnson@Sun.COM }
8447756SMark.Johnson@Sun.COM
8457756SMark.Johnson@Sun.COM return (B_TRUE);
8467756SMark.Johnson@Sun.COM }
8477756SMark.Johnson@Sun.COM
8487756SMark.Johnson@Sun.COM
8497756SMark.Johnson@Sun.COM /*
8507756SMark.Johnson@Sun.COM * blk_ring_request_requeue()
8517756SMark.Johnson@Sun.COM * if a request is requeued, caller will have to poll for request
8527756SMark.Johnson@Sun.COM * later.
8537756SMark.Johnson@Sun.COM */
8547756SMark.Johnson@Sun.COM void
blk_ring_request_requeue(blk_ring_t ring)8557756SMark.Johnson@Sun.COM blk_ring_request_requeue(blk_ring_t ring)
8567756SMark.Johnson@Sun.COM {
85710175SStuart.Maybee@Sun.COM mutex_enter(&ring->ri_mutex);
85810175SStuart.Maybee@Sun.COM
85910175SStuart.Maybee@Sun.COM if (ring->ri_if_status != BLK_IF_CONNECTED) {
86010175SStuart.Maybee@Sun.COM mutex_exit(&ring->ri_mutex);
86110175SStuart.Maybee@Sun.COM return;
86210175SStuart.Maybee@Sun.COM }
86310175SStuart.Maybee@Sun.COM
8647756SMark.Johnson@Sun.COM ring->ri_ring->xr_sring.br.req_cons--;
86510175SStuart.Maybee@Sun.COM
86610175SStuart.Maybee@Sun.COM mutex_exit(&ring->ri_mutex);
8677756SMark.Johnson@Sun.COM }
8687756SMark.Johnson@Sun.COM
8697756SMark.Johnson@Sun.COM
8707756SMark.Johnson@Sun.COM /*
8717756SMark.Johnson@Sun.COM * blk_ring_response_put()
8727756SMark.Johnson@Sun.COM */
8737756SMark.Johnson@Sun.COM void
blk_ring_response_put(blk_ring_t ring,blkif_response_t * src)8747756SMark.Johnson@Sun.COM blk_ring_response_put(blk_ring_t ring, blkif_response_t *src)
8757756SMark.Johnson@Sun.COM {
87610175SStuart.Maybee@Sun.COM blkif_response_t *rsp;
8777756SMark.Johnson@Sun.COM int e;
8787756SMark.Johnson@Sun.COM
87910175SStuart.Maybee@Sun.COM
88010175SStuart.Maybee@Sun.COM mutex_enter(&ring->ri_mutex);
88110175SStuart.Maybee@Sun.COM
88210175SStuart.Maybee@Sun.COM if (ring->ri_if_status != BLK_IF_CONNECTED) {
88310175SStuart.Maybee@Sun.COM mutex_exit(&ring->ri_mutex);
88410175SStuart.Maybee@Sun.COM return;
88510175SStuart.Maybee@Sun.COM }
88610175SStuart.Maybee@Sun.COM
88710175SStuart.Maybee@Sun.COM rsp = xvdi_ring_get_response(ring->ri_ring);
8887756SMark.Johnson@Sun.COM ASSERT(rsp);
8897756SMark.Johnson@Sun.COM
8907756SMark.Johnson@Sun.COM switch (ring->ri_protocol) {
8917756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_NATIVE:
8927756SMark.Johnson@Sun.COM bcopy(src, rsp, sizeof (*rsp));
8937756SMark.Johnson@Sun.COM break;
8947756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_X86_32:
8957756SMark.Johnson@Sun.COM blk_ring_response_32((blkif_x86_32_response_t *)rsp, src);
8967756SMark.Johnson@Sun.COM break;
8977756SMark.Johnson@Sun.COM case BLKIF_PROTOCOL_X86_64:
8987756SMark.Johnson@Sun.COM blk_ring_response_64((blkif_x86_64_response_t *)rsp, src);
8997756SMark.Johnson@Sun.COM break;
9007756SMark.Johnson@Sun.COM default:
9017756SMark.Johnson@Sun.COM cmn_err(CE_WARN, "blk@%s: unrecognised protocol: %d",
9027756SMark.Johnson@Sun.COM ddi_get_name_addr(ring->ri_dip),
9037756SMark.Johnson@Sun.COM ring->ri_protocol);
9047756SMark.Johnson@Sun.COM }
9057756SMark.Johnson@Sun.COM
9067756SMark.Johnson@Sun.COM e = xvdi_ring_push_response(ring->ri_ring);
9077756SMark.Johnson@Sun.COM if (e != 0) {
9087756SMark.Johnson@Sun.COM xvdi_notify_oe(ring->ri_dip);
9097756SMark.Johnson@Sun.COM }
91010175SStuart.Maybee@Sun.COM
91110175SStuart.Maybee@Sun.COM mutex_exit(&ring->ri_mutex);
9127756SMark.Johnson@Sun.COM }
9137756SMark.Johnson@Sun.COM
9147756SMark.Johnson@Sun.COM
9157756SMark.Johnson@Sun.COM /*
9167756SMark.Johnson@Sun.COM * blk_ring_request_32()
9177756SMark.Johnson@Sun.COM */
9187756SMark.Johnson@Sun.COM static void
blk_ring_request_32(blkif_request_t * dst,blkif_x86_32_request_t * src)9197756SMark.Johnson@Sun.COM blk_ring_request_32(blkif_request_t *dst, blkif_x86_32_request_t *src)
9207756SMark.Johnson@Sun.COM {
9217756SMark.Johnson@Sun.COM int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
9227756SMark.Johnson@Sun.COM dst->operation = src->operation;
9237756SMark.Johnson@Sun.COM dst->nr_segments = src->nr_segments;
9247756SMark.Johnson@Sun.COM dst->handle = src->handle;
9257756SMark.Johnson@Sun.COM dst->id = src->id;
9267756SMark.Johnson@Sun.COM dst->sector_number = src->sector_number;
9277756SMark.Johnson@Sun.COM if (n > src->nr_segments)
9287756SMark.Johnson@Sun.COM n = src->nr_segments;
9297756SMark.Johnson@Sun.COM for (i = 0; i < n; i++)
9307756SMark.Johnson@Sun.COM dst->seg[i] = src->seg[i];
9317756SMark.Johnson@Sun.COM }
9327756SMark.Johnson@Sun.COM
9337756SMark.Johnson@Sun.COM
9347756SMark.Johnson@Sun.COM /*
9357756SMark.Johnson@Sun.COM * blk_ring_request_64()
9367756SMark.Johnson@Sun.COM */
9377756SMark.Johnson@Sun.COM static void
blk_ring_request_64(blkif_request_t * dst,blkif_x86_64_request_t * src)9387756SMark.Johnson@Sun.COM blk_ring_request_64(blkif_request_t *dst, blkif_x86_64_request_t *src)
9397756SMark.Johnson@Sun.COM {
9407756SMark.Johnson@Sun.COM int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
9417756SMark.Johnson@Sun.COM dst->operation = src->operation;
9427756SMark.Johnson@Sun.COM dst->nr_segments = src->nr_segments;
9437756SMark.Johnson@Sun.COM dst->handle = src->handle;
9447756SMark.Johnson@Sun.COM dst->id = src->id;
9457756SMark.Johnson@Sun.COM dst->sector_number = src->sector_number;
9467756SMark.Johnson@Sun.COM if (n > src->nr_segments)
9477756SMark.Johnson@Sun.COM n = src->nr_segments;
9487756SMark.Johnson@Sun.COM for (i = 0; i < n; i++)
9497756SMark.Johnson@Sun.COM dst->seg[i] = src->seg[i];
9507756SMark.Johnson@Sun.COM }
9517756SMark.Johnson@Sun.COM
9527756SMark.Johnson@Sun.COM
9537756SMark.Johnson@Sun.COM /*
9547756SMark.Johnson@Sun.COM * blk_ring_response_32()
9557756SMark.Johnson@Sun.COM */
9567756SMark.Johnson@Sun.COM static void
blk_ring_response_32(blkif_x86_32_response_t * dst,blkif_response_t * src)9577756SMark.Johnson@Sun.COM blk_ring_response_32(blkif_x86_32_response_t *dst, blkif_response_t *src)
9587756SMark.Johnson@Sun.COM {
9597756SMark.Johnson@Sun.COM dst->id = src->id;
9607756SMark.Johnson@Sun.COM dst->operation = src->operation;
9617756SMark.Johnson@Sun.COM dst->status = src->status;
9627756SMark.Johnson@Sun.COM }
9637756SMark.Johnson@Sun.COM
9647756SMark.Johnson@Sun.COM
9657756SMark.Johnson@Sun.COM /*
9667756SMark.Johnson@Sun.COM * blk_ring_response_64()
9677756SMark.Johnson@Sun.COM */
9687756SMark.Johnson@Sun.COM static void
blk_ring_response_64(blkif_x86_64_response_t * dst,blkif_response_t * src)9697756SMark.Johnson@Sun.COM blk_ring_response_64(blkif_x86_64_response_t *dst, blkif_response_t *src)
9707756SMark.Johnson@Sun.COM {
9717756SMark.Johnson@Sun.COM dst->id = src->id;
9727756SMark.Johnson@Sun.COM dst->operation = src->operation;
9737756SMark.Johnson@Sun.COM dst->status = src->status;
9747756SMark.Johnson@Sun.COM }
9757756SMark.Johnson@Sun.COM
9767756SMark.Johnson@Sun.COM
9777756SMark.Johnson@Sun.COM /*
9787756SMark.Johnson@Sun.COM * blk_ring_request_dump()
9797756SMark.Johnson@Sun.COM */
9807756SMark.Johnson@Sun.COM void
blk_ring_request_dump(blkif_request_t * req)9817756SMark.Johnson@Sun.COM blk_ring_request_dump(blkif_request_t *req)
9827756SMark.Johnson@Sun.COM {
9837756SMark.Johnson@Sun.COM int i;
9847756SMark.Johnson@Sun.COM
9857756SMark.Johnson@Sun.COM /*
9867756SMark.Johnson@Sun.COM * Exploit the public interface definitions for BLKIF_OP_READ
9877756SMark.Johnson@Sun.COM * etc..
9887756SMark.Johnson@Sun.COM */
9897756SMark.Johnson@Sun.COM char *op_name[] = { "read", "write", "barrier", "flush" };
9907756SMark.Johnson@Sun.COM
9917756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " op=%s", op_name[req->operation]);
9927756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " num of segments=%d", req->nr_segments);
9937756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " handle=%d", req->handle);
9947756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " id=0x%llx", (unsigned long long)req->id);
9957756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " start sector=%llu",
9967756SMark.Johnson@Sun.COM (unsigned long long)req->sector_number);
9977756SMark.Johnson@Sun.COM for (i = 0; i < req->nr_segments; i++) {
9987756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " gref=%d, first sec=%d,"
9997756SMark.Johnson@Sun.COM "last sec=%d", req->seg[i].gref, req->seg[i].first_sect,
10007756SMark.Johnson@Sun.COM req->seg[i].last_sect);
10017756SMark.Johnson@Sun.COM }
10027756SMark.Johnson@Sun.COM }
10037756SMark.Johnson@Sun.COM
10047756SMark.Johnson@Sun.COM
10057756SMark.Johnson@Sun.COM /*
10067756SMark.Johnson@Sun.COM * blk_ring_response_dump()
10077756SMark.Johnson@Sun.COM */
10087756SMark.Johnson@Sun.COM void
blk_ring_response_dump(blkif_response_t * resp)10097756SMark.Johnson@Sun.COM blk_ring_response_dump(blkif_response_t *resp)
10107756SMark.Johnson@Sun.COM {
10117756SMark.Johnson@Sun.COM /*
10127756SMark.Johnson@Sun.COM * Exploit the public interface definitions for BLKIF_OP_READ
10137756SMark.Johnson@Sun.COM * etc..
10147756SMark.Johnson@Sun.COM */
10157756SMark.Johnson@Sun.COM char *op_name[] = { "read", "write", "barrier", "flush" };
10167756SMark.Johnson@Sun.COM
10177756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " op=%d:%s", resp->operation,
10187756SMark.Johnson@Sun.COM op_name[resp->operation]);
10197756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " op=%d", resp->operation);
10207756SMark.Johnson@Sun.COM cmn_err(CE_NOTE, " status=%d", resp->status);
10217756SMark.Johnson@Sun.COM }
1022