843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER START
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * The contents of this file are subject to the terms of the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Common Development and Distribution License (the "License").
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You may not use this file except in compliance with the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
843e19887f64dde75055cf8842fc4db2171eff45johnlev * or http://www.opensolaris.org/os/licensing.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * See the License for the specific language governing permissions
843e19887f64dde75055cf8842fc4db2171eff45johnlev * and limitations under the License.
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * When distributing Covered Code, include this CDDL HEADER in each
843e19887f64dde75055cf8842fc4db2171eff45johnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * If applicable, add the following below this CDDL HEADER, with the
843e19887f64dde75055cf8842fc4db2171eff45johnlev * fields enclosed by brackets "[]" replaced with your own identifying
843e19887f64dde75055cf8842fc4db2171eff45johnlev * information: Portions Copyright [yyyy] [name of copyright owner]
843e19887f64dde75055cf8842fc4db2171eff45johnlev *
843e19887f64dde75055cf8842fc4db2171eff45johnlev * CDDL HEADER END
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Use is subject to license terms.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * xdf.c - Xen Virtual Block Device Driver
843e19887f64dde75055cf8842fc4db2171eff45johnlev * TODO:
843e19887f64dde75055cf8842fc4db2171eff45johnlev * - support alternate block size (currently only DEV_BSIZE supported)
843e19887f64dde75055cf8842fc4db2171eff45johnlev * - revalidate geometry for removable devices
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * This driver export solaris disk device nodes, accepts IO requests from
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * those nodes, and services those requests by talking to a backend device
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * in another domain.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Communication with the backend device is done via a ringbuffer (which is
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * managed via xvdi interfaces) and dma memory (which is managed via ddi
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * interfaces).
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Communication with the backend device is dependant upon establishing a
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * connection to the backend device. This connection process involves
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * reading device configuration information from xenbus and publishing
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * some frontend runtime configuration parameters via the xenbus (for
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * consumption by the backend). Once we've published runtime configuration
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * information via the xenbus, the backend device can enter the connected
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * state and we'll enter the XD_CONNECTED state. But before we can allow
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * random IO to begin, we need to do IO to the backend device to determine
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * the device label and if flush operations are supported. Once this is
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * done we enter the XD_READY state and can process any IO operations.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We recieve notifications of xenbus state changes for the backend device
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (aka, the "other end") via the xdf_oe_change() callback. This callback
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * is single threaded, meaning that we can't recieve new notification of
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * other end state changes while we're processing an outstanding
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * notification of an other end state change. There for we can't do any
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * blocking operations from the xdf_oe_change() callback. This is why we
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * have a seperate taskq (xdf_ready_tq) which exists to do the necessary
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * IO to get us from the XD_CONNECTED to the XD_READY state. All IO
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * generated by the xdf_ready_tq thread (xdf_ready_tq_thread) will go
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * throught xdf_lb_rdwr(), which is a synchronous IO interface. IOs
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * generated by the xdf_ready_tq_thread thread have priority over all
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * other IO requests.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We also communicate with the backend device via the xenbus "media-req"
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (XBP_MEDIA_REQ) property. For more information on this see the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * comments in blkif.h.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#include <io/xdf.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp#include <sys/conf.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/dkio.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/promif.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/sysmacros.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/kstat.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/mach_mmu.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#ifdef XPV_HVM_DRIVER
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/xpv_support.h>
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp#include <sys/sunndi.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#include <sys/evtchn_impl.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <public/io/xenbus.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <xen/sys/xenbus_impl.h>
551bc2a66868b5cb5be6b70ab9f55515e77a39a9mrj#include <sys/scsi/generic/inquiry.h>
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab#include <xen/io/blkif_impl.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#include <sys/fdio.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#include <sys/cdio.h>
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * DEBUG_EVAL can be used to include debug only statements without
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * having to use '#ifdef DEBUG' statements
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef DEBUG
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define DEBUG_EVAL(x) (x)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !DEBUG */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define DEBUG_EVAL(x)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !DEBUG */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define XDF_DRAIN_MSEC_DELAY (50*1000) /* 00.05 sec */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define XDF_DRAIN_RETRY_COUNT 200 /* 10.00 sec */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define INVALID_DOMID ((domid_t)-1)
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define FLUSH_DISKCACHE 0x1
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define WRITE_BARRIER 0x2
843e19887f64dde75055cf8842fc4db2171eff45johnlev#define DEFAULT_FLUSH_BLOCK 156 /* block to write to cause a cache flush */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define USE_WRITE_BARRIER(vdp) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev ((vdp)->xdf_feature_barrier && !(vdp)->xdf_flush_supported)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define USE_FLUSH_DISKCACHE(vdp) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev ((vdp)->xdf_feature_barrier && (vdp)->xdf_flush_supported)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define IS_WRITE_BARRIER(vdp, bp) \
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (!IS_READ(bp) && USE_WRITE_BARRIER(vdp) && \
843e19887f64dde75055cf8842fc4db2171eff45johnlev ((bp)->b_un.b_addr == (vdp)->xdf_cache_flush_block))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define IS_FLUSH_DISKCACHE(bp) \
843e19887f64dde75055cf8842fc4db2171eff45johnlev (!IS_READ(bp) && USE_FLUSH_DISKCACHE(vdp) && ((bp)->b_bcount == 0))
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define VREQ_DONE(vreq) \
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz VOID2BOOLEAN(((vreq)->v_status == VREQ_DMAWIN_DONE) && \
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (((vreq)->v_flush_diskcache == FLUSH_DISKCACHE) || \
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (((vreq)->v_dmaw + 1) == (vreq)->v_ndmaws)))
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define BP_VREQ(bp) ((v_req_t *)((bp)->av_back))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define BP_VREQ_SET(bp, vreq) (((bp)->av_back = (buf_t *)(vreq)))
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczextern int do_polled_io;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* run-time tunables that we don't want the compiler to optimize away */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvolatile int xdf_debug = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvolatile boolean_t xdf_barrier_flush_disable = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* per module globals */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczmajor_t xdf_major;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void *xdf_ssp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic kmem_cache_t *xdf_vreq_cache;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic kmem_cache_t *xdf_gs_cache;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int xdf_maxphys = XB_MAXPHYS;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic diskaddr_t xdf_flush_block = DEFAULT_FLUSH_BLOCK;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int xdf_fbrewrites; /* flush block re-write count */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* misc public functions (used by xdf_shell.c) */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint xdf_lb_rdwr(dev_info_t *, uchar_t, void *, diskaddr_t, size_t, void *);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint xdf_lb_getinfo(dev_info_t *, int, void *, void *);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* misc private functions */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void xdf_io_start(xdf_t *);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* callbacks from commmon label */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic cmlb_tg_ops_t xdf_lb_ops = {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz TG_DK_OPS_VERSION_1,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_lb_rdwr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_lb_getinfo
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * I/O buffer DMA attributes
843e19887f64dde75055cf8842fc4db2171eff45johnlev * Make sure: one DMA window contains BLKIF_MAX_SEGMENTS_PER_REQUEST at most
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic ddi_dma_attr_t xb_dma_attr = {
843e19887f64dde75055cf8842fc4db2171eff45johnlev DMA_ATTR_V0,
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)0, /* lowest address */
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)0xffffffffffffffff, /* highest usable address */
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)0xffffff, /* DMA counter limit max */
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)XB_BSIZE, /* alignment in bytes */
843e19887f64dde75055cf8842fc4db2171eff45johnlev XB_BSIZE - 1, /* bitmap of burst sizes */
843e19887f64dde75055cf8842fc4db2171eff45johnlev XB_BSIZE, /* min transfer */
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)XB_MAX_XFER, /* maximum transfer */
843e19887f64dde75055cf8842fc4db2171eff45johnlev (uint64_t)PAGEOFFSET, /* 1 page segment length */
843e19887f64dde75055cf8842fc4db2171eff45johnlev BLKIF_MAX_SEGMENTS_PER_REQUEST, /* maximum number of segments */
843e19887f64dde75055cf8842fc4db2171eff45johnlev XB_BSIZE, /* granularity */
843e19887f64dde75055cf8842fc4db2171eff45johnlev 0, /* flags (reserved) */
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic ddi_device_acc_attr_t xc_acc_attr = {
843e19887f64dde75055cf8842fc4db2171eff45johnlev DDI_DEVICE_ATTR_V0,
843e19887f64dde75055cf8842fc4db2171eff45johnlev DDI_NEVERSWAP_ACC,
843e19887f64dde75055cf8842fc4db2171eff45johnlev DDI_STRICTORDER_ACC
843e19887f64dde75055cf8842fc4db2171eff45johnlev};
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_timeout_handler(void *arg)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_timeout_id = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* new timeout thread could be re-scheduled */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * callback func when DMA/GTE resources is available
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Note: we only register one callback function to grant table subsystem
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * since we only have one 'struct gnttab_free_callback' in xdf_t.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_dmacallback(caddr_t arg)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)arg;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp != NULL);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: DMA callback started\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_trigger_softintr(vdp->xdf_softintr_id);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_DMA_CALLBACK_DONE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic ge_slot_t *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczgs_get(xdf_t *vdp, int isread)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz grant_ref_t gh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ge_slot_t *gs;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* try to alloc GTEs needed in this slot, first */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (gnttab_alloc_grant_references(
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_MAX_SEGMENTS_PER_REQUEST, &gh) == -1) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_gnt_callback.next == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBON(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gnttab_request_free_callback(
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &vdp->xdf_gnt_callback,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void (*)(void *))xdf_dmacallback,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void *)vdp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_MAX_SEGMENTS_PER_REQUEST);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs = kmem_cache_alloc(xdf_gs_cache, KM_NOSLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (gs == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gnttab_free_grant_references(gh);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_timeout_id == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* restart I/O after one second */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_timeout_id =
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz timeout(xdf_timeout_handler, vdp, hz);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* init gs_slot */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_oeid = vdp->xdf_peer;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_isread = isread;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_ghead = gh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_ngrefs = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczgs_free(ge_slot_t *gs)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int i;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* release all grant table entry resources used in this slot */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (i = 0; i < gs->gs_ngrefs; i++)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gnttab_end_foreign_access(gs->gs_ge[i], !gs->gs_isread, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gnttab_free_grant_references(gs->gs_ghead);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_remove(&gs->gs_vreq->v_gs, gs);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_free(xdf_gs_cache, gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic grant_ref_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczgs_grant(ge_slot_t *gs, mfn_t mfn)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz grant_ref_t gr = gnttab_claim_grant_reference(&gs->gs_ghead);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(gr != -1);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(gs->gs_ngrefs < BLKIF_MAX_SEGMENTS_PER_REQUEST);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_ge[gs->gs_ngrefs++] = gr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gnttab_grant_foreign_access_ref(gr, gs->gs_oeid, mfn, !gs->gs_isread);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (gr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Alloc a vreq for this bp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * bp->av_back contains the pointer to the vreq upon return
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic v_req_t *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvreq_get(xdf_t *vdp, buf_t *bp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(BP_VREQ(bp) == NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq = kmem_cache_alloc(xdf_vreq_cache, KM_NOSLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vreq == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_timeout_id == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* restart I/O after one second */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_timeout_id =
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz timeout(xdf_timeout_handler, vdp, hz);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bzero(vreq, sizeof (v_req_t));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_create(&vreq->v_gs, sizeof (ge_slot_t),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz offsetof(ge_slot_t, gs_vreq_link));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_buf = bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_INIT;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_runq = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BP_VREQ_SET(bp, vreq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* init of other fields in vreq is up to the caller */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_insert_head(&vdp->xdf_vreq_act, (void *)vreq);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (vreq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvreq_free(xdf_t *vdp, v_req_t *vreq)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp = vreq->v_buf;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(BP_VREQ(bp) == vreq);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_remove(&vdp->xdf_vreq_act, vreq);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vreq->v_flush_diskcache == FLUSH_DISKCACHE)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto done;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (vreq->v_status) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAWIN_DONE:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_GS_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMABUF_BOUND:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) ddi_dma_unbind_handle(vreq->v_dmahdl);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAMEM_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!ALIGNED_XFER(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vreq->v_abuf != NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!IS_ERROR(bp) && IS_READ(bp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bcopy(vreq->v_abuf, bp->b_un.b_addr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_bcount);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_mem_free(&vreq->v_align);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_MEMDMAHDL_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!ALIGNED_XFER(bp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_free_handle(&vreq->v_memdmahdl);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAHDL_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_free_handle(&vreq->v_dmahdl);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz default:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczdone:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(!vreq->v_runq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_destroy(&vreq->v_gs);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_free(xdf_vreq_cache, vreq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Snarf new data if our flush block was re-written
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczcheck_fbwrite(xdf_t *vdp, buf_t *bp, daddr_t blkno)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int nblks;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t mapin;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (IS_WRITE_BARRIER(vdp, bp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return; /* write was a flush write */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mapin = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nblks = bp->b_bcount >> DEV_BSHIFT;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_flush_block >= blkno && xdf_flush_block < (blkno + nblks)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_fbrewrites++;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp->b_flags & (B_PAGEIO | B_PHYS)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mapin = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_mapin(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bcopy(bp->b_un.b_addr +
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((xdf_flush_block - blkno) << DEV_BSHIFT),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cache_flush_block, DEV_BSIZE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (mapin)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_mapout(bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Initalize the DMA and grant table resources for the buf
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvreq_setup(xdf_t *vdp, v_req_t *vreq)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rc;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_attr_t dmaattr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint_t ndcs, ndws;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_handle_t dh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_handle_t mdh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_cookie_t dc;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_acc_handle_t abh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz caddr_t aba;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ge_slot_t *gs;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz size_t bufsz;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz off_t off;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz size_t sz;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp = vreq->v_buf;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int dma_flags = (IS_READ(bp) ? DDI_DMA_READ : DDI_DMA_WRITE) |
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_DMA_STREAMING | DDI_DMA_PARTIAL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (vreq->v_status) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_INIT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (IS_FLUSH_DISKCACHE(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((gs = gs_get(vdp, IS_READ(bp))) == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "get ge_slotfailed\n", vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_blkno = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_nslots = 1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_flush_diskcache = FLUSH_DISKCACHE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_GS_ALLOCED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_vreq = vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_insert_head(&vreq->v_gs, gs);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (IS_WRITE_BARRIER(vdp, bp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_flush_diskcache = WRITE_BARRIER;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_blkno = bp->b_blkno +
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (diskaddr_t)(uintptr_t)bp->b_private;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* See if we wrote new data to our flush block */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!IS_READ(bp) && USE_WRITE_BARRIER(vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz check_fbwrite(vdp, bp, vreq->v_blkno);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_INIT_DONE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_INIT_DONE:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * alloc DMA handle
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_alloc_handle(vdp->xdf_dip, &xb_dma_attr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_dmacallback, (caddr_t)vdp, &dh);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rc != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBON(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: DMA handle alloc failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_dmahdl = dh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_DMAHDL_ALLOCED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
6eb35ee750312cc65aa066dd0f625b9d54c6f86erab
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAHDL_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * alloc dma handle for 512-byte aligned buf
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!ALIGNED_XFER(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * XXPV: we need to temporarily enlarge the seg
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * boundary and s/g length to work round CR6381968
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dmaattr = xb_dma_attr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dmaattr.dma_attr_seg = (uint64_t)-1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dmaattr.dma_attr_sgllen = INT_MAX;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_alloc_handle(vdp->xdf_dip, &dmaattr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_dmacallback, (caddr_t)vdp, &mdh);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rc != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBON(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "unaligned buf DMAhandle alloc failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_memdmahdl = mdh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_MEMDMAHDL_ALLOCED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_MEMDMAHDL_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * alloc 512-byte aligned buf
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!ALIGNED_XFER(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp->b_flags & (B_PAGEIO | B_PHYS))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_mapin(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_mem_alloc(vreq->v_memdmahdl,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz roundup(bp->b_bcount, XB_BSIZE), &xc_acc_attr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_DMA_STREAMING, xdf_dmacallback, (caddr_t)vdp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &aba, &bufsz, &abh);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rc != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBON(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "DMA mem allocation failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_abuf = aba;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_align = abh;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_DMAMEM_ALLOCED;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bufsz >= bp->b_bcount);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!IS_READ(bp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bcopy(bp->b_un.b_addr, vreq->v_abuf,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_bcount);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAMEM_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * dma bind
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ALIGNED_XFER(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_buf_bind_handle(vreq->v_dmahdl, bp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dma_flags, xdf_dmacallback, (caddr_t)vdp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &dc, &ndcs);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_addr_bind_handle(vreq->v_dmahdl,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, vreq->v_abuf, bp->b_bcount, dma_flags,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_dmacallback, (caddr_t)vdp, &dc, &ndcs);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rc == DDI_DMA_MAPPED || rc == DDI_DMA_PARTIAL_MAP) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* get num of dma windows */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rc == DDI_DMA_PARTIAL_MAP) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rc = ddi_dma_numwin(vreq->v_dmahdl, &ndws);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(rc == DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ndws = 1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBON(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: DMA bind failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_dmac = dc;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_dmaw = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_ndmacs = ndcs;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_ndmaws = ndws;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_nslots = ndws;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_DMABUF_BOUND;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHRU*/
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMABUF_BOUND:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * get ge_slot, callback is set upon failure from gs_get(),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * if not set previously
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((gs = gs_get(vdp, IS_READ(bp))) == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: get ge_slot failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_GS_ALLOCED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_vreq = vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_insert_head(&vreq->v_gs, gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_GS_ALLOCED:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* nothing need to be done */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case VREQ_DMAWIN_DONE:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * move to the next dma window
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((vreq->v_dmaw + 1) < vreq->v_ndmaws);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* get a ge_slot for this DMA window */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((gs = gs_get(vdp, IS_READ(bp))) == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DMA_DBG, ("xdf@%s: get ge_slot failed\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_dmaw++;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz VERIFY(ddi_dma_getwin(vreq->v_dmahdl, vreq->v_dmaw, &off, &sz,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &vreq->v_dmac, &vreq->v_ndmacs) == DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_GS_ALLOCED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs->gs_vreq = vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_insert_head(&vreq->v_gs, gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev default:
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_cmlb_attach(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (cmlb_attach(dip, &xdf_lb_ops,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XD_IS_CD(vdp) ? DTYPE_RODIRECT : DTYPE_DIRECT,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XD_IS_RM(vdp),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz B_TRUE,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XD_IS_CD(vdp) ? DDI_NT_CD_XVMD : DDI_NT_BLOCK_XVMD,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (XD_IS_CD(vdp) ? 0 : CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT) |
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz CMLB_INTERNAL_MINOR_NODES,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XD_IS_CD(vdp) ? 0 : CMLB_FAKE_LABEL_ONE_PARTITION,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_lbl, NULL));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_io_err(buf_t *bp, int err, size_t resid)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerror(bp, err);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (resid == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_resid = bp->b_bcount;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz biodone(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_enter(xdf_t *vdp, buf_t *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = BP_VREQ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vreq != NULL) && vreq->v_runq) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_runq_enter(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_waitq_enter(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_exit(xdf_t *vdp, buf_t *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = BP_VREQ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vreq != NULL) && vreq->v_runq) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_runq_exit(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_waitq_exit(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_waitq_to_runq(xdf_t *vdp, buf_t *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = BP_VREQ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(!vreq->v_runq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_runq = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_waitq_to_runq(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_runq_to_waitq(xdf_t *vdp, buf_t *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = BP_VREQ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vreq->v_runq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_runq = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_runq_back_to_waitq(KSTAT_IO_PTR(vdp->xdf_xdev_iostat));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_create(dev_info_t *dip, char *ks_module, int instance)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_t *kstat;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((kstat = kstat_create(
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ks_module, instance, NULL, "disk",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (-1);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* See comment about locking in xdf_kstat_delete(). */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_iostat_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* only one kstat can exist at a time */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat != NULL) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_iostat_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_delete(kstat);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (-1);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xdev_iostat = kstat;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xdev_iostat->ks_lock = &vdp->xdf_dev_lk;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_install(vdp->xdf_xdev_iostat);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Now that we've created a kstat, we need to update the waitq and
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * runq counts for the kstat to reflect our current state.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * For a buf_t structure to be on the runq, it must have a ring
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * buffer slot associated with it. To get a ring buffer slot the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * buf must first have a v_req_t and a ge_slot_t associated with it.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Then when it is granted a ring buffer slot, v_runq will be set to
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * true.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * For a buf_t structure to be on the waitq, it must not be on the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * runq. So to find all the buf_t's that should be on waitq, we
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * walk the active buf list and add any buf_t's which aren't on the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * runq to the waitq.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = vdp->xdf_f_act;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (bp != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_enter(vdp, bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = bp->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_ready_tq_bp != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_enter(vdp, vdp->xdf_ready_tq_bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_iostat_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvoid
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_kstat_delete(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_t *kstat;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * The locking order here is xdf_iostat_lk and then xdf_dev_lk.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * xdf_dev_lk is used to protect the xdf_xdev_iostat pointer
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * and the contents of the our kstat. xdf_iostat_lk is used
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * to protect the allocation and freeing of the actual kstat.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * xdf_dev_lk can't be used for this purpose because kstat
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * readers use it to access the contents of the kstat and
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * hence it can't be held when calling kstat_delete().
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_iostat_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_iostat == NULL) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_iostat_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We're about to destroy the kstat structures, so it isn't really
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * necessary to update the runq and waitq counts. But, since this
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * isn't a hot code path we can afford to be a little pedantic and
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * go ahead and decrement the runq and waitq kstat counters to zero
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * before free'ing them. This helps us ensure that we've gotten all
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * our accounting correct.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * For an explanation of how we determine which buffers go on the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * runq vs which go on the waitq, see the comments in
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * xdf_kstat_create().
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = vdp->xdf_f_act;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (bp != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_exit(vdp, bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = bp->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_ready_tq_bp != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_exit(vdp, vdp->xdf_ready_tq_bp);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat = vdp->xdf_xdev_iostat;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xdev_iostat = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kstat_delete(kstat);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_iostat_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Add an IO requests onto the active queue.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We have to detect IOs generated by xdf_ready_tq_thread. These IOs
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * are used to establish a connection to the backend, so they recieve
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * priority over all other IOs. Since xdf_ready_tq_thread only does
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * synchronous IO, there can only be one xdf_ready_tq_thread request at any
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * given time and we record the buf associated with that request in
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * xdf_ready_tq_bp.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_bp_push(xdf_t *vdp, buf_t *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bp->av_forw == NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_enter(vdp, bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (curthread == vdp->xdf_ready_tq_thread) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* new IO requests from the ready thread */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_ready_tq_bp == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_ready_tq_bp = bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* this is normal IO request */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bp != vdp->xdf_ready_tq_bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_f_act == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* this is only only IO on the active queue */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_l_act == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_i_act == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_f_act = vdp->xdf_l_act = vdp->xdf_i_act = bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* add this IO to the tail of the active queue */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_l_act->av_forw = bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_l_act = bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_i_act == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_i_act = bp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_bp_pop(xdf_t *vdp, buf_t *bp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp_iter;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(VREQ_DONE(BP_VREQ(bp)));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_ready_tq_bp == bp) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* we're done with a ready thread IO request */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bp->av_forw == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_ready_tq_bp = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* we're done with a normal IO request */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((bp->av_forw != NULL) || (bp == vdp->xdf_l_act));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((bp->av_forw == NULL) || (bp != vdp->xdf_l_act));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(VREQ_DONE(BP_VREQ(vdp->xdf_f_act)));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_f_act != vdp->xdf_i_act);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp == vdp->xdf_f_act) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* This IO was at the head of our active queue. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_f_act = bp->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp == vdp->xdf_l_act)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_l_act = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* There IO finished before some other pending IOs. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_iter = vdp->xdf_f_act;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (bp != bp_iter->av_forw) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_iter = bp_iter->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(VREQ_DONE(BP_VREQ(bp_iter)));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bp_iter != vdp->xdf_i_act);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp_iter->av_forw = bp->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp == vdp->xdf_l_act)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_l_act = bp_iter;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->av_forw = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic buf_t *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_bp_next(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_CONNECTED) {
1d03c31e0733adea0edef54f0d5d2ea9639ecd2ajohnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If we're in the XD_CONNECTED state, we only service IOs
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * from the xdf_ready_tq_thread thread.
1d03c31e0733adea0edef54f0d5d2ea9639ecd2ajohnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((bp = vdp->xdf_ready_tq_bp) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((vreq = BP_VREQ(bp)) == NULL) || (!VREQ_DONE(vreq)))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
1d03c31e0733adea0edef54f0d5d2ea9639ecd2ajohnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* if we're not in the XD_CONNECTED or XD_READY state we can't do IO */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state != XD_READY)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_ready_tq_bp == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (;;) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((bp = vdp->xdf_i_act) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((vreq = BP_VREQ(bp)) == NULL) || (!VREQ_DONE(vreq)))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* advance the active buf index pointer */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_i_act = bp->av_forw;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_io_fini(xdf_t *vdp, uint64_t id, int bioerr)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ge_slot_t *gs = (ge_slot_t *)(uintptr_t)id;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = gs->gs_vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp = vreq->v_buf;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(BP_VREQ(bp) == vreq);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs_free(gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bioerr != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerror(bp, bioerr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vreq->v_nslots > 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (--vreq->v_nslots > 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* remove this IO from our active queue */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_bp_pop(vdp, bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vreq->v_runq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_exit(vdp, bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_runq = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq_free(vdp, vreq);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (IS_ERROR(bp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, geterror(bp), 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else if (bp->b_resid != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Partial transfers are an error */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, EIO, bp->b_resid);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz biodone(bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * xdf interrupt handler
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic uint_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_intr_locked(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xendev_ring_t *xbr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz blkif_response_t *resp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int bioerr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint64_t id;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint8_t op;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint16_t status;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_acc_handle_t acchdl;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((xbr = vdp->xdf_xb_ring) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_INTR_UNCLAIMED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz acchdl = vdp->xdf_xb_ring_hdl;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * complete all requests which have a response
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (resp = xvdi_ring_get_response(xbr)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz id = ddi_get64(acchdl, &resp->id);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz op = ddi_get8(acchdl, &resp->operation);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz status = ddi_get16(acchdl, (uint16_t *)&resp->status);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(INTR_DBG, ("resp: op %d id %"PRIu64" status %d\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz op, id, status));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (status != BLKIF_RSP_OKAY) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: I/O error while %s",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (op == BLKIF_OP_READ) ? "reading" : "writing"));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerr = EIO;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerr = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_fini(vdp, id, bioerr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_INTR_CLAIMED);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz/*
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * xdf_intr runs at PIL 5, so no one else can grab xdf_dev_lk and
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * block at a lower pil.
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic uint_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_intr(caddr_t arg)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)arg;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_intr_locked(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!do_polled_io)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ring_push(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xb_ring == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_ring_push_request(vdp->xdf_xb_ring)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, (
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: xdf_ring_push: sent request(s) to backend\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr));
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_get_evtchn(vdp->xdf_dip) != INVALID_EVTCHN)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_notify_oe(vdp->xdf_dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ring_drain_locked(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int pollc, rv = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf_ring_drain: start\n");
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (pollc = 0; pollc < XDF_DRAIN_RETRY_COUNT; pollc++) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xb_ring == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto out;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_ring_has_unconsumed_responses(vdp->xdf_xb_ring))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_intr_locked(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xvdi_ring_has_incomp_request(vdp->xdf_xb_ring))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto out;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_ring_push(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* file-backed devices can be slow */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef XPV_HVM_DRIVER
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) HYPERVISOR_yield();
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz delay(drv_usectohz(XDF_DRAIN_MSEC_DELAY));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: xdf_ring_drain: timeout", vdp->xdf_addr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczout:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xb_ring != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_ring_has_incomp_request(vdp->xdf_xb_ring) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_ring_has_unconsumed_responses(vdp->xdf_xb_ring))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = EIO;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_ring_drain: end, err=%d\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ring_drain(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_ring_drain_locked(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Destroy all v_req_t, grant table entries, and our ring buffer.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ring_destroy(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz buf_t *bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ge_slot_t *gs;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_state != XD_INIT) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_state != XD_CONNECTED) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_state != XD_READY)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_xb_ring == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_xb_ring_hdl == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_peer == INVALID_DOMID);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_evtchn == INVALID_EVTCHN);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(list_is_empty(&vdp->xdf_vreq_act));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We don't want to recieve async notifications from the backend
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * when it finishes processing ring entries.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef XPV_HVM_DRIVER
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ec_unbind_evtchn(vdp->xdf_evtchn);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) ddi_remove_intr(vdp->xdf_dip, 0, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Drain any requests in the ring. We need to do this before we
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * can free grant table entries, because if active ring entries
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * point to grants, then the backend could be trying to access
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * those grants.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_ring_drain_locked(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We're done talking to the backend so free up our event channel */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_free_evtchn(vdp->xdf_dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_evtchn = INVALID_EVTCHN;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while ((vreq = list_head(&vdp->xdf_vreq_act)) != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = vreq->v_buf;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(BP_VREQ(bp) == vreq);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Free up any grant table entries associaed with this IO */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while ((gs = list_head(&vreq->v_gs)) != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gs_free(gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If this IO was on the runq, move it back to the waitq. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vreq->v_runq)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_runq_to_waitq(vdp, bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Reset any buf IO state since we're going to re-issue the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * IO when we reconnect.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq_free(vdp, vreq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BP_VREQ_SET(bp, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerror(bp, 0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* reset the active queue index pointer */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_i_act = vdp->xdf_f_act;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Destroy the ring */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_free_ring(vdp->xdf_xb_ring);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xb_ring = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xb_ring_hdl = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_peer = INVALID_DOMID;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczvoid
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdfmin(struct buf *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (bp->b_bcount > xdf_maxphys)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_bcount = xdf_maxphys;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Check if we have a pending "eject" media request.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_eject_pending(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *xsname, *str;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!vdp->xdf_media_req_supported)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((xsname = xvdi_get_xsname(dip)) == NULL) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (xenbus_read_str(xsname, XBP_MEDIA_REQ, &str) != 0))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (strcmp(str, XBV_MEDIA_REQ_EJECT) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_TRUE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Generate a media request.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_media_req(xdf_t *vdp, char *req, boolean_t media_required)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *xsname;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /*
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * we can't be holding xdf_dev_lk because xenbus_printf() can
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * block while waiting for a PIL 1 interrupt message. this
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * would cause a deadlock with xdf_intr() which needs to grab
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * xdf_dev_lk as well and runs at PIL 5.
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz ASSERT(MUTEX_NOT_HELD(&vdp->xdf_dev_lk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((xsname = xvdi_get_xsname(dip)) == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Check if we support media requests */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!XD_IS_CD(vdp) || !vdp->xdf_media_req_supported)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOTTY);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If an eject is pending then don't allow any new requests */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_eject_pending(vdp))
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Make sure that there is media present */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (media_required && (vdp->xdf_xdev_nblocks == 0))
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We only allow operations when the device is ready and connected */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state != XD_READY)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_printf(XBT_NULL, xsname, XBP_MEDIA_REQ, "%s", req) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * populate a single blkif_request_t w/ a buf
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_process_rreq(xdf_t *vdp, struct buf *bp, blkif_request_t *rreq)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz grant_ref_t gr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint8_t fsect, lsect;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz size_t bcnt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz paddr_t dma_addr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz off_t blk_off;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz blkif_vdev_t vdev = xvdi_get_vdevnum(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq = BP_VREQ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint64_t blkno = vreq->v_blkno;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint_t ndmacs = vreq->v_ndmacs;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_acc_handle_t acchdl = vdp->xdf_xb_ring_hdl;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int seg = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int isread = IS_READ(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ge_slot_t *gs = list_head(&vreq->v_gs);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vreq->v_status == VREQ_GS_ALLOCED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (isread)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->operation, BLKIF_OP_READ);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (vreq->v_flush_diskcache) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case FLUSH_DISKCACHE:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->operation,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_OP_FLUSH_DISKCACHE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put16(acchdl, &rreq->handle, vdev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put64(acchdl, &rreq->id,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (uint64_t)(uintptr_t)(gs));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->nr_segments, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_DMAWIN_DONE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case WRITE_BARRIER:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->operation,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_OP_WRITE_BARRIER);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz default:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!vdp->xdf_wce)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->operation,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_OP_WRITE_BARRIER);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->operation,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz BLKIF_OP_WRITE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put16(acchdl, &rreq->handle, vdev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put64(acchdl, &rreq->sector_number, blkno);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put64(acchdl, &rreq->id, (uint64_t)(uintptr_t)(gs));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * loop until all segments are populated or no more dma cookie in buf
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (;;) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Each segment of a blkif request can transfer up to
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * one 4K page of data.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bcnt = vreq->v_dmac.dmac_size;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dma_addr = vreq->v_dmac.dmac_laddress;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz blk_off = (uint_t)((paddr_t)XB_SEGOFFSET & dma_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz fsect = blk_off >> XB_BSHIFT;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz lsect = fsect + (bcnt >> XB_BSHIFT) - 1;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bcnt <= PAGESIZE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((bcnt % XB_BSIZE) == 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((blk_off & XB_BMASK) == 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(fsect < XB_MAX_SEGLEN / XB_BSIZE &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz lsect < XB_MAX_SEGLEN / XB_BSIZE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz gr = gs_grant(gs, PATOMA(dma_addr) >> PAGESHIFT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put32(acchdl, &rreq->seg[seg].gref, gr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->seg[seg].first_sect, fsect);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->seg[seg].last_sect, lsect);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, (
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: seg%d: dmacS %lu blk_off %ld\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, seg, vreq->v_dmac.dmac_size, blk_off));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, (
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: seg%d: fs %d ls %d gr %d dma 0x%"PRIx64"\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, seg, fsect, lsect, gr, dma_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz blkno += (bcnt >> XB_BSHIFT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz seg++;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(seg <= BLKIF_MAX_SEGMENTS_PER_REQUEST);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (--ndmacs) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_dma_nextcookie(vreq->v_dmahdl, &vreq->v_dmac);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz continue;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_status = VREQ_DMAWIN_DONE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vreq->v_blkno = blkno;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_put8(acchdl, &rreq->nr_segments, seg);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, (
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: xdf_process_rreq: request id=%"PRIx64" ready\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, rreq->id));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_io_start(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct buf *bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz v_req_t *vreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz blkif_request_t *rreq;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t rreqready = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Populate the ring request(s). Loop until there is no buf to
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * transfer or no free slot available in I/O ring.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (;;) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* don't start any new IO if we're suspending */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_suspending)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((bp = xdf_bp_next(vdp)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* if the buf doesn't already have a vreq, allocate one */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((vreq = BP_VREQ(bp)) == NULL) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((vreq = vreq_get(vdp, bp)) == NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* alloc DMA/GTE resources */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vreq_setup(vdp, vreq) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* get next blkif_request in the ring */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((rreq = xvdi_ring_get_request(vdp->xdf_xb_ring)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bzero(rreq, sizeof (blkif_request_t));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rreqready = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* populate blkif_request with this buf */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_process_rreq(vdp, bp, rreq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * This buffer/vreq pair is has been allocated a ring buffer
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * resources, so if it isn't already in our runq, add it.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!vreq->v_runq)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_waitq_to_runq(vdp, bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Send the request(s) to the backend */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rreqready)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_ring_push(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* check if partition is open, -1 - check all partitions on the disk */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic boolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_isopen(xdf_t *vdp, int partition)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int i;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ulong_t parbit;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t rval = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((partition == -1) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((partition >= 0) || (partition < XDF_PEXT)));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (partition == -1)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz parbit = (ulong_t)-1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz parbit = 1 << partition;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (i = 0; i < OTYPCNT; i++) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_vd_open[i] & parbit)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rval = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rval);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * The connection should never be closed as long as someone is holding
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * us open, there is pending IO, or someone is waiting waiting for a
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * connection.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic boolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_busy(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_xb_ring != NULL) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_ring_has_unconsumed_responses(vdp->xdf_xb_ring)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state != XD_CLOSED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!list_is_empty(&vdp->xdf_vreq_act) || (vdp->xdf_f_act != NULL)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state != XD_CLOSED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_isopen(vdp, -1)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state != XD_CLOSED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_connect_req > 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state != XD_CLOSED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_set_state(xdf_t *vdp, xdf_state_t new_state)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: state change %d -> %d\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, vdp->xdf_state, new_state));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_state = new_state;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_dev_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_disconnect(xdf_t *vdp, xdf_state_t new_state, boolean_t quiet)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t busy;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_NOT_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((new_state == XD_UNKNOWN) || (new_state == XD_CLOSED));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Check if we're already there. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == new_state)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz busy = xdf_busy(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If we're already closed then there's nothing todo. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_CLOSED) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(!busy);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, new_state);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef DEBUG
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* UhOh. Warn the user that something bad has happened. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!quiet && busy && (vdp->xdf_state == XD_READY) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_xdev_nblocks != 0)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: disconnected while in use",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* DEBUG */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_ring_destroy(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If we're busy then we can only go into the unknown state */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, (busy) ? XD_UNKNOWN : new_state);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* if we're closed now, let the other end know */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_CLOSED)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateClosed);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Kick-off connect process
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Status should be XD_UNKNOWN or XD_CLOSED
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * On success, status will be changed to XD_INIT
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * On error, it will be changed to XD_UNKNOWN
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_setstate_init(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xenbus_transaction_t xbt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz grant_ref_t gref;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *xsname, *str;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_NOT_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((vdp->xdf_state == XD_UNKNOWN) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_state == XD_CLOSED));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ("xdf@%s: starting connection process\n", vdp->xdf_addr));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * If an eject is pending then don't allow a new connection.
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * (Only the backend can clear media request eject request.)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (xdf_eject_pending(vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((xsname = xvdi_get_xsname(dip)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_peer = xvdi_get_oeid(dip)) == INVALID_DOMID)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateInitialising);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Sanity check for the existance of the xenbus device-type property.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * This property might not exist if we our xenbus device nodes was
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * force destroyed while we were still connected to the backend.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_read_str(xsname, XBP_DEV_TYPE, &str) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_alloc_evtchn(dip) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_evtchn = xvdi_get_evtchn(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef XPV_HVM_DRIVER
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ec_bind_evtchn_to_handler(vdp->xdf_evtchn, IPL_VBD, xdf_intr, vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_add_intr(dip, 0, NULL, NULL, xdf_intr, (caddr_t)vdp) !=
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: xdf_setstate_init: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "failed to add intr handler", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_alloc_ring(dip, BLKIF_RING_SIZE,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (union blkif_sring_entry), &gref, &vdp->xdf_xb_ring) !=
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: failed to alloc comm ring",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout2;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xb_ring_hdl = vdp->xdf_xb_ring->xr_acc_hdl; /* ugly!! */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Write into xenstore the info needed by backend
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicztrans_retry:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_transaction_start(&xbt)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: failed to start transaction",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_fatal_error(dip, EIO, "connect transaction init");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto fail_trans;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * XBP_PROTOCOL is written by the domain builder in the case of PV
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * domains. However, it is not written for HVM domains, so let's
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * write it here.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((rv = xenbus_printf(xbt, xsname,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_MEDIA_REQ, "%s", XBV_MEDIA_REQ_NONE)) != 0) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((rv = xenbus_printf(xbt, xsname,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_RING_REF, "%u", gref)) != 0) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((rv = xenbus_printf(xbt, xsname,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_EVENT_CHAN, "%u", vdp->xdf_evtchn)) != 0) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((rv = xenbus_printf(xbt, xsname,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_PROTOCOL, "%s", XEN_IO_PROTO_ABI_NATIVE)) != 0) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((rv = xvdi_switch_state(dip, xbt, XenbusStateInitialised)) > 0)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xenbus_transaction_end(xbt, 1);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_fatal_error(dip, rv, "connect transaction setup");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto fail_trans;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* kick-off connect process */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rv = xenbus_transaction_end(xbt, 0)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rv == EAGAIN)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto trans_retry;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_fatal_error(dip, rv, "connect transaction commit");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto fail_trans;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, XD_INIT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczfail_trans:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_free_ring(vdp->xdf_xb_ring);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerrout2:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef XPV_HVM_DRIVER
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ec_unbind_evtchn(vdp->xdf_evtchn);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) ddi_remove_intr(vdp->xdf_dip, 0, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerrout1:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_free_evtchn(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_evtchn = INVALID_EVTCHN;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerrout:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: failed to start connection to backend",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_get_flush_block(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Get a DEV_BSIZE aligned bufer
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_flush_mem = kmem_alloc(vdp->xdf_xdev_secsize * 2, KM_SLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cache_flush_block =
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China (char *)P2ROUNDUP((uintptr_t)(vdp->xdf_flush_mem),
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China (int)vdp->xdf_xdev_secsize);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_lb_rdwr(vdp->xdf_dip, TG_READ, vdp->xdf_cache_flush_block,
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China xdf_flush_block, vdp->xdf_xdev_secsize, NULL) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_setstate_ready(void *arg)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_ready_tq_thread = curthread;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We've created all the minor nodes via cmlb_attach() using default
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * value in xdf_attach() to make it possible to block in xdf_open(),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * in case there's anyone (say, booting thread) ever trying to open
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * it before connected to backend. We will refresh all those minor
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * nodes w/ latest info we've got now when we are almost connected.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_cmbl_reattach) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cmbl_reattach = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_cmlb_attach(vdp) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If we're not still trying to get to the ready state, then bail. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state != XD_CONNECTED) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If backend has feature-barrier, see if it supports disk
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * cache flush op.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_flush_supported = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_feature_barrier) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Pretend we already know flush is supported so probe
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * will attempt the correct op.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_flush_supported = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_lb_rdwr(vdp->xdf_dip, TG_WRITE, NULL, 0, 0, 0) == 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_flush_supported = B_TRUE;
63c3e6179df15229a074893be77318fc37933d2amrj } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_flush_supported = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If the other end does not support the cache flush op
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * then we must use a barrier-write to force disk
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * cache flushing. Barrier writes require that a data
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * block actually be written.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Cache a block to barrier-write when we are
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * asked to perform a flush.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * XXX - would it be better to just copy 1 block
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (512 bytes) from whatever write we did last
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * and rewrite that block?
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_get_flush_block(vdp) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_CONNECTED)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, XD_READY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Restart any currently queued up io */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * synthetic geometry
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define XDF_NSECTS 256
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#define XDF_NHEADS 16
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_synthetic_pgeom(dev_info_t *dip, cmlb_geom_t *geomp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint_t ncyl;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ncyl = vdp->xdf_xdev_nblocks / (XDF_NHEADS * XDF_NSECTS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bzero(geomp, sizeof (*geomp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_ncyl = ncyl == 0 ? 1 : ncyl;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_acyl = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_nhead = XDF_NHEADS;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_nsect = XDF_NSECTS;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China geomp->g_secsize = vdp->xdf_xdev_secsize;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_capacity = vdp->xdf_xdev_nblocks;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_intrlv = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz geomp->g_rpm = 7200;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Finish other initialization after we've connected to backend
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Status should be XD_INIT before calling this routine
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * On success, status should be changed to XD_CONNECTED.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * On error, status should stay XD_INIT
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_setstate_connected(xdf_t *vdp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip = vdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_geom_t pgeom;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t nblocks = 0;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China uint_t secsize = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *oename, *xsname, *str;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz uint_t dinfo;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_NOT_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state == XD_INIT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((xsname = xvdi_get_xsname(dip)) == NULL) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((oename = xvdi_get_oename(dip)) == NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /* Make sure the other end is XenbusStateConnected */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (xenbus_read_driver_state(oename) != XenbusStateConnected)
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz return (DDI_FAILURE);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Determine if feature barrier is supported by backend */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!(vdp->xdf_feature_barrier = xenbus_exists(oename, XBP_FB)))
5d03b6c34e8209515d5c25d3dfc5609ad2b7b5afMark Johnson cmn_err(CE_NOTE, "!xdf@%s: feature-barrier not supported",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Probe backend. Read the device size into xdf_xdev_nblocks
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * and set the VDISK_READONLY, VDISK_CDROM, and VDISK_REMOVABLE
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * flags in xdf_dinfo. If the emulated device type is "cdrom",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we always set VDISK_CDROM, regardless of if it's present in
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * the xenbus info parameter.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_gather(XBT_NULL, oename,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_SECTORS, "%"SCNu64, &nblocks,
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China XBP_SECTOR_SIZE, "%u", &secsize,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XBP_INFO, "%u", &dinfo,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: xdf_setstate_connected: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "cannot read backend info", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_read_str(xsname, XBP_DEV_TYPE, &str) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: cannot read device-type",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (strcmp(str, XBV_DEV_TYPE_CD) == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dinfo |= VDISK_CDROM;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (secsize == 0 || !(ISP2(secsize / DEV_BSIZE)))
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China secsize = DEV_BSIZE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_xdev_nblocks = nblocks;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_xdev_secsize = secsize;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef _ILP32
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_nblocks > DK_MAX_BLOCKS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: xdf_setstate_connected: "
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "backend disk device too large with %llu blocks for"
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz " 32-bit kernel", vdp->xdf_addr, vdp->xdf_xdev_nblocks);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_fatal_error(dip, EFBIG, "reading backend info");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If the physical geometry for a fixed disk has been explicity
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * set then make sure that the specified physical geometry isn't
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * larger than the device we connected to.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_pgeom_fixed &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_pgeom.g_capacity > vdp->xdf_xdev_nblocks)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: connect failed, fixed geometry too large",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_media_req_supported = xenbus_exists(oename, XBP_MEDIA_REQ_SUP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* mark vbd is ready for I/O */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, XD_CONNECTED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* check if the cmlb label should be updated */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_synthetic_pgeom(dip, &pgeom);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_dinfo != dinfo) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (!vdp->xdf_pgeom_fixed &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (memcmp(&vdp->xdf_pgeom, &pgeom, sizeof (pgeom)) != 0))) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cmbl_reattach = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_dinfo = dinfo;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!vdp->xdf_pgeom_fixed)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom = pgeom;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (XD_IS_CD(vdp) || XD_IS_RM(vdp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_xdev_nblocks == 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_mstate = DKIO_EJECTED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_mstate_cv);
b1a3e7f1642868df84107f6eb9f823e0b02c1ac3mrj } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_mstate = DKIO_INSERTED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_mstate_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_mstate != DKIO_NONE) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_mstate = DKIO_NONE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_mstate_cv);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_CONT, "?xdf@%s: %"PRIu64" blocks", vdp->xdf_addr,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (uint64_t)vdp->xdf_xdev_nblocks);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Restart any currently queued up io */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * To get to the ready state we have to do IO to the backend device,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * but we can't initiate IO from the other end change callback thread
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (which is the current context we're executing in.) This is because
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * if the other end disconnects while we're doing IO from the callback
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * thread, then we can't recieve that disconnect event and we hang
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * waiting for an IO that can never complete.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) ddi_taskq_dispatch(vdp->xdf_ready_tq, xdf_setstate_ready, vdp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_SLEEP);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xvdi_switch_state(dip, XBT_NULL, XenbusStateConnected);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_oe_change(dev_info_t *dip, ddi_eventcookie_t id, void *arg, void *impl_data)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XenbusState new_state = *(XenbusState *)impl_data;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: otherend state change to %d!\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, new_state));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We assume that this callback is single threaded */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_oe_change_thread == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DEBUG_EVAL(vdp->xdf_oe_change_thread = curthread);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* ignore any backend state changes if we're suspending/suspended */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_suspending || (vdp->xdf_state == XD_SUSPEND)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DEBUG_EVAL(vdp->xdf_oe_change_thread = NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (new_state) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateUnknown:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateInitialising:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateInitWait:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateInitialised:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_INIT)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_setstate_init(vdp) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state == XD_INIT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateConnected:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_state == XD_CONNECTED) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_state == XD_READY))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state != XD_INIT) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_setstate_init(vdp) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state == XD_INIT);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_setstate_connected(vdp) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_UNKNOWN, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state == XD_CONNECTED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateClosing:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_isopen(vdp, -1)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_NOTE,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: hot-unplug failed, still in use",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*FALLTHROUGH*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case XenbusStateClosed:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_CLOSED, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* notify anybody waiting for oe state change */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_dev_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DEBUG_EVAL(vdp->xdf_oe_change_thread = NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_connect_locked(xdf_t *vdp, boolean_t wait)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz int rv, timeouts = 0, reset = 20;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* we can't connect once we're in the closed state */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state == XD_CLOSED)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (XD_CLOSED);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_connect_req++;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (vdp->xdf_state != XD_READY) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /* only one thread at a time can be the connection thread */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_connect_thread == NULL)
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz vdp->xdf_connect_thread = curthread;
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_connect_thread == curthread) {
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if ((timeouts > 0) && ((timeouts % reset) == 0)) {
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /*
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * If we haven't establised a connection
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * within the reset time, then disconnect
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * so we can try again, and double the reset
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * time. The reset time starts at 2 sec.
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz (void) xdf_disconnect(vdp, XD_UNKNOWN, B_TRUE);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz reset *= 2;
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz }
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_state == XD_UNKNOWN)
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz (void) xdf_setstate_init(vdp);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_state == XD_INIT)
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz (void) xdf_setstate_connected(vdp);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz }
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!wait || (vdp->xdf_state == XD_READY))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto out;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit((&vdp->xdf_cb_lk));
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_connect_thread != curthread) {
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz rv = cv_wait_sig(&vdp->xdf_dev_cv, &vdp->xdf_dev_lk);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz } else {
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /* delay for 0.1 sec */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni rv = cv_reltimedwait_sig(&vdp->xdf_dev_cv,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &vdp->xdf_dev_lk, drv_usectohz(100*1000),
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni TR_CLOCK_TICK);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (rv == -1)
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz timeouts++;
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit((&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter((&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter((&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (rv == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto out;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczout:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz if (vdp->xdf_connect_thread == curthread) {
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz /*
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * wake up someone else so they can become the connection
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz * thread.
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz cv_signal(&vdp->xdf_dev_cv);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz vdp->xdf_connect_thread = NULL;
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz }
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Try to lock the media */
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz mutex_exit((&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_media_req(vdp, XBV_MEDIA_REQ_LOCK, B_TRUE);
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz mutex_enter((&vdp->xdf_dev_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_connect_req--;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (vdp->xdf_state);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic uint_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_iorestart(caddr_t arg)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)arg;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp != NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
a6e5dd18ce1ac2c94bbb09fbb01867dc6effa694cz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(ISDMACBON(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz SETDMACBOFF(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_INTR_CLAIMED);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicztypedef struct xdf_hvm_entry {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_node_t xdf_he_list;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *xdf_he_path;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *xdf_he_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz} xdf_hvm_entry_t;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic list_t xdf_hvm_list;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic kmutex_t xdf_hvm_list_lock;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic xdf_hvm_entry_t *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczi_xdf_hvm_find(const char *path, dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_entry_t *i;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((path != NULL) || (dip != NULL));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&xdf_hvm_list_lock));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i = list_head(&xdf_hvm_list);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (i != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((path != NULL) && strcmp(i->xdf_he_path, path) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i = list_next(&xdf_hvm_list, i);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz continue;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((dip != NULL) && (i->xdf_he_dip != dip)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i = list_next(&xdf_hvm_list, i);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz continue;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (i);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczdev_info_t *
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_hold(const char *path)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_entry_t *i;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_info_t *dip;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i = i_xdf_hvm_find(path, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (i == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ndi_hold_devi(dip = i->xdf_he_dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_add(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_entry_t *i;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *path;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* figure out the path for the dip */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) ddi_pathname(dip, path);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i = kmem_alloc(sizeof (*i), KM_SLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i->xdf_he_dip = dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz i->xdf_he_path = i_ddi_strdup(path, KM_SLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(i_xdf_hvm_find(path, NULL) == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(i_xdf_hvm_find(NULL, dip) == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_insert_head(&xdf_hvm_list, i);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&xdf_hvm_list_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_free(path, MAXPATHLEN);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_rm(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_entry_t *i;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz VERIFY((i = i_xdf_hvm_find(NULL, dip)) != NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_remove(&xdf_hvm_list, i);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&xdf_hvm_list_lock);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_free(i->xdf_he_path, strlen(i->xdf_he_path) + 1);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_free(i, sizeof (*i));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_init(void)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_create(&xdf_hvm_list, sizeof (xdf_hvm_entry_t),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz offsetof(xdf_hvm_entry_t, xdf_he_list));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_init(&xdf_hvm_list_lock, NULL, MUTEX_DEFAULT, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_fini(void)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(list_head(&xdf_hvm_list) == NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_destroy(&xdf_hvm_list);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_destroy(&xdf_hvm_list_lock);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczboolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_connect(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *oename, *str;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Before try to establish a connection we need to wait for the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * backend hotplug scripts to have run. Once they are run the
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * "<oename>/hotplug-status" property will be set to "connected".
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz for (;;) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Get the xenbus path to the backend device. Note that
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we can't cache this path (and we look it up on each pass
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * through this loop) because it could change during
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * suspend, resume, and migration operations.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((oename = xvdi_get_oename(dip)) == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz str = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((xenbus_read_str(oename, XBP_HP_STATUS, &str) == 0) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (strcmp(str, XBV_HP_STATUS_CONN) == 0))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (str != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* wait for an update to "<oename>/hotplug-status" */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cv_wait_sig(&vdp->xdf_hp_status_cv, &vdp->xdf_cb_lk) == 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* we got interrupted by a signal */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Good news. The backend hotplug scripts have been run. */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(MUTEX_HELD(&vdp->xdf_cb_lk));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(strcmp(str, XBV_HP_STATUS_CONN) == 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If we're emulating a cd device and if the backend doesn't support
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * media request opreations, then we're not going to bother trying
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * to establish a connection for a couple reasons. First off, media
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * requests support is required to support operations like eject and
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * media locking. Second, other backend platforms like Linux don't
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * support hvm pv cdrom access. They don't even have a backend pv
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * driver for cdrom device nodes, so we don't want to block forever
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * waiting for a connection to a backend driver that doesn't exist.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (XD_IS_CD(vdp) && !xenbus_exists(oename, XBP_MEDIA_REQ_SUP)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
2de7185c750441776d8007f1506194162e80b273Edward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_connect_locked(vdp, B_TRUE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return ((rv == XD_READY) ? B_TRUE : B_FALSE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edpint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_hvm_setpgeom(dev_info_t *dip, cmlb_geom_t *geomp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* sanity check the requested physical geometry */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((geomp->g_secsize != XB_BSIZE) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (geomp->g_capacity == 0)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * If we've already connected to the backend device then make sure
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we're not defining a physical geometry larger than our backend
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * device.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_xdev_nblocks != 0) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (geomp->g_capacity > vdp->xdf_xdev_nblocks)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (EINVAL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bzero(&vdp->xdf_pgeom, sizeof (vdp->xdf_pgeom));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_ncyl = geomp->g_ncyl;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_acyl = geomp->g_acyl;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_nhead = geomp->g_nhead;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_nsect = geomp->g_nsect;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_secsize = geomp->g_secsize;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_capacity = geomp->g_capacity;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_intrlv = geomp->g_intrlv;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom.g_rpm = geomp->g_rpm;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom_fixed = B_TRUE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* force a re-validation */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_invalidate(vdp->xdf_vd_lbl, NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczboolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_is_cd(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t rv;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = XD_IS_CD(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczboolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_is_rm(dev_info_t *dip)
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t rv;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = XD_IS_RM(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczboolean_t
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_media_req_supported(dev_info_t *dip)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t rv;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = vdp->xdf_media_req_supported;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_getcap(dev_info_t *dip, diskaddr_t *capp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (vdp == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp *capp = vdp->xdf_pgeom.g_capacity;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(LBL_DBG, ("xdf@%s:capacity %llu\n", vdp->xdf_addr, *capp));
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_getpgeom(dev_info_t *dip, cmlb_geom_t *geomp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev xdf_t *vdp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip))) == NULL)
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp *geomp = vdp->xdf_pgeom;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
843e19887f64dde75055cf8842fc4db2171eff45johnlev * No real HBA, no geometry available from it
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_getvgeom(dev_info_t *dip, cmlb_geom_t *geomp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (EINVAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_getattribute(dev_info_t *dip, tg_attribute_t *tgattributep)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev xdf_t *vdp;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!(vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip))))
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev if (XD_IS_RO(vdp))
843e19887f64dde75055cf8842fc4db2171eff45johnlev tgattributep->media_is_writable = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev else
843e19887f64dde75055cf8842fc4db2171eff45johnlev tgattributep->media_is_writable = 1;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/* ARGSUSED3 */
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edpint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_getinfo(dev_info_t *dip, int cmd, void *arg, void *tg_cookie)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China int instance;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China xdf_t *vdp;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China instance = ddi_get_instance(dip);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if ((vdp = ddi_get_soft_state(xdf_ssp, instance)) == NULL)
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China return (ENXIO);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
843e19887f64dde75055cf8842fc4db2171eff45johnlev switch (cmd) {
843e19887f64dde75055cf8842fc4db2171eff45johnlev case TG_GETPHYGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_lb_getpgeom(dip, (cmlb_geom_t *)arg));
843e19887f64dde75055cf8842fc4db2171eff45johnlev case TG_GETVIRTGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_lb_getvgeom(dip, (cmlb_geom_t *)arg));
843e19887f64dde75055cf8842fc4db2171eff45johnlev case TG_GETCAPACITY:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_lb_getcap(dip, (diskaddr_t *)arg));
843e19887f64dde75055cf8842fc4db2171eff45johnlev case TG_GETBLOCKSIZE:
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China mutex_enter(&vdp->xdf_cb_lk);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China *(uint32_t *)arg = vdp->xdf_xdev_secsize;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China mutex_exit(&vdp->xdf_cb_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev case TG_GETATTR:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_lb_getattribute(dip, (tg_attribute_t *)arg));
843e19887f64dde75055cf8842fc4db2171eff45johnlev default:
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (ENOTTY);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/* ARGSUSED5 */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_lb_rdwr(dev_info_t *dip, uchar_t cmd, void *bufp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t start, size_t reqlen, void *tg_cookie)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct buf *bp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int err = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We don't allow IO from the oe_change callback thread */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(curthread != vdp->xdf_oe_change_thread);
a576ab5b6e08c47732b3dedca9eaa8a8cbb85720rab
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if ((start + ((reqlen / (vdp->xdf_xdev_secsize / DEV_BSIZE))
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China >> DEV_BSHIFT)) > vdp->xdf_pgeom.g_capacity)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp = getrbuf(KM_SLEEP);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmd == TG_READ)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_flags = B_BUSY | B_READ;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_flags = B_BUSY | B_WRITE;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_un.b_addr = bufp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_bcount = reqlen;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China bp->b_blkno = start * (vdp->xdf_xdev_secsize / DEV_BSIZE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_edev = DDI_DEV_T_NONE; /* don't have dev_t */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_bp_push(vdp, bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (curthread == vdp->xdf_ready_tq_thread)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_ring_drain(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz err = biowait(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(bp->b_flags & B_DONE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz freerbuf(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Lock the current media. Set the media state to "lock".
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (Media locks are only respected by the backend driver.)
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ioctl_mlock(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_media_req(vdp, XBV_MEDIA_REQ_LOCK, B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Release a media lock. Set the media state to "none".
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ioctl_munlock(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_media_req(vdp, XBV_MEDIA_REQ_NONE, B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Eject the current media. Ignores any media locks. (Media locks
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * are only for benifit of the the backend.)
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ioctl_eject(xdf_t *vdp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
843e19887f64dde75055cf8842fc4db2171eff45johnlev int rv;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((rv = xdf_media_req(vdp, XBV_MEDIA_REQ_EJECT, B_FALSE)) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We've set the media requests xenbus parameter to eject, so now
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * disconnect from the backend, wait for the backend to clear
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * the media requets xenbus paramter, and then we can reconnect
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * to the backend.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_disconnect(vdp, XD_UNKNOWN, B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_connect_locked(vdp, B_TRUE) != XD_READY) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Watch for media state changes. This can be an insertion of a device
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * (triggered by a 'xm block-configure' request in another domain) or
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * the ejection of a device (triggered by a local "eject" operation).
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * For a full description of the DKIOCSTATE ioctl behavior see dkio(7I).
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_dkstate(xdf_t *vdp, enum dkio_state mstate)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz enum dkio_state prev_state;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz prev_state = vdp->xdf_mstate;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_mstate == mstate) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz while (vdp->xdf_mstate == prev_state) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cv_wait_sig(&vdp->xdf_mstate_cv,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &vdp->xdf_cb_lk) == 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINTR);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((prev_state != DKIO_INSERTED) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (vdp->xdf_mstate == DKIO_INSERTED)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_media_req(vdp, XBV_MEDIA_REQ_LOCK, B_TRUE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp }
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int *rvalp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rv;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (!xdf_isopen(vdp, part)))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IOCTL_DBG, ("xdf@%s:ioctl: cmd %d (0x%x)\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, cmd, cmd));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (cmd) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz default:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOTTY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCG_PHYGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCG_VIRTGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSGEOM:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGAPART:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSAPART:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGVTOC:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSVTOC:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCPARTINFO:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGEXTVTOC:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSEXTVTOC:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCEXTPARTINFO:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGMBOOT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSMBOOT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGETEFI:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSETEFI:
aa1b14e7d68925d80eebf0ce8ed0b9cc55246546Sheshadri Vasudevan case DKIOCSETEXTPART:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCPARTITION:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (cmlb_ioctl(vdp->xdf_vd_lbl, dev, cmd, arg, mode, credp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rvalp, NULL));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case FDEJECT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCEJECT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case CDROMEJECT:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_ioctl_eject(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCLOCK:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_ioctl_mlock(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCUNLOCK:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_ioctl_munlock(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case CDROMREADOFFSET: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int offset = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!XD_IS_CD(vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOTTY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&offset, (void *)arg, sizeof (int), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
342440ec94087b8c751c580ab9ed6c693d31d418Prasad Singamsetty }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGMEDIAINFO: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct dk_minfo media_info;
342440ec94087b8c751c580ab9ed6c693d31d418Prasad Singamsetty
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China media_info.dki_lbsize = vdp->xdf_xdev_secsize;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz media_info.dki_capacity = vdp->xdf_pgeom.g_capacity;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (XD_IS_CD(vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz media_info.dki_media_type = DK_CDROM;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz media_info.dki_media_type = DK_FIXED_DISK;
342440ec94087b8c751c580ab9ed6c693d31d418Prasad Singamsetty
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&media_info, (void *)arg,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (struct dk_minfo), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCINFO: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct dk_cinfo info;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* controller information */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (XD_IS_CD(vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_ctype = DKC_CDROM;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz else
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_ctype = DKC_VBD;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_cnum = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) strncpy((char *)(&info.dki_cname), "xdf", 8);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* unit information */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_unit = ddi_get_instance(vdp->xdf_dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) strncpy((char *)(&info.dki_dname), "xdf", 8);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_flags = DKI_FMTVOL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_partition = part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_maxtransfer = maxphys / DEV_BSIZE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_addr = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_space = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_prio = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz info.dki_vec = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&info, (void *)arg, sizeof (info), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSTATE: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz enum dkio_state mstate;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyin((void *)arg, &mstate,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (mstate), mode) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((rv = xdf_dkstate(vdp, mstate)) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mstate = vdp->xdf_mstate;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&mstate, (void *)arg,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (mstate), mode) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCREMOVABLE: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int i = BOOLEAN2VOID(XD_IS_RM(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&i, (caddr_t)arg, sizeof (i), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCGETWCE: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int i = BOOLEAN2VOID(XD_IS_RM(vdp));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyout(&i, (void *)arg, sizeof (i), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCSETWCE: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int i;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_copyin((void *)arg, &i, sizeof (i), mode))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EFAULT);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_wce = VOID2BOOLEAN(i);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DKIOCFLUSHWRITECACHE: {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct dk_callback *dkc = (struct dk_callback *)arg;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_flush_supported) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_lb_rdwr(vdp->xdf_dip, TG_WRITE,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, 0, 0, (void *)dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else if (vdp->xdf_feature_barrier &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz !xdf_barrier_flush_disable) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = xdf_lb_rdwr(vdp->xdf_dip, TG_WRITE,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cache_flush_block, xdf_flush_block,
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_xdev_secsize, (void *)dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOTTY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((mode & FKIOCTL) && (dkc != NULL) &&
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (dkc->dkc_callback != NULL)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (*dkc->dkc_callback)(dkc->dkc_cookie, rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* need to return 0 after calling callback */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz rv = 0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*NOTREACHED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_strategy(struct buf *bp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkct, p_blkst;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China daddr_t blkno;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ulong_t nblks;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(bp->b_edev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, ENXIO, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We don't allow IO from the oe_change callback thread */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(curthread != vdp->xdf_oe_change_thread);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Check for writes to a read only device */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!IS_READ(bp) && XD_IS_RO(vdp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, EROFS, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Check if this I/O is accessing a partition or the entire disk */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((long)bp->b_private == XB_SLICE_NONE) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* This I/O is using an absolute offset */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz p_blkct = vdp->xdf_xdev_nblocks;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz p_blkst = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* This I/O is using a partition relative offset */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkct,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &p_blkst, NULL, NULL, NULL)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, ENXIO, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China /*
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China * Adjust the real blkno and bcount according to the underline
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China * physical sector size.
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China */
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China blkno = bp->b_blkno / (vdp->xdf_xdev_secsize / XB_BSIZE);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* check for a starting block beyond the disk or partition limit */
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (blkno > p_blkct) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: block %lld exceeds VBD size %"PRIu64,
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_addr, (longlong_t)blkno, (uint64_t)p_blkct));
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_err(bp, EINVAL, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Legacy: don't set error flag at this case */
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (blkno == p_blkct) {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_resid = bp->b_bcount;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz biodone(bp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* sanitize the input buf */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioerror(bp, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_resid = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->av_back = bp->av_forw = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Adjust for partial transfer, this will result in an error later */
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (vdp->xdf_xdev_secsize != 0 &&
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_xdev_secsize != XB_BSIZE) {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China nblks = bp->b_bcount / vdp->xdf_xdev_secsize;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China } else {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China nblks = bp->b_bcount >> XB_BSHIFT;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China }
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if ((blkno + nblks) > p_blkct) {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (vdp->xdf_xdev_secsize != 0 &&
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_xdev_secsize != XB_BSIZE) {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China bp->b_resid =
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China ((blkno + nblks) - p_blkct) *
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_xdev_secsize;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China } else {
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China bp->b_resid =
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China ((blkno + nblks) - p_blkct) <<
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China XB_BSHIFT;
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_bcount -= bp->b_resid;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: strategy blk %lld len %lu\n",
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_addr, (longlong_t)blkno, (ulong_t)bp->b_bcount));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Fix up the buf struct */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_flags |= B_BUSY;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bp->b_private = (void *)(uintptr_t)p_blkst;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_bp_push(vdp, bp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (do_polled_io)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_ring_drain(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_read(dev_t dev, struct uio *uiop, cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkcnt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: read offset 0x%"PRIx64"\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, (int64_t)uiop->uio_offset));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkcnt,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL, NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China return (ENOSPC);
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (U_INVAL(uiop))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (physio(xdf_strategy, NULL, dev, B_READ, xdfmin, uiop));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_write(dev_t dev, struct uio *uiop, cred_t *credp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkcnt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: write offset 0x%"PRIx64"\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, (int64_t)uiop->uio_offset));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkcnt,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL, NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOSPC);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (U_INVAL(uiop))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (physio(xdf_strategy, NULL, dev, B_WRITE, xdfmin, uiop));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_aread(dev_t dev, struct aio_req *aiop, cred_t *credp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct uio *uiop = aiop->aio_uio;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkcnt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkcnt,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL, NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOSPC);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (U_INVAL(uiop))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (aphysio(xdf_strategy, anocancel, dev, B_READ, xdfmin, aiop));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
843e19887f64dde75055cf8842fc4db2171eff45johnlevstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_awrite(dev_t dev, struct aio_req *aiop, cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct uio *uiop = aiop->aio_uio;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkcnt;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkcnt,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL, NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if (uiop->uio_loffset >= XB_DTOB(p_blkcnt, vdp))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENOSPC);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (U_INVAL(uiop))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (aphysio(xdf_strategy, anocancel, dev, B_WRITE, xdfmin, aiop));
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz struct buf dumpbuf, *dbp = &dumpbuf;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int err = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkcnt, p_blkst;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(IO_DBG, ("xdf@%s: dump addr (0x%p) blk (%ld) nblks (%d)\n",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr, (void *)addr, blkno, nblk));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* We don't allow IO from the oe_change callback thread */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(curthread != vdp->xdf_oe_change_thread);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkcnt, &p_blkst,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China if ((blkno + nblk) >
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China (p_blkcnt * (vdp->xdf_xdev_secsize / XB_BSIZE))) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: block %ld exceeds VBD size %"PRIu64,
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China vdp->xdf_addr, (daddr_t)((blkno + nblk) /
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China (vdp->xdf_xdev_secsize / XB_BSIZE)), (uint64_t)p_blkcnt);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz bioinit(dbp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_flags = B_BUSY;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_un.b_addr = addr;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_bcount = nblk << DEV_BSHIFT;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_blkno = blkno;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_edev = dev;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dbp->b_private = (void *)(uintptr_t)p_blkst;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_bp_push(vdp, dbp);
843e19887f64dde75055cf8842fc4db2171eff45johnlev mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_io_start(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz err = xdf_ring_drain(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz biofini(dbp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (err);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_close(dev_t dev, int flag, int otyp, struct cred *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ulong_t parbit;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(dev);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!xdf_isopen(vdp, part)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz parbit = 1 << part;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((vdp->xdf_vd_open[otyp] & parbit) != 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (otyp == OTYP_LYR) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_vd_lyropen[part] > 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (--vdp->xdf_vd_lyropen[part] == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_open[otyp] &= ~parbit;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_open[otyp] &= ~parbit;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_exclopen &= ~parbit;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_open(dev_t *devp, int flag, int otyp, cred_t *credp)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor_t minor;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ulong_t parbit;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz diskaddr_t p_blkct = 0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t firstopen;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t nodelay;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz minor = getminor(*devp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, XDF_INST(minor))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodelay = (flag & (FNDELAY | FNONBLOCK));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: opening\n", vdp->xdf_addr));
a6e5dd18ce1ac2c94bbb09fbb01867dc6effa694cz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* do cv_wait until connected or failed */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (!nodelay && (xdf_connect_locked(vdp, B_TRUE) != XD_READY)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((flag & FWRITE) && XD_IS_RO(vdp)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EROFS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz part = XDF_PART(minor);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz parbit = 1 << part;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_vd_exclopen & parbit) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((flag & FEXCL) && xdf_isopen(vdp, part))) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EBUSY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* are we the first one to open this node? */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz firstopen = !xdf_isopen(vdp, -1);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (otyp == OTYP_LYR)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_lyropen[part]++;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_open[otyp] |= parbit;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (flag & FEXCL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_exclopen |= parbit;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* force a re-validation */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (firstopen)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_invalidate(vdp->xdf_vd_lbl, NULL);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* If this is a non-blocking open then we're done */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (nodelay)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * This is a blocking open, so we require:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * - that the disk have a valid label on it
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * - that the size of the partition that we're opening is non-zero
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((cmlb_partinfo(vdp->xdf_vd_lbl, part, &p_blkct,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, NULL, NULL, NULL) != 0) || (p_blkct == 0)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xdf_close(*devp, flag, otyp, credp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ENXIO);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic void
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_watch_hp_status_cb(dev_info_t *dip, const char *path, void *arg)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = (xdf_t *)ddi_get_driver_private(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_broadcast(&vdp->xdf_hp_status_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int flags,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *name, caddr_t valuep, int *lengthp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Sanity check that if a dev_t or dip were specified that they
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * correspond to this device driver. On debug kernels we'll
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * panic and on non-debug kernels we'll return failure.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(ddi_driver_major(dip) == xdf_major);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT((dev == DDI_DEV_T_ANY) || (getmajor(dev) == xdf_major));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((ddi_driver_major(dip) != xdf_major) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((dev != DDI_DEV_T_ANY) && (getmajor(dev) != xdf_major)))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_PROP_NOT_FOUND);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (ddi_prop_op(dev, dip, prop_op, flags,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz name, valuep, lengthp));
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (cmlb_prop_op(vdp->xdf_vd_lbl,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev, dip, prop_op, flags, name, valuep, lengthp,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XDF_PART(getminor(dev)), NULL));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **rp)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int instance = XDF_INST(getminor((dev_t)arg));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vbdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (cmd) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_INFO_DEVT2DEVINFO:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vbdp = ddi_get_soft_state(xdf_ssp, instance)) == NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *rp = NULL;
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *rp = vbdp->xdf_dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_INFO_DEVT2INSTANCE:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz *rp = (void *)(uintptr_t)instance;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev default:
843e19887f64dde75055cf8842fc4db2171eff45johnlev return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*ARGSUSED*/
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_resume(dev_info_t *dip)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *oename;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, ddi_get_instance(dip))) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto err;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_resume\n", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_resume(dip) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto err;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((oename = xvdi_get_oename(dip)) == NULL) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (xvdi_add_xb_watch_handler(dip, oename, XBP_HP_STATUS,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_watch_hp_status_cb, NULL) != DDI_SUCCESS)) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto err;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(vdp->xdf_state != XD_READY);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, XD_UNKNOWN);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_dev_lk);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_setstate_init(vdp) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto err;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_resume: done\n", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerr:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_resume: fail\n", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
843e19887f64dde75055cf8842fc4db2171eff45johnlev{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int n, instance = ddi_get_instance(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_iblock_cookie_t ibc, softibc;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz boolean_t dev_iscd = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz char *oename, *xsname, *str;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_NOTPROM,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf_debug", 0)) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_debug = n;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (cmd) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_RESUME:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_resume(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_ATTACH:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz default:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* DDI_ATTACH */
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (((xsname = xvdi_get_xsname(dip)) == NULL) ||
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ((oename = xvdi_get_oename(dip)) == NULL))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Disable auto-detach. This is necessary so that we don't get
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * detached while we're disconnected from the back end.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((ddi_prop_update_int(DDI_DEV_T_NONE, dip,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_NO_AUTODETACH, 1) != DDI_PROP_SUCCESS))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* driver handles kernel-issued IOCTLs */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_prop_create(DDI_DEV_T_NONE, dip,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_PROP_CANSLEEP, DDI_KERNEL_IOCTL, NULL, 0) != DDI_PROP_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_get_iblock_cookie(dip, 0, &ibc) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_get_soft_iblock_cookie(dip,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DDI_SOFTINT_LOW, &softibc) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xenbus_read_str(xsname, XBP_DEV_TYPE, &str) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: cannot read device-type",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (strcmp(str, XBV_DEV_TYPE_CD) == 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz dev_iscd = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz strfree(str);
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_soft_state_zalloc(xdf_ssp, instance) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: attaching\n", ddi_get_name_addr(dip)));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, instance);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_set_driver_private(dip, vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_dip = dip;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_addr = ddi_get_name_addr(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_suspending = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_media_req_supported = B_FALSE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_peer = INVALID_DOMID;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_evtchn = INVALID_EVTCHN;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_create(&vdp->xdf_vreq_act, sizeof (v_req_t),
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz offsetof(v_req_t, v_link));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_init(&vdp->xdf_dev_cv, NULL, CV_DEFAULT, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_init(&vdp->xdf_hp_status_cv, NULL, CV_DEFAULT, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_init(&vdp->xdf_mstate_cv, NULL, CV_DEFAULT, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_init(&vdp->xdf_dev_lk, NULL, MUTEX_DRIVER, (void *)ibc);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_init(&vdp->xdf_cb_lk, NULL, MUTEX_DRIVER, (void *)ibc);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_init(&vdp->xdf_iostat_lk, NULL, MUTEX_DRIVER, (void *)ibc);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_cmbl_reattach = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (dev_iscd) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_dinfo |= VDISK_CDROM;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_mstate = DKIO_EJECTED;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz } else {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_mstate = DKIO_NONE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp->xdf_ready_tq = ddi_taskq_create(dip, "xdf_ready_tq",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz 1, TASKQ_DEFAULTPRI, 0)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_add_xb_watch_handler(dip, oename, XBP_HP_STATUS,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_watch_hp_status_cb, NULL) != DDI_SUCCESS)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &vdp->xdf_softintr_id,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &softibc, NULL, xdf_iorestart, (caddr_t)vdp) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: failed to add softintr",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
843e19887f64dde75055cf8842fc4db2171eff45johnlev /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Initialize the physical geometry stucture. Note that currently
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we don't know the size of the backend device so the number
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * of blocks on the device will be initialized to zero. Once
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we connect to the backend device we'll update the physical
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * geometry to reflect the real size of the device.
843e19887f64dde75055cf8842fc4db2171eff45johnlev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_synthetic_pgeom(dip, &vdp->xdf_pgeom);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_pgeom_fixed = B_FALSE;
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * create default device minor nodes: non-removable disk
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * we will adjust minor nodes after we are connected w/ backend
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_alloc_handle(&vdp->xdf_vd_lbl);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_cmlb_attach(vdp) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "xdf@%s: attach failed, cmlb attach failed",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout0;
843e19887f64dde75055cf8842fc4db2171eff45johnlev }
843e19887f64dde75055cf8842fc4db2171eff45johnlev
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * We ship with cache-enabled disks
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_wce = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Watch backend XenbusState change */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xvdi_add_event_handler(dip,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz XS_OE_STATE, xdf_oe_change, NULL) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout0;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_setstate_init(vdp) != DDI_SUCCESS) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: start connection failed",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_add(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* Report our version to dom0. */
349b53dd4e695e3d833b5380540385145b2d3ae8Stuart Maybee if (xenbus_printf(XBT_NULL, "guest/xdf", "version", "%d",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz HVMPV_XDF_VERS))
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf: couldn't write version\n");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#else /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* create kstat for iostat(1M) */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_kstat_create(dip, "xdf", instance) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: failed to create kstat",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz goto errout1;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* !XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_report_dev(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: attached\n", vdp->xdf_addr));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerrout1:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xvdi_switch_state(vdp->xdf_dip, XBT_NULL, XenbusStateClosed);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_remove_event_handler(dip, XS_OE_STATE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczerrout0:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_vd_lbl != NULL) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_detach(vdp->xdf_vd_lbl, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_free_handle(&vdp->xdf_vd_lbl);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_vd_lbl = NULL;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_softintr_id != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_remove_softintr(vdp->xdf_softintr_id);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_remove_xb_watch_handlers(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_ready_tq != NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_taskq_destroy(vdp->xdf_ready_tq);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_destroy(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_destroy(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_destroy(&vdp->xdf_dev_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_destroy(&vdp->xdf_hp_status_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_soft_state_free(xdf_ssp, instance);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_set_driver_private(dip, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_prop_remove_all(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmn_err(CE_WARN, "xdf@%s: attach failed", ddi_get_name_addr(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
843e19887f64dde75055cf8842fc4db2171eff45johnlev}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_suspend(dev_info_t *dip)
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int instance = ddi_get_instance(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((vdp = ddi_get_soft_state(xdf_ssp, instance)) == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_suspend\n", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_suspend(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp mutex_enter(&vdp->xdf_dev_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_suspending = B_TRUE;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_ring_destroy(vdp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_set_state(vdp, XD_SUSPEND);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp->xdf_suspending = B_FALSE;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp mutex_exit(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_debug & SUSRES_DBG)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xen_printf("xdf@%s: xdf_suspend: done\n", vdp->xdf_addr);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic int
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczxdf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_t *vdp;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int instance;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz switch (cmd) {
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_PM_SUSPEND:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_SUSPEND:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (xdf_suspend(dip));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz case DDI_DETACH:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz break;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz default:
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp }
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz instance = ddi_get_instance(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DPRINTF(DDI_DBG, ("xdf@%s: detaching\n", ddi_get_name_addr(dip)));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz vdp = ddi_get_soft_state(xdf_ssp, instance);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp == NULL)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_enter(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_disconnect(vdp, XD_CLOSED, B_FALSE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_state != XD_CLOSED) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_FAILURE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_exit(&vdp->xdf_cb_lk);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ASSERT(!ISDMACBON(vdp));
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_rm(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_timeout_id != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) untimeout(vdp->xdf_timeout_id);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_remove_event_handler(dip, XS_OE_STATE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_taskq_destroy(vdp->xdf_ready_tq);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_detach(vdp->xdf_vd_lbl, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cmlb_free_handle(&vdp->xdf_vd_lbl);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz /* we'll support backend running in domU later */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#ifdef DOMU_BACKEND
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz (void) xvdi_post_event(dip, XEN_HP_REMOVE);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz list_destroy(&vdp->xdf_vreq_act);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_prop_remove_all(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_kstat_delete(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_remove_softintr(vdp->xdf_softintr_id);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xvdi_remove_xb_watch_handlers(dip);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_set_driver_private(dip, NULL);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz cv_destroy(&vdp->xdf_dev_cv);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_destroy(&vdp->xdf_cb_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz mutex_destroy(&vdp->xdf_dev_lk);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (vdp->xdf_cache_flush_block != NULL)
65908c77dfc02644236ba18bffe67b5ed6f23135yu, larry liu - Sun Microsystems - Beijing China kmem_free(vdp->xdf_flush_mem, 2 * vdp->xdf_xdev_secsize);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_soft_state_free(xdf_ssp, instance);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (DDI_SUCCESS);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Driver linkage structures.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic struct cb_ops xdf_cbops = {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_open,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_close,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_strategy,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodev,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_dump,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_read,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_write,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_ioctl,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodev,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodev,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodev,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nochpoll,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_prop_op,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz D_MP | D_NEW | D_64BIT,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz CB_REV,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_aread,
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_awrite
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz};
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstruct dev_ops xdf_devops = {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz DEVO_REV, /* devo_rev */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz 0, /* devo_refcnt */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_getinfo, /* devo_getinfo */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nulldev, /* devo_identify */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nulldev, /* devo_probe */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_attach, /* devo_attach */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_detach, /* devo_detach */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz nodev, /* devo_reset */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &xdf_cbops, /* devo_cb_ops */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, /* devo_bus_ops */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz NULL, /* devo_power */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_quiesce_not_supported, /* devo_quiesce */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz};
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * Module linkage structures.
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic struct modldrv modldrv = {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &mod_driverops, /* Type of module. This one is a driver */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz "virtual block driver", /* short description */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz &xdf_devops /* driver specific ops */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz};
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczstatic struct modlinkage xdf_modlinkage = {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz MODREV_1, (void *)&modldrv, NULL
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz};
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz/*
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz * standard module entry points
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz_init(void)
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int rc;
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_major = ddi_name_to_major("xdf");
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if (xdf_major == (major_t)-1)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (EINVAL);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((rc = ddi_soft_state_init(&xdf_ssp, sizeof (xdf_t), 0)) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rc);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_vreq_cache = kmem_cache_create("xdf_vreq_cache",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (v_req_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_gs_cache = kmem_cache_create("xdf_gs_cache",
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz sizeof (ge_slot_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_init();
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((rc = mod_install(&xdf_modlinkage)) != 0) {
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_fini();
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_destroy(xdf_vreq_cache);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_destroy(xdf_gs_cache);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_soft_state_fini(&xdf_ssp);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rc);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz }
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (rc);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edpint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz_fini(void)
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz int err;
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz if ((err = mod_remove(&xdf_modlinkage)) != 0)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (err);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#if defined(XPV_HVM_DRIVER)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz xdf_hvm_fini();
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz#endif /* XPV_HVM_DRIVER */
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_destroy(xdf_vreq_cache);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz kmem_cache_destroy(xdf_gs_cache);
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz ddi_soft_state_fini(&xdf_ssp);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp return (0);
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp}
06bbe1e05e4f6fd0773ee85a50c0de7adfc4fa06edp
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowiczint
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz_info(struct modinfo *modinfop)
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz{
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz return (mod_info(&xdf_modlinkage, modinfop));
7f0b8309074a5d8e9f9d8ffe7aad7bb0b1ee6b1fEdward Pilatowicz}