7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * CDDL HEADER START
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * The contents of this file are subject to the terms of the
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Common Development and Distribution License (the "License").
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * You may not use this file except in compliance with the License.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * or http://www.opensolaris.org/os/licensing.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * See the License for the specific language governing permissions
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * and limitations under the License.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * When distributing Covered Code, include this CDDL HEADER in each
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * If applicable, add the following below this CDDL HEADER, with the
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * fields enclosed by brackets "[]" replaced with your own identifying
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * information: Portions Copyright [yyyy] [name of copyright owner]
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * CDDL HEADER END
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Use is subject to license terms.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/errno.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/types.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/conf.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/kmem.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/ddi.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/stat.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/sunddi.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/file.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/open.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/modctl.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/ddi_impldefs.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/sysmacros.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/ddidevmap.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <sys/xendev.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <public/io/protocols.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include <xen/io/blkif_impl.h>
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson#include "blk_common.h"
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/* blk interface status */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonenum blk_if_state {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * initial state
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_IF_UNKNOWN = 0,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * frontend xenbus state changed to XenbusStateConnected,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * we finally connect
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_IF_CONNECTED,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * frontend xenbus state changed to XenbusStateClosed,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * interface disconnected
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_IF_DISCONNECTED
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson};
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/* backend device status */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonenum blk_be_state {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* initial state */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_BE_UNKNOWN = 0,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* backend device is ready (hotplug script finishes successfully) */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_BE_READY
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson};
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/* frontend status */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonenum blk_fe_state {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* initial state */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_FE_UNKNOWN = 0,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * frontend's xenbus state has changed to
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * XenbusStateInitialised, is ready for connecting
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson BLK_FE_READY
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson};
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsontypedef struct blk_ring_state_s {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kmutex_t rs_mutex;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson boolean_t rs_sleeping_on_ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson boolean_t rs_ring_up;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kcondvar_t rs_cv;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson} blk_ring_state_t;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/* Disk Statistics */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic char *blk_stats[] = {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "rd_reqs",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "wr_reqs",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "br_reqs",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "fl_reqs",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "oo_reqs"
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson};
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsontypedef struct blk_stats_s {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson uint64_t bs_req_reads;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson uint64_t bs_req_writes;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson uint64_t bs_req_barriers;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson uint64_t bs_req_flushes;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson} blk_stats_t;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstruct blk_ring_s {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kmutex_t ri_mutex;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dev_info_t *ri_dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_t *ri_kstats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_stats_t ri_stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_intr_t ri_intr;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson caddr_t ri_intr_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_cb_t ri_ringup;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson caddr_t ri_ringup_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_cb_t ri_ringdown;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson caddr_t ri_ringdown_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* blk interface, backend, and frontend status */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson enum blk_if_state ri_if_status;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson enum blk_be_state ri_be_status;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson enum blk_fe_state ri_fe_status;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson domid_t ri_fe;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson enum blkif_protocol ri_protocol;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson size_t ri_nentry;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson size_t ri_entrysize;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xendev_ring_t *ri_ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_state_t ri_state;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson};
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_oe_state_change(dev_info_t *dip, ddi_eventcookie_t id,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson void *arg, void *impl_data);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_hp_state_change(dev_info_t *dip, ddi_eventcookie_t id,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson void *arg, void *impl_data);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int blk_check_state_transition(blk_ring_t ring, XenbusState oestate);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int blk_start_connect(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_start_disconnect(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_ring_close(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int blk_bindto_frontend(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_unbindfrom_frontend(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic uint_t blk_intr(caddr_t arg);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int blk_kstat_init(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_kstat_fini(blk_ring_t ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int blk_kstat_update(kstat_t *ksp, int flag);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_ring_request_32(blkif_request_t *dst,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blkif_x86_32_request_t *src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_ring_request_64(blkif_request_t *dst,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blkif_x86_64_request_t *src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_ring_response_32(blkif_x86_32_response_t *dst,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blkif_response_t *src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void blk_ring_response_64(blkif_x86_64_response_t *dst,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blkif_response_t *src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_init()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonint
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_init(blk_ringinit_args_t *args, blk_ring_t *ringp)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int e;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = kmem_zalloc(sizeof (struct blk_ring_s), KM_SLEEP);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_init(&ring->ri_mutex, NULL, MUTEX_DRIVER, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_dip = args->ar_dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_intr = args->ar_intr;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_intr_arg = args->ar_intr_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_ringup = args->ar_ringup;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_ringup_arg = args->ar_ringup_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_ringdown = args->ar_ringdown;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_ringdown_arg = args->ar_ringdown_arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_if_status = BLK_IF_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_be_status = BLK_BE_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe_status = BLK_FE_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_sleeping_on_ring = B_FALSE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_ring_up = B_FALSE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_init(&ring->ri_state.rs_mutex, NULL, MUTEX_DRIVER, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cv_init(&ring->ri_state.rs_cv, NULL, CV_DRIVER, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = blk_kstat_init(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto ringinitfail_kstat;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* Watch frontend and hotplug state change */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (xvdi_add_event_handler(ring->ri_dip, XS_OE_STATE,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_oe_state_change, ring) != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto ringinitfail_oestate;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (xvdi_add_event_handler(ring->ri_dip, XS_HP_STATE,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_hp_state_change, ring) != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto ringinitfail_hpstate;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Kick-off hotplug script
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (xvdi_post_event(ring->ri_dip, XEN_HP_ADD) != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_WARN, "blk@%s: failed to start hotplug script",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_get_name_addr(ring->ri_dip));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto ringinitfail_postevent;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * start waiting for hotplug event and otherend state event
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * mainly for debugging, frontend will not take any op seeing this
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_switch_state(ring->ri_dip, XBT_NULL, XenbusStateInitWait);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *ringp = ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_SUCCESS);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonringinitfail_postevent:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_remove_event_handler(ring->ri_dip, XS_HP_STATE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonringinitfail_hpstate:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_remove_event_handler(ring->ri_dip, XS_OE_STATE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonringinitfail_oestate:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_kstat_fini(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonringinitfail_kstat:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cv_destroy(&ring->ri_state.rs_cv);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_destroy(&ring->ri_state.rs_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_destroy(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kmem_free(ring, sizeof (struct blk_ring_s));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_fini()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonvoid
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_fini(blk_ring_t *ringp)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = *ringp;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_if_status != BLK_IF_DISCONNECTED) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_close(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_remove_event_handler(ring->ri_dip, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_kstat_fini(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cv_destroy(&ring->ri_state.rs_cv);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_destroy(&ring->ri_state.rs_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_destroy(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kmem_free(ring, sizeof (struct blk_ring_s));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson *ringp = NULL;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_kstat_init()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_kstat_init(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int nstat = sizeof (blk_stats) / sizeof (blk_stats[0]);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char **cp = blk_stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_named_t *knp;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_kstats = kstat_create(ddi_get_name(ring->ri_dip),
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_get_instance(ring->ri_dip), "req_statistics", "block",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson KSTAT_TYPE_NAMED, nstat, 0);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_kstats == NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_kstats->ks_private = ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_kstats->ks_update = blk_kstat_update;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson knp = ring->ri_kstats->ks_data;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson while (nstat > 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_named_init(knp, *cp, KSTAT_DATA_UINT64);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson knp++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cp++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson nstat--;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_install(ring->ri_kstats);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_SUCCESS);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_kstat_fini()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_kstat_fini(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_delete(ring->ri_kstats);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_kstat_update()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_kstat_update(kstat_t *ksp, int flag)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kstat_named_t *knp;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_stats_t *stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (flag != KSTAT_READ) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (EACCES);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = ksp->ks_private;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats = &ring->ri_stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson knp = ksp->ks_data;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Assignment order should match that of the names in
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_stats.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (knp++)->value.ui64 = stats->bs_req_reads;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (knp++)->value.ui64 = stats->bs_req_writes;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (knp++)->value.ui64 = stats->bs_req_barriers;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (knp++)->value.ui64 = stats->bs_req_flushes;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (knp++)->value.ui64 = 0; /* oo_req */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (0);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_oe_state_change()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*ARGSUSED*/
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_oe_state_change(dev_info_t *dip, ddi_eventcookie_t id, void *arg,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson void *impl_data)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson XenbusState new_state;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = (blk_ring_t)arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson new_state = *(XenbusState *)impl_data;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (blk_check_state_transition(ring, new_state) == DDI_FAILURE) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson switch (new_state) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case XenbusStateInitialised:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(ring->ri_if_status == BLK_IF_UNKNOWN);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* frontend is ready for connecting */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe_status = BLK_FE_READY;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_be_status == BLK_BE_READY) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (blk_start_connect(ring) != DDI_SUCCESS)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) blk_start_disconnect(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case XenbusStateClosing:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosing);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case XenbusStateClosed:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* clean up */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_post_event(ring->ri_dip, XEN_HP_REMOVE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_ringdown != NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (*(ring->ri_ringdown))(ring->ri_ringdown_arg);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_close(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* reset state in case of reconnect */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_if_status = BLK_IF_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_be_status = BLK_BE_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe_status = BLK_FE_UNKNOWN;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_sleeping_on_ring = B_FALSE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_ring_up = B_FALSE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson default:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(0);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_hp_state_change()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*ARGSUSED*/
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_hp_state_change(dev_info_t *dip, ddi_eventcookie_t id, void *arg,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson void *impl_data)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xendev_hotplug_state_t hpstate;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = (blk_ring_t)arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson hpstate = *(xendev_hotplug_state_t *)impl_data;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (hpstate == Connected) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* Hotplug script has completed successfully */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_be_status == BLK_BE_UNKNOWN) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_be_status = BLK_BE_READY;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_fe_status == BLK_FE_READY) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* try to connect to frontend */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (blk_start_connect(ring) != DDI_SUCCESS)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) blk_start_disconnect(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_check_state_transition()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * check the XenbusState change to see if the change is a valid transition
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * or not. The new state is written by frontend domain, or by running
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * xenstore-write to change it manually in dom0.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_check_state_transition(blk_ring_t ring, XenbusState oestate)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson switch (ring->ri_if_status) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLK_IF_UNKNOWN:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_fe_status == BLK_FE_UNKNOWN) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if ((oestate == XenbusStateUnknown) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateConnected))
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_bug;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson else if ((oestate == XenbusStateInitialising) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitWait))
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_nop;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if ((oestate == XenbusStateUnknown) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitialising) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitWait) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateConnected))
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_bug;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson else if (oestate == XenbusStateInitialised)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_nop;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLK_IF_CONNECTED:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if ((oestate == XenbusStateUnknown) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitialising) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitWait) ||
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (oestate == XenbusStateInitialised))
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_bug;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson else if (oestate == XenbusStateConnected)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_nop;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLK_IF_DISCONNECTED:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson default:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto statechkfail_bug;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_SUCCESS);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatechkfail_bug:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, "blk@%s: unexpected otherend "
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "state change to %d!, when status is %d",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_get_name_addr(ring->ri_dip), oestate,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_if_status);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatechkfail_nop:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_start_connect()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Kick-off connect process
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * If ri_fe_status == BLK_FE_READY and ri_be_status == BLK_BE_READY
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * the ri_if_status will be changed to BLK_IF_CONNECTED on success,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * otherwise, ri_if_status will not be changed
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_start_connect(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xenbus_transaction_t xbt;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dev_info_t *dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char *barrier;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char *xsnode;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson uint_t len;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int e;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dip = ring->ri_dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Start connect to frontend only when backend device are ready
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * and frontend has moved to XenbusStateInitialised, which means
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * ready to connect
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(ring->ri_fe_status == BLK_FE_READY);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(ring->ri_be_status == BLK_BE_READY);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xsnode = xvdi_get_xsname(dip);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (xsnode == NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_get_xsname;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe = xvdi_get_oeid(dip);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_fe == (domid_t)-1) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_get_oeid;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xvdi_switch_state(dip, XBT_NULL, XenbusStateInitialised);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e > 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_switch_init;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = blk_bindto_frontend(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_bindto_frontend;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_if_status = BLK_IF_CONNECTED;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = ddi_add_intr(dip, 0, NULL, NULL, blk_intr, (caddr_t)ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_add_intr;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsontrans_retry:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_transaction_start(&xbt);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e, "transaction start");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_transaction_start;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson /* xentop requires the instance in xenstore */
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson e = xenbus_printf(xbt, xsnode, "instance", "%d",
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson ddi_get_instance(ring->ri_dip));
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson if (e != 0) {
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson cmn_err(CE_WARN, "xdb@%s: failed to write 'instance'",
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson ddi_get_name_addr(dip));
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson xvdi_fatal_error(dip, e, "writing 'instance'");
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson (void) xenbus_transaction_end(xbt, 1);
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson goto startconnectfail_xenbus_printf;
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson }
62dcc6f36fd03042857eae7d26dc2dca0db70d0cMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* If feature-barrier isn't present in xenstore, add it */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_read(xbt, xsnode, "feature-barrier", (void **)&barrier,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson &len);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_printf(xbt, xsnode, "feature-barrier", "%d", 1);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_WARN, "xdb@%s: failed to write "
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "'feature-barrier'", ddi_get_name_addr(dip));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e, "writing 'feature-barrier'");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xenbus_transaction_end(xbt, 1);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_xenbus_printf;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson kmem_free(barrier, len);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xvdi_switch_state(dip, xbt, XenbusStateConnected);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e > 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e, "writing 'state'");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xenbus_transaction_end(xbt, 1);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_switch_connected;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_transaction_end(xbt, 0);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e == EAGAIN) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* transaction is ended, don't need to abort it */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto trans_retry;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e, "completing transaction");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson goto startconnectfail_transaction_end;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_state.rs_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_ring_up = B_TRUE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_state.rs_sleeping_on_ring) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_state.rs_sleeping_on_ring = B_FALSE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cv_signal(&ring->ri_state.rs_cv);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_state.rs_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_ringup != NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (*(ring->ri_ringup))(ring->ri_ringup_arg);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_SUCCESS);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_transaction_end:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_switch_connected:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_xenbus_printf:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_transaction_start:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_remove_intr(dip, 0, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_add_intr:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_unbindfrom_frontend(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe = (domid_t)-1;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_bindto_frontend:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosed);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_switch_init:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_get_oeid:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstartconnectfail_get_xsname:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_start_disconnect()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Kick-off disconnect process. ri_if_status will not be changed
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_start_disconnect(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* Kick-off disconnect process */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_switch_state(ring->ri_dip, XBT_NULL, XenbusStateClosing);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_close()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Disconnect from frontend and close backend device
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * ifstatus will be changed to BLK_DISCONNECTED
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Xenbus state will be changed to XenbusStateClosed
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_close(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dev_info_t *dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* mutex protect ri_if_status only here */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(MUTEX_HELD(&ring->ri_mutex));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dip = ring->ri_dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_if_status != BLK_IF_CONNECTED) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_if_status = BLK_IF_DISCONNECTED;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /* stop accepting I/O request from frontend */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_remove_intr(dip, 0, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_unbindfrom_frontend(ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_fe = (domid_t)-1;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosed);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_bindto_frontend()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic int
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_bindto_frontend(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson evtchn_port_t evtchn;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char protocol[64];
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson grant_ref_t gref;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dev_info_t *dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char *oename;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int e;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dip = ring->ri_dip;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson protocol[0] = 0x0;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Gather info from frontend
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson oename = xvdi_get_oename(dip);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (oename == NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_gather(XBT_NULL, oename, "ring-ref", "%lu", &gref,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "event-channel", "%u", &evtchn, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "Getting ring-ref and evtchn from frontend");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xenbus_gather(XBT_NULL, oename, "protocol", "%63s",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson protocol, NULL);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) strcpy(protocol, "unspecified, assuming native");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else if (strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE) == 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_protocol = BLKIF_PROTOCOL_NATIVE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_nentry = BLKIF_RING_SIZE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_entrysize = sizeof (union blkif_sring_entry);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_protocol = BLKIF_PROTOCOL_X86_32;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_nentry = BLKIF_X86_32_RING_SIZE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_entrysize = sizeof (union blkif_x86_32_sring_entry);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_protocol = BLKIF_PROTOCOL_X86_64;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_nentry = BLKIF_X86_64_RING_SIZE;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_entrysize = sizeof (union blkif_x86_64_sring_entry);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson } else {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_fatal_error(dip, e, "unknown fe protocol");
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * map and init ring
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xvdi_map_ring(dip, ring->ri_nentry, ring->ri_entrysize, gref,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson &ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * bind event channel
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xvdi_bind_evtchn(dip, evtchn);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != DDI_SUCCESS) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_unmap_ring(ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_FAILURE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_SUCCESS);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_unbindfrom_frontend()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_unbindfrom_frontend(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_free_evtchn(ring->ri_dip);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_unmap_ring(ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_intr()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic uint_t
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_intr(caddr_t arg)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_t ring;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring = (blk_ring_t)arg;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (ring->ri_if_status != BLK_IF_CONNECTED) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_INTR_CLAIMED);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (void) (*ring->ri_intr)(ring->ri_intr_arg);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (DDI_INTR_CLAIMED);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_request_get()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonboolean_t
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_request_get(blk_ring_t ring, blkif_request_t *req)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blkif_request_t *src;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_stats_t *stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_enter(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee if (ring->ri_if_status != BLK_IF_CONNECTED) {
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_exit(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee return (B_FALSE);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee }
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson src = xvdi_ring_get_request(ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (src == NULL) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (B_FALSE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson switch (ring->ri_protocol) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_NATIVE:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson bcopy(src, req, sizeof (*req));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_X86_32:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_request_32(req, (blkif_x86_32_request_t *)src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_X86_64:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_request_64(req, (blkif_x86_64_request_t *)src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson default:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_WARN, "blkif@%s: unrecognised protocol: %d",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_get_name_addr(ring->ri_dip),
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_protocol);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats = &ring->ri_stats;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson switch (req->operation) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_OP_READ:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats->bs_req_reads++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_OP_WRITE:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats->bs_req_writes++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_OP_WRITE_BARRIER:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats->bs_req_barriers++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_OP_FLUSH_DISKCACHE:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson stats->bs_req_flushes++;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson return (B_TRUE);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_request_requeue()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * if a request is requeued, caller will have to poll for request
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * later.
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonvoid
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_request_requeue(blk_ring_t ring)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_enter(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee if (ring->ri_if_status != BLK_IF_CONNECTED) {
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_exit(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee return;
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee }
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_ring->xr_sring.br.req_cons--;
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_response_put()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonvoid
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_response_put(blk_ring_t ring, blkif_response_t *src)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee blkif_response_t *rsp;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int e;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_enter(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee if (ring->ri_if_status != BLK_IF_CONNECTED) {
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_exit(&ring->ri_mutex);
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee return;
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee }
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee rsp = xvdi_ring_get_response(ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ASSERT(rsp);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson switch (ring->ri_protocol) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_NATIVE:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson bcopy(src, rsp, sizeof (*rsp));
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_X86_32:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_response_32((blkif_x86_32_response_t *)rsp, src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson case BLKIF_PROTOCOL_X86_64:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson blk_ring_response_64((blkif_x86_64_response_t *)rsp, src);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson break;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson default:
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_WARN, "blk@%s: unrecognised protocol: %d",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ddi_get_name_addr(ring->ri_dip),
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson ring->ri_protocol);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson e = xvdi_ring_push_response(ring->ri_ring);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (e != 0) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson xvdi_notify_oe(ring->ri_dip);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee mutex_exit(&ring->ri_mutex);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_request_32()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_request_32(blkif_request_t *dst, blkif_x86_32_request_t *src)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->operation = src->operation;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->nr_segments = src->nr_segments;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->handle = src->handle;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->id = src->id;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->sector_number = src->sector_number;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (n > src->nr_segments)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson n = src->nr_segments;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson for (i = 0; i < n; i++)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->seg[i] = src->seg[i];
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_request_64()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_request_64(blkif_request_t *dst, blkif_x86_64_request_t *src)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->operation = src->operation;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->nr_segments = src->nr_segments;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->handle = src->handle;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->id = src->id;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->sector_number = src->sector_number;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson if (n > src->nr_segments)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson n = src->nr_segments;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson for (i = 0; i < n; i++)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->seg[i] = src->seg[i];
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_response_32()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_response_32(blkif_x86_32_response_t *dst, blkif_response_t *src)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->id = src->id;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->operation = src->operation;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->status = src->status;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_response_64()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonstatic void
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_response_64(blkif_x86_64_response_t *dst, blkif_response_t *src)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->id = src->id;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->operation = src->operation;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson dst->status = src->status;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_request_dump()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonvoid
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_request_dump(blkif_request_t *req)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson int i;
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Exploit the public interface definitions for BLKIF_OP_READ
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * etc..
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char *op_name[] = { "read", "write", "barrier", "flush" };
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " op=%s", op_name[req->operation]);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " num of segments=%d", req->nr_segments);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " handle=%d", req->handle);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " id=0x%llx", (unsigned long long)req->id);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " start sector=%llu",
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson (unsigned long long)req->sector_number);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson for (i = 0; i < req->nr_segments; i++) {
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " gref=%d, first sec=%d,"
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson "last sec=%d", req->seg[i].gref, req->seg[i].first_sect,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson req->seg[i].last_sect);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson }
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson/*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * blk_ring_response_dump()
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonvoid
7eea693d6b672899726e75993fddc4e95b52647fMark Johnsonblk_ring_response_dump(blkif_response_t *resp)
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson{
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson /*
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * Exploit the public interface definitions for BLKIF_OP_READ
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson * etc..
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson */
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson char *op_name[] = { "read", "write", "barrier", "flush" };
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " op=%d:%s", resp->operation,
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson op_name[resp->operation]);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " op=%d", resp->operation);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson cmn_err(CE_NOTE, " status=%d", resp->status);
7eea693d6b672899726e75993fddc4e95b52647fMark Johnson}