Home | History | Annotate | Line # | Download | only in hyperv
hvs.c revision 1.5.2.1
      1  1.5.2.1  thorpej /*	$NetBSD: hvs.c,v 1.5.2.1 2021/06/17 04:46:28 thorpej Exp $	*/
      2      1.1   nonaka /*	$OpenBSD: hvs.c,v 1.17 2017/08/10 17:22:48 mikeb Exp $	*/
      3      1.1   nonaka 
      4      1.1   nonaka /*-
      5      1.1   nonaka  * Copyright (c) 2009-2012,2016 Microsoft Corp.
      6      1.1   nonaka  * Copyright (c) 2012 NetApp Inc.
      7      1.1   nonaka  * Copyright (c) 2012 Citrix Inc.
      8      1.1   nonaka  * Copyright (c) 2017 Mike Belopuhov <mike (at) esdenera.com>
      9      1.1   nonaka  * All rights reserved.
     10      1.1   nonaka  *
     11      1.1   nonaka  * Redistribution and use in source and binary forms, with or without
     12      1.1   nonaka  * modification, are permitted provided that the following conditions
     13      1.1   nonaka  * are met:
     14      1.1   nonaka  * 1. Redistributions of source code must retain the above copyright
     15      1.1   nonaka  *    notice unmodified, this list of conditions, and the following
     16      1.1   nonaka  *    disclaimer.
     17      1.1   nonaka  * 2. Redistributions in binary form must reproduce the above copyright
     18      1.1   nonaka  *    notice, this list of conditions and the following disclaimer in the
     19      1.1   nonaka  *    documentation and/or other materials provided with the distribution.
     20      1.1   nonaka  *
     21      1.1   nonaka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22      1.1   nonaka  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23      1.1   nonaka  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24      1.1   nonaka  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25      1.1   nonaka  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26      1.1   nonaka  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27      1.1   nonaka  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28      1.1   nonaka  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29      1.1   nonaka  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30      1.1   nonaka  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31      1.1   nonaka  */
     32      1.1   nonaka 
     33      1.1   nonaka /*
     34      1.1   nonaka  * The OpenBSD port was done under funding by Esdenera Networks GmbH.
     35      1.1   nonaka  */
     36      1.1   nonaka 
     37      1.1   nonaka /* #define HVS_DEBUG_IO */
     38      1.1   nonaka 
     39      1.1   nonaka #include <sys/cdefs.h>
     40  1.5.2.1  thorpej __KERNEL_RCSID(0, "$NetBSD: hvs.c,v 1.5.2.1 2021/06/17 04:46:28 thorpej Exp $");
     41      1.1   nonaka 
     42      1.1   nonaka #include <sys/param.h>
     43      1.1   nonaka #include <sys/systm.h>
     44      1.1   nonaka #include <sys/kernel.h>
     45      1.1   nonaka #include <sys/device.h>
     46      1.1   nonaka #include <sys/buf.h>
     47      1.1   nonaka #include <sys/bus.h>
     48      1.1   nonaka #include <sys/kmem.h>
     49      1.1   nonaka #include <sys/mutex.h>
     50      1.1   nonaka 
     51      1.1   nonaka #include <uvm/uvm_extern.h>
     52      1.1   nonaka 
     53      1.1   nonaka #include <dev/hyperv/vmbusvar.h>
     54      1.1   nonaka 
     55      1.1   nonaka #include <dev/scsipi/scsi_all.h>
     56      1.1   nonaka #include <dev/scsipi/scsiconf.h>
     57      1.1   nonaka #include <dev/scsipi/scsipi_all.h>
     58      1.1   nonaka 
     59      1.1   nonaka #define HVS_PROTO_VERSION_WIN6		0x200
     60      1.1   nonaka #define HVS_PROTO_VERSION_WIN7		0x402
     61      1.1   nonaka #define HVS_PROTO_VERSION_WIN8		0x501
     62      1.1   nonaka #define HVS_PROTO_VERSION_WIN8_1	0x600
     63      1.1   nonaka #define HVS_PROTO_VERSION_WIN10		0x602
     64      1.1   nonaka 
     65      1.1   nonaka #define HVS_MSG_IODONE			0x01
     66      1.1   nonaka #define HVS_MSG_DEVGONE			0x02
     67      1.1   nonaka #define HVS_MSG_ENUMERATE		0x0b
     68      1.1   nonaka 
     69      1.1   nonaka #define HVS_REQ_SCSIIO			0x03
     70      1.1   nonaka #define HVS_REQ_STARTINIT		0x07
     71      1.1   nonaka #define HVS_REQ_FINISHINIT		0x08
     72      1.1   nonaka #define HVS_REQ_QUERYPROTO		0x09
     73      1.1   nonaka #define HVS_REQ_QUERYPROPS		0x0a
     74      1.1   nonaka #define HVS_REQ_CREATEMULTICHANNELS	0x0d
     75      1.1   nonaka 
     76      1.1   nonaka struct hvs_cmd_hdr {
     77      1.1   nonaka 	uint32_t		hdr_op;
     78      1.1   nonaka 	uint32_t		hdr_flags;
     79      1.1   nonaka 	uint32_t		hdr_status;
     80      1.1   nonaka #define cmd_op			cmd_hdr.hdr_op
     81      1.1   nonaka #define cmd_flags		cmd_hdr.hdr_flags
     82      1.1   nonaka #define cmd_status		cmd_hdr.hdr_status
     83      1.1   nonaka } __packed;
     84      1.1   nonaka 
     85      1.1   nonaka /* Negotiate version */
     86      1.1   nonaka struct hvs_cmd_ver {
     87      1.1   nonaka 	struct hvs_cmd_hdr	cmd_hdr;
     88      1.1   nonaka 	uint16_t		cmd_ver;
     89      1.1   nonaka 	uint16_t		cmd_rev;
     90      1.1   nonaka } __packed;
     91      1.1   nonaka 
     92      1.1   nonaka /* Query channel properties */
     93      1.1   nonaka struct hvs_chp {
     94      1.1   nonaka 	uint16_t		chp_proto;
     95      1.1   nonaka 	uint8_t			chp_path;
     96      1.1   nonaka 	uint8_t			chp_target;
     97      1.1   nonaka 	uint16_t		chp_maxchan;
     98      1.1   nonaka 	uint16_t		chp_port;
     99      1.1   nonaka 	uint32_t		chp_chflags;
    100      1.1   nonaka #define CHP_CHFLAGS_MULTI_CHANNEL	0x1
    101      1.1   nonaka 	uint32_t		chp_maxfer;
    102      1.1   nonaka 	uint64_t		chp_chanid;
    103      1.1   nonaka } __packed;
    104      1.1   nonaka 
    105      1.1   nonaka struct hvs_cmd_chp {
    106      1.1   nonaka 	struct hvs_cmd_hdr	cmd_hdr;
    107      1.1   nonaka 	struct hvs_chp		cmd_chp;
    108      1.1   nonaka } __packed;
    109      1.1   nonaka 
    110      1.1   nonaka #define SENSE_DATA_LEN_WIN7		18
    111      1.1   nonaka #define SENSE_DATA_LEN			20
    112      1.1   nonaka #define MAX_SRB_DATA			20
    113      1.1   nonaka 
    114      1.1   nonaka /* SCSI Request Block */
    115      1.1   nonaka struct hvs_srb {
    116      1.1   nonaka 	uint16_t		srb_reqlen;
    117      1.1   nonaka 	uint8_t			srb_iostatus;
    118      1.1   nonaka 	uint8_t			srb_scsistatus;
    119      1.1   nonaka 
    120      1.1   nonaka 	uint8_t			srb_initiator;
    121      1.1   nonaka 	uint8_t			srb_bus;
    122      1.1   nonaka 	uint8_t			srb_target;
    123      1.1   nonaka 	uint8_t			srb_lun;
    124      1.1   nonaka 
    125      1.1   nonaka 	uint8_t			srb_cdblen;
    126      1.1   nonaka 	uint8_t			srb_senselen;
    127      1.1   nonaka 	uint8_t			srb_direction;
    128      1.1   nonaka 	uint8_t			_reserved;
    129      1.1   nonaka 
    130      1.1   nonaka 	uint32_t		srb_datalen;
    131      1.1   nonaka 	uint8_t			srb_data[MAX_SRB_DATA];
    132      1.1   nonaka } __packed;
    133      1.1   nonaka 
    134      1.1   nonaka #define SRB_DATA_WRITE			0
    135      1.1   nonaka #define SRB_DATA_READ			1
    136      1.1   nonaka #define SRB_DATA_NONE			2
    137      1.1   nonaka 
    138      1.1   nonaka #define SRB_STATUS_PENDING		0x00
    139      1.1   nonaka #define SRB_STATUS_SUCCESS		0x01
    140      1.1   nonaka #define SRB_STATUS_ABORTED		0x02
    141      1.1   nonaka #define SRB_STATUS_ERROR		0x04
    142      1.1   nonaka #define SRB_STATUS_INVALID_LUN		0x20
    143      1.1   nonaka #define SRB_STATUS_QUEUE_FROZEN		0x40
    144      1.1   nonaka #define SRB_STATUS_AUTOSENSE_VALID	0x80
    145      1.1   nonaka 
    146      1.1   nonaka #define SRB_FLAGS_QUEUE_ACTION_ENABLE		0x00000002
    147      1.1   nonaka #define SRB_FLAGS_DISABLE_DISCONNECT		0x00000004
    148      1.1   nonaka #define SRB_FLAGS_DISABLE_SYNCH_TRANSFER	0x00000008
    149      1.1   nonaka #define SRB_FLAGS_BYPASS_FROZEN_QUEUE		0x00000010
    150      1.1   nonaka #define SRB_FLAGS_DISABLE_AUTOSENSE		0x00000020
    151      1.1   nonaka #define SRB_FLAGS_DATA_IN			0x00000040
    152      1.1   nonaka #define SRB_FLAGS_DATA_OUT			0x00000080
    153      1.1   nonaka #define SRB_FLAGS_NO_DATA_TRANSFER		0x00000000
    154      1.1   nonaka #define SRB_FLAGS_NO_QUEUE_FREEZE		0x00000100
    155      1.1   nonaka #define SRB_FLAGS_ADAPTER_CACHE_ENABLE		0x00000200
    156      1.1   nonaka #define SRB_FLAGS_FREE_SENSE_BUFFER		0x00000400
    157      1.1   nonaka 
    158      1.1   nonaka struct hvs_cmd_io {
    159      1.1   nonaka 	struct hvs_cmd_hdr	cmd_hdr;
    160      1.1   nonaka 	struct hvs_srb		cmd_srb;
    161      1.1   nonaka 	/* Win8 extensions */
    162      1.1   nonaka 	uint16_t		_reserved;
    163      1.1   nonaka 	uint8_t			cmd_qtag;
    164      1.1   nonaka 	uint8_t			cmd_qaction;
    165      1.1   nonaka 	uint32_t		cmd_srbflags;
    166      1.1   nonaka 	uint32_t		cmd_timeout;
    167      1.1   nonaka 	uint32_t		cmd_qsortkey;
    168      1.1   nonaka } __packed;
    169      1.1   nonaka 
    170      1.1   nonaka #define HVS_CMD_SIZE			64
    171      1.1   nonaka 
    172      1.1   nonaka union hvs_cmd {
    173      1.1   nonaka 	struct hvs_cmd_hdr	cmd_hdr;
    174      1.1   nonaka 	struct hvs_cmd_ver	ver;
    175      1.1   nonaka 	struct hvs_cmd_chp	chp;
    176      1.1   nonaka 	struct hvs_cmd_io	io;
    177      1.1   nonaka 	uint16_t		multi_chans_cnt;
    178      1.1   nonaka 	uint8_t			pad[HVS_CMD_SIZE];
    179      1.1   nonaka } __packed;
    180      1.1   nonaka 
    181      1.1   nonaka #define HVS_RING_SIZE			(20 * PAGE_SIZE)
    182      1.1   nonaka #define HVS_MAX_CCB			128
    183      1.4   nonaka #define HVS_MAX_SGE			(howmany(MAXPHYS, PAGE_SIZE) + 1)
    184      1.1   nonaka 
    185      1.1   nonaka struct hvs_softc;
    186      1.1   nonaka 
    187      1.1   nonaka struct hvs_ccb {
    188      1.1   nonaka 	struct scsipi_xfer	*ccb_xfer;  /* associated transfer */
    189      1.1   nonaka 	union hvs_cmd		*ccb_cmd;   /* associated command */
    190      1.1   nonaka 	union hvs_cmd		ccb_rsp;    /* response */
    191      1.1   nonaka 	bus_dmamap_t		ccb_dmap;   /* transfer map */
    192      1.1   nonaka 	uint64_t		ccb_rid;    /* request id */
    193      1.1   nonaka 	struct vmbus_gpa_range	*ccb_sgl;
    194      1.1   nonaka 	int			ccb_nsge;
    195      1.1   nonaka 	void			(*ccb_done)(struct hvs_ccb *);
    196      1.1   nonaka 	void			*ccb_cookie;
    197      1.1   nonaka 	SIMPLEQ_ENTRY(hvs_ccb)	ccb_link;
    198      1.1   nonaka };
    199      1.1   nonaka SIMPLEQ_HEAD(hvs_ccb_queue, hvs_ccb);
    200      1.1   nonaka 
    201      1.1   nonaka struct hvs_config;
    202      1.1   nonaka 
    203      1.1   nonaka struct hvs_softc {
    204      1.1   nonaka 	device_t		sc_dev;
    205      1.1   nonaka 	bus_dma_tag_t		sc_dmat;
    206      1.1   nonaka 
    207      1.1   nonaka 	struct vmbus_channel	*sc_chan;
    208      1.1   nonaka 
    209      1.1   nonaka 	const struct hvs_config	*sc_config;
    210      1.1   nonaka 
    211      1.1   nonaka 	struct hvs_chp		sc_props;
    212      1.1   nonaka 
    213      1.1   nonaka 	/* CCBs */
    214      1.1   nonaka 	int			sc_nccb;
    215      1.1   nonaka 	struct hvs_ccb		*sc_ccbs;
    216      1.1   nonaka 	struct hvs_ccb_queue	sc_ccb_fq;  /* free queue */
    217      1.1   nonaka 	kmutex_t		sc_ccb_fqlck;
    218      1.1   nonaka 
    219      1.1   nonaka 	int			sc_bus;
    220      1.1   nonaka 
    221      1.1   nonaka 	struct scsipi_adapter	sc_adapter;
    222      1.1   nonaka 	struct scsipi_channel	sc_channel;
    223      1.1   nonaka 	device_t		sc_scsibus;
    224      1.1   nonaka #if notyet /* XXX subchannel */
    225      1.1   nonaka 	u_int			sc_nchan;
    226      1.1   nonaka 	struct vmbus_channel	*sc_sel_chan[MAXCPUS];
    227      1.1   nonaka #endif
    228      1.1   nonaka };
    229      1.1   nonaka 
    230      1.1   nonaka static int	hvs_match(device_t, cfdata_t, void *);
    231      1.1   nonaka static void	hvs_attach(device_t, device_t, void *);
    232      1.1   nonaka static int	hvs_detach(device_t, int);
    233      1.1   nonaka 
    234      1.1   nonaka CFATTACH_DECL_NEW(hvs, sizeof(struct hvs_softc),
    235      1.1   nonaka     hvs_match, hvs_attach, hvs_detach, NULL);
    236      1.1   nonaka 
    237      1.1   nonaka static void	hvs_scsipi_request(struct scsipi_channel *,
    238      1.1   nonaka 		    scsipi_adapter_req_t, void *);
    239      1.1   nonaka static void	hvs_scsi_cmd_done(struct hvs_ccb *);
    240      1.1   nonaka static int	hvs_start(struct hvs_softc *, struct vmbus_channel *,
    241      1.1   nonaka 		    struct hvs_ccb *);
    242      1.1   nonaka static int	hvs_poll(struct hvs_softc *, struct vmbus_channel *,
    243      1.1   nonaka 		    struct hvs_ccb *);
    244      1.1   nonaka static void	hvs_poll_done(struct hvs_ccb *);
    245      1.1   nonaka static void	hvs_intr(void *);
    246      1.1   nonaka static void	hvs_scsi_probe(void *arg);
    247      1.1   nonaka static void	hvs_scsi_done(struct scsipi_xfer *, int);
    248      1.1   nonaka 
    249      1.1   nonaka static int	hvs_connect(struct hvs_softc *);
    250      1.1   nonaka static void	hvs_empty_done(struct hvs_ccb *);
    251      1.1   nonaka 
    252      1.1   nonaka static int	hvs_alloc_ccbs(struct hvs_softc *);
    253      1.1   nonaka static void	hvs_free_ccbs(struct hvs_softc *);
    254      1.1   nonaka static struct hvs_ccb *
    255      1.1   nonaka 		hvs_get_ccb(struct hvs_softc *);
    256      1.1   nonaka static void	hvs_put_ccb(struct hvs_softc *, struct hvs_ccb *);
    257      1.1   nonaka 
    258      1.1   nonaka static const struct hvs_config {
    259      1.1   nonaka 	uint32_t	proto_version;
    260      1.1   nonaka 	uint16_t	reqlen;
    261      1.1   nonaka 	uint8_t		senselen;
    262      1.1   nonaka 	bool		fixup_wrong_response;
    263      1.1   nonaka 	bool		upgrade_spc2_to_spc3;
    264      1.1   nonaka 	bool		use_win8ext_flags;
    265      1.1   nonaka } hvs_config_list[] = {
    266      1.1   nonaka 	{
    267      1.1   nonaka 		.proto_version = HVS_PROTO_VERSION_WIN10,
    268      1.1   nonaka 		.reqlen = sizeof(struct hvs_cmd_io),
    269      1.1   nonaka 		.senselen = SENSE_DATA_LEN,
    270      1.1   nonaka 		.fixup_wrong_response = false,
    271      1.1   nonaka 		.upgrade_spc2_to_spc3 = false,
    272      1.1   nonaka 		.use_win8ext_flags = true,
    273      1.1   nonaka 	},
    274      1.1   nonaka 	{
    275      1.1   nonaka 		.proto_version = HVS_PROTO_VERSION_WIN8_1,
    276      1.1   nonaka 		.reqlen = sizeof(struct hvs_cmd_io),
    277      1.1   nonaka 		.senselen = SENSE_DATA_LEN,
    278      1.1   nonaka 		.fixup_wrong_response = true,
    279      1.1   nonaka 		.upgrade_spc2_to_spc3 = true,
    280      1.1   nonaka 		.use_win8ext_flags = true,
    281      1.1   nonaka 	},
    282      1.1   nonaka 	{
    283      1.1   nonaka 		.proto_version = HVS_PROTO_VERSION_WIN8,
    284      1.1   nonaka 		.reqlen = sizeof(struct hvs_cmd_io),
    285      1.1   nonaka 		.senselen = SENSE_DATA_LEN,
    286      1.1   nonaka 		.fixup_wrong_response = true,
    287      1.1   nonaka 		.upgrade_spc2_to_spc3 = true,
    288      1.1   nonaka 		.use_win8ext_flags = true,
    289      1.1   nonaka 	},
    290      1.1   nonaka 	{
    291      1.1   nonaka 		.proto_version = HVS_PROTO_VERSION_WIN7,
    292      1.1   nonaka 		.reqlen = offsetof(struct hvs_cmd_io, _reserved),
    293      1.1   nonaka 		.senselen = SENSE_DATA_LEN_WIN7,
    294      1.1   nonaka 		.fixup_wrong_response = true,
    295      1.1   nonaka 		.upgrade_spc2_to_spc3 = false,
    296      1.1   nonaka 		.use_win8ext_flags = false,
    297      1.1   nonaka 	},
    298      1.1   nonaka 	{
    299      1.1   nonaka 		.proto_version = HVS_PROTO_VERSION_WIN6,
    300      1.1   nonaka 		.reqlen = offsetof(struct hvs_cmd_io, _reserved),
    301      1.1   nonaka 		.senselen = SENSE_DATA_LEN_WIN7,
    302      1.1   nonaka 		.fixup_wrong_response = false,
    303      1.1   nonaka 		.upgrade_spc2_to_spc3 = false,
    304      1.1   nonaka 		.use_win8ext_flags = false,
    305      1.1   nonaka 	},
    306      1.1   nonaka };
    307      1.1   nonaka 
    308      1.1   nonaka #if notyet /* XXX subchannel */
    309      1.1   nonaka static int hvs_chan_cnt;
    310      1.1   nonaka #endif
    311      1.1   nonaka 
    312      1.1   nonaka static int
    313      1.1   nonaka hvs_match(device_t parent, cfdata_t cf, void *aux)
    314      1.1   nonaka {
    315      1.1   nonaka 	struct vmbus_attach_args *aa = aux;
    316      1.1   nonaka 
    317      1.1   nonaka 	if (memcmp(aa->aa_type, &hyperv_guid_ide, sizeof(*aa->aa_type)) != 0 &&
    318      1.1   nonaka 	    memcmp(aa->aa_type, &hyperv_guid_scsi, sizeof(*aa->aa_type)) != 0)
    319      1.1   nonaka 		return 0;
    320      1.1   nonaka 	return 1;
    321      1.1   nonaka }
    322      1.1   nonaka 
    323      1.1   nonaka static void
    324      1.1   nonaka hvs_attach(device_t parent, device_t self, void *aux)
    325      1.1   nonaka {
    326      1.1   nonaka 	extern struct cfdata cfdata[];
    327      1.1   nonaka 	struct hvs_softc *sc = device_private(self);
    328      1.1   nonaka 	struct vmbus_attach_args *aa = aux;
    329      1.1   nonaka 	struct scsipi_adapter *adapt = &sc->sc_adapter;
    330      1.1   nonaka 	struct scsipi_channel *chan = &sc->sc_channel;
    331      1.1   nonaka 	const char *bus;
    332      1.1   nonaka 	bool is_scsi;
    333      1.1   nonaka 
    334      1.1   nonaka 	sc->sc_dev = self;
    335      1.1   nonaka 	sc->sc_chan = aa->aa_chan;
    336      1.1   nonaka 	sc->sc_dmat = sc->sc_chan->ch_sc->sc_dmat;
    337      1.1   nonaka #if notyet /* XXX subchannel */
    338      1.1   nonaka 	sc->sc_nchan = 1;
    339      1.1   nonaka 	sc->sc_sel_chan[0] = sc->sc_chan;
    340      1.1   nonaka #endif
    341      1.1   nonaka 
    342      1.1   nonaka 	if (memcmp(aa->aa_type, &hyperv_guid_scsi, sizeof(*aa->aa_type)) == 0) {
    343      1.1   nonaka 		is_scsi = true;
    344      1.1   nonaka 		bus = "SCSI";
    345      1.1   nonaka 	} else {
    346      1.1   nonaka 		is_scsi = false;
    347      1.1   nonaka 		bus = "IDE";
    348      1.1   nonaka 	}
    349      1.1   nonaka 
    350      1.1   nonaka 	aprint_naive("\n");
    351      1.1   nonaka 	aprint_normal(": Hyper-V StorVSC %s\n", bus);
    352      1.1   nonaka 
    353      1.1   nonaka 	if (vmbus_channel_setdeferred(sc->sc_chan, device_xname(self))) {
    354      1.1   nonaka 		aprint_error_dev(self,
    355      1.1   nonaka 		    "failed to create the interrupt thread\n");
    356      1.1   nonaka 		return;
    357      1.1   nonaka 	}
    358      1.1   nonaka 
    359      1.1   nonaka 	if (vmbus_channel_open(sc->sc_chan, HVS_RING_SIZE, &sc->sc_props,
    360      1.1   nonaka 	    sizeof(sc->sc_props), hvs_intr, sc)) {
    361      1.1   nonaka 		aprint_error_dev(self, "failed to open channel\n");
    362      1.1   nonaka 		return;
    363      1.1   nonaka 	}
    364      1.1   nonaka 
    365      1.1   nonaka 	if (hvs_alloc_ccbs(sc))
    366      1.1   nonaka 		return;
    367      1.1   nonaka 
    368      1.1   nonaka 	if (hvs_connect(sc))
    369      1.1   nonaka 		return;
    370      1.1   nonaka 
    371      1.1   nonaka 	aprint_normal_dev(self, "protocol %u.%u\n",
    372      1.1   nonaka 	    (sc->sc_config->proto_version >> 8) & 0xff,
    373      1.1   nonaka 	    sc->sc_config->proto_version & 0xff);
    374      1.1   nonaka 
    375      1.1   nonaka 	adapt = &sc->sc_adapter;
    376      1.1   nonaka 	adapt->adapt_dev = self;
    377      1.1   nonaka 	adapt->adapt_nchannels = 1;
    378      1.1   nonaka 	adapt->adapt_openings = sc->sc_nccb;
    379      1.1   nonaka 	adapt->adapt_max_periph = adapt->adapt_openings;
    380      1.1   nonaka 	adapt->adapt_request = hvs_scsipi_request;
    381      1.1   nonaka 	adapt->adapt_minphys = minphys;
    382      1.1   nonaka 	adapt->adapt_flags = SCSIPI_ADAPT_MPSAFE;
    383      1.1   nonaka 
    384      1.1   nonaka 	chan = &sc->sc_channel;
    385      1.1   nonaka 	chan->chan_adapter = adapt;
    386      1.1   nonaka 	chan->chan_bustype = &scsi_bustype;	/* XXX IDE/ATAPI */
    387      1.1   nonaka 	chan->chan_channel = 0;
    388      1.1   nonaka 	chan->chan_ntargets = 2;
    389      1.1   nonaka 	chan->chan_nluns = is_scsi ? 64 : 1;
    390      1.1   nonaka 	chan->chan_id = 0;
    391      1.1   nonaka 	chan->chan_flags = SCSIPI_CHAN_NOSETTLE;
    392      1.1   nonaka 	chan->chan_defquirks |= PQUIRK_ONLYBIG;
    393      1.1   nonaka 
    394      1.5  thorpej 	sc->sc_scsibus = config_found(self, &sc->sc_channel, scsiprint,
    395      1.5  thorpej 	    CFARG_EOL);
    396      1.1   nonaka 
    397      1.1   nonaka 	/*
    398      1.1   nonaka 	 * If the driver has successfully attached to an IDE device,
    399      1.1   nonaka 	 * we need to make sure that the same disk is not available to
    400      1.1   nonaka 	 * the system via pciide(4) or piixide(4) causing DUID conflicts
    401      1.1   nonaka 	 * and preventing system from booting.
    402      1.1   nonaka 	 */
    403      1.1   nonaka 	if (!is_scsi && sc->sc_scsibus != NULL) {
    404      1.1   nonaka 		static const char *disable_devices[] = {
    405      1.1   nonaka 			"wd",
    406      1.1   nonaka 		};
    407      1.1   nonaka 		size_t j;
    408      1.1   nonaka 
    409      1.1   nonaka 		for (j = 0; j < __arraycount(disable_devices); j++) {
    410      1.1   nonaka 			const char *dev = disable_devices[j];
    411      1.1   nonaka 			size_t len = strlen(dev);
    412      1.1   nonaka 			int devno;
    413      1.1   nonaka 
    414      1.1   nonaka 			for (devno = 0; cfdata[devno].cf_name != NULL; devno++) {
    415      1.1   nonaka 				cfdata_t cf = &cfdata[devno];
    416      1.1   nonaka 
    417      1.1   nonaka 				if (strlen(cf->cf_name) != len ||
    418      1.1   nonaka 				    strncasecmp(dev, cf->cf_name, len) != 0 ||
    419      1.1   nonaka 				    cf->cf_fstate != FSTATE_STAR)
    420      1.1   nonaka 					continue;
    421      1.1   nonaka 
    422      1.1   nonaka 				cf->cf_fstate = FSTATE_DSTAR;
    423      1.1   nonaka 			}
    424      1.1   nonaka 		}
    425      1.1   nonaka 	}
    426      1.1   nonaka }
    427      1.1   nonaka 
    428      1.1   nonaka static int
    429      1.1   nonaka hvs_detach(device_t self, int flags)
    430      1.1   nonaka {
    431      1.1   nonaka 
    432      1.1   nonaka 	/* XXX detach */
    433      1.1   nonaka 
    434      1.1   nonaka 	return 0;
    435      1.1   nonaka }
    436      1.1   nonaka 
    437      1.1   nonaka #define XS2DMA(xs) \
    438      1.1   nonaka     ((((xs)->xs_control & XS_CTL_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE) | \
    439      1.1   nonaka     (((xs)->xs_control & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | \
    440      1.1   nonaka     BUS_DMA_STREAMING)
    441      1.1   nonaka 
    442      1.1   nonaka #define XS2DMAPRE(xs) (((xs)->xs_control & XS_CTL_DATA_IN) ? \
    443      1.1   nonaka     BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)
    444      1.1   nonaka 
    445      1.1   nonaka #define XS2DMAPOST(xs) (((xs)->xs_control & XS_CTL_DATA_IN) ? \
    446      1.1   nonaka     BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)
    447      1.1   nonaka 
    448      1.1   nonaka static void
    449      1.1   nonaka hvs_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t request,
    450      1.1   nonaka     void *arg)
    451      1.1   nonaka {
    452      1.1   nonaka 	struct scsipi_adapter *adapt = chan->chan_adapter;
    453      1.1   nonaka 	struct hvs_softc *sc = device_private(adapt->adapt_dev);
    454      1.1   nonaka 	struct scsipi_xfer *xs;
    455      1.1   nonaka 	struct scsipi_xfer_mode *xm;
    456      1.1   nonaka 	struct scsipi_periph *periph;
    457      1.1   nonaka 	struct hvs_ccb *ccb;
    458      1.1   nonaka 	union hvs_cmd cmd;
    459      1.1   nonaka 	struct hvs_cmd_io *io = &cmd.io;
    460      1.1   nonaka 	struct hvs_srb *srb = &io->cmd_srb;
    461      1.1   nonaka 	int i, error;
    462      1.1   nonaka 
    463      1.1   nonaka 	switch (request) {
    464      1.1   nonaka 	default:
    465      1.1   nonaka 		device_printf(sc->sc_dev,
    466      1.1   nonaka 		    "%s: unhandled request %u\n", __func__, request);
    467      1.1   nonaka 		return;
    468      1.1   nonaka 
    469      1.1   nonaka 	case ADAPTER_REQ_GROW_RESOURCES:
    470      1.1   nonaka 		/* Not supported. */
    471      1.1   nonaka 		return;
    472      1.1   nonaka 
    473      1.1   nonaka 	case ADAPTER_REQ_SET_XFER_MODE:
    474      1.1   nonaka 		xm = arg;
    475      1.1   nonaka 		xm->xm_mode = PERIPH_CAP_TQING;
    476      1.1   nonaka 		xm->xm_period = 0;
    477      1.1   nonaka 		xm->xm_offset = 0;
    478      1.1   nonaka 		scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
    479      1.1   nonaka 		return;
    480      1.1   nonaka 
    481      1.1   nonaka 	case ADAPTER_REQ_RUN_XFER:
    482      1.1   nonaka 		break;
    483      1.1   nonaka 	}
    484      1.1   nonaka 
    485      1.1   nonaka 	xs = arg;
    486      1.1   nonaka 
    487      1.1   nonaka 	if (xs->cmdlen > MAX_SRB_DATA) {
    488      1.1   nonaka 		device_printf(sc->sc_dev, "CDB is too big: %d\n",
    489      1.1   nonaka 		    xs->cmdlen);
    490      1.1   nonaka 		memset(&xs->sense, 0, sizeof(xs->sense));
    491      1.1   nonaka 		xs->sense.scsi_sense.response_code =
    492      1.1   nonaka 		    SSD_RCODE_VALID | SSD_RCODE_CURRENT;
    493      1.1   nonaka 		xs->sense.scsi_sense.flags = SSD_ILI;
    494      1.1   nonaka 		xs->sense.scsi_sense.asc = 0x20;
    495      1.1   nonaka 		hvs_scsi_done(xs, XS_SENSE);
    496      1.1   nonaka 		return;
    497      1.1   nonaka 	}
    498      1.1   nonaka 
    499      1.1   nonaka 	ccb = hvs_get_ccb(sc);
    500      1.1   nonaka 	if (ccb == NULL) {
    501      1.1   nonaka 		device_printf(sc->sc_dev, "failed to allocate ccb\n");
    502      1.1   nonaka 		hvs_scsi_done(xs, XS_RESOURCE_SHORTAGE);
    503      1.1   nonaka 		return;
    504      1.1   nonaka 	}
    505      1.1   nonaka 
    506      1.1   nonaka 	periph = xs->xs_periph;
    507      1.1   nonaka 
    508      1.1   nonaka 	memset(&cmd, 0, sizeof(cmd));
    509      1.1   nonaka 
    510      1.1   nonaka 	srb->srb_initiator = chan->chan_id;
    511      1.1   nonaka 	srb->srb_bus = sc->sc_bus;
    512      1.1   nonaka 	srb->srb_target = periph->periph_target - 1;
    513      1.1   nonaka 	srb->srb_lun = periph->periph_lun;
    514      1.1   nonaka 	srb->srb_cdblen = xs->cmdlen;
    515      1.1   nonaka 	memcpy(srb->srb_data, xs->cmd, xs->cmdlen);
    516      1.1   nonaka 
    517      1.1   nonaka 	if (sc->sc_config->use_win8ext_flags) {
    518      1.1   nonaka 		io->cmd_timeout = 60;
    519      1.1   nonaka 		SET(io->cmd_srbflags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
    520      1.1   nonaka 	}
    521      1.1   nonaka 
    522      1.1   nonaka 	switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
    523      1.1   nonaka 	case XS_CTL_DATA_IN:
    524      1.1   nonaka 		srb->srb_direction = SRB_DATA_READ;
    525      1.1   nonaka 		if (sc->sc_config->use_win8ext_flags)
    526      1.1   nonaka 			SET(io->cmd_srbflags, SRB_FLAGS_DATA_IN);
    527      1.1   nonaka 		break;
    528      1.1   nonaka 	case XS_CTL_DATA_OUT:
    529      1.1   nonaka 		srb->srb_direction = SRB_DATA_WRITE;
    530      1.1   nonaka 		if (sc->sc_config->use_win8ext_flags)
    531      1.1   nonaka 			SET(io->cmd_srbflags, SRB_FLAGS_DATA_OUT);
    532      1.1   nonaka 		break;
    533      1.1   nonaka 	default:
    534      1.1   nonaka 		srb->srb_direction = SRB_DATA_NONE;
    535      1.1   nonaka 		if (sc->sc_config->use_win8ext_flags)
    536      1.1   nonaka 			SET(io->cmd_srbflags, SRB_FLAGS_NO_DATA_TRANSFER);
    537      1.1   nonaka 		break;
    538      1.1   nonaka 	}
    539      1.1   nonaka 
    540      1.1   nonaka 	srb->srb_datalen = xs->datalen;
    541      1.1   nonaka 	srb->srb_reqlen = sc->sc_config->reqlen;
    542      1.1   nonaka 	srb->srb_senselen = sc->sc_config->senselen;
    543      1.1   nonaka 
    544      1.1   nonaka 	cmd.cmd_op = HVS_REQ_SCSIIO;
    545      1.1   nonaka 	cmd.cmd_flags = VMBUS_CHANPKT_FLAG_RC;
    546      1.1   nonaka 
    547      1.1   nonaka 	if (xs->datalen > 0) {
    548      1.1   nonaka 		error = bus_dmamap_load(sc->sc_dmat, ccb->ccb_dmap, xs->data,
    549      1.1   nonaka 		    xs->datalen, NULL, XS2DMA(xs));
    550      1.1   nonaka 		if (error) {
    551      1.1   nonaka 			device_printf(sc->sc_dev,
    552      1.1   nonaka 			    "failed to load %d bytes (%d)\n", xs->datalen,
    553      1.1   nonaka 			    error);
    554      1.1   nonaka 			hvs_put_ccb(sc, ccb);
    555      1.1   nonaka 			hvs_scsi_done(xs, (error == ENOMEM || error == EAGAIN) ?
    556      1.1   nonaka 			    XS_RESOURCE_SHORTAGE : XS_DRIVER_STUFFUP);
    557      1.1   nonaka 			return;
    558      1.1   nonaka 		}
    559      1.1   nonaka 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmap, 0, xs->datalen,
    560      1.1   nonaka 		    XS2DMAPRE(xs));
    561      1.1   nonaka 
    562      1.1   nonaka 		ccb->ccb_sgl->gpa_len = xs->datalen;
    563      1.1   nonaka 		ccb->ccb_sgl->gpa_ofs = (vaddr_t)xs->data & PAGE_MASK;
    564      1.1   nonaka 		for (i = 0; i < ccb->ccb_dmap->dm_nsegs; i++)
    565      1.1   nonaka 			ccb->ccb_sgl->gpa_page[i] =
    566      1.1   nonaka 			    atop(ccb->ccb_dmap->dm_segs[i].ds_addr);
    567      1.1   nonaka 		ccb->ccb_nsge = ccb->ccb_dmap->dm_nsegs;
    568      1.1   nonaka 	} else
    569      1.1   nonaka 		ccb->ccb_nsge = 0;
    570      1.1   nonaka 
    571      1.1   nonaka 	ccb->ccb_xfer = xs;
    572      1.1   nonaka 	ccb->ccb_cmd = &cmd;
    573      1.1   nonaka 	ccb->ccb_done = hvs_scsi_cmd_done;
    574      1.1   nonaka 
    575      1.1   nonaka #ifdef HVS_DEBUG_IO
    576      1.1   nonaka 	printf("%s: %u.%u: rid %"PRIu64" opcode %#x control %#x datalen %d\n",
    577      1.1   nonaka 	    device_xname(sc->sc_dev), periph->periph_target, periph->periph_lun,
    578      1.1   nonaka 	    ccb->ccb_rid, xs->cmd->opcode, xs->xs_control, xs->datalen);
    579      1.1   nonaka #endif
    580      1.1   nonaka 
    581      1.1   nonaka 	if (xs->xs_control & XS_CTL_POLL)
    582      1.1   nonaka 		error = hvs_poll(sc, sc->sc_chan, ccb);
    583      1.1   nonaka 	else
    584      1.1   nonaka 		error = hvs_start(sc, sc->sc_chan, ccb);
    585      1.1   nonaka 	if (error) {
    586      1.1   nonaka 		hvs_put_ccb(sc, ccb);
    587      1.1   nonaka 		hvs_scsi_done(xs, (error == ENOMEM || error == EAGAIN) ?
    588      1.1   nonaka 		    XS_RESOURCE_SHORTAGE : XS_DRIVER_STUFFUP);
    589      1.1   nonaka 	}
    590      1.1   nonaka }
    591      1.1   nonaka 
    592      1.1   nonaka static int
    593      1.1   nonaka hvs_start(struct hvs_softc *sc, struct vmbus_channel *chan, struct hvs_ccb *ccb)
    594      1.1   nonaka {
    595      1.1   nonaka 	union hvs_cmd *cmd = ccb->ccb_cmd;
    596      1.1   nonaka 	int error;
    597      1.1   nonaka 
    598      1.1   nonaka 	ccb->ccb_cmd = NULL;
    599      1.1   nonaka 
    600      1.1   nonaka 	if (ccb->ccb_nsge > 0) {
    601      1.1   nonaka 		error = vmbus_channel_send_prpl(chan, ccb->ccb_sgl,
    602      1.1   nonaka 		    ccb->ccb_nsge, cmd, HVS_CMD_SIZE, ccb->ccb_rid);
    603      1.1   nonaka 		if (error) {
    604      1.1   nonaka 			device_printf(sc->sc_dev,
    605      1.1   nonaka 			    "failed to submit operation %x via prpl\n",
    606      1.1   nonaka 			    cmd->cmd_op);
    607      1.1   nonaka 			bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmap);
    608      1.1   nonaka 		}
    609      1.1   nonaka 	} else {
    610      1.1   nonaka 		error = vmbus_channel_send(chan, cmd, HVS_CMD_SIZE,
    611      1.1   nonaka 		    ccb->ccb_rid, VMBUS_CHANPKT_TYPE_INBAND,
    612      1.1   nonaka 		    VMBUS_CHANPKT_FLAG_RC);
    613      1.1   nonaka 		if (error)
    614      1.1   nonaka 			device_printf(sc->sc_dev,
    615      1.1   nonaka 			    "failed to submit operation %x\n", cmd->cmd_op);
    616      1.1   nonaka 	}
    617      1.1   nonaka 
    618      1.1   nonaka 	return error;
    619      1.1   nonaka }
    620      1.1   nonaka 
    621      1.1   nonaka static void
    622      1.1   nonaka hvs_poll_done(struct hvs_ccb *ccb)
    623      1.1   nonaka {
    624      1.1   nonaka 	int *rv = ccb->ccb_cookie;
    625      1.1   nonaka 
    626      1.1   nonaka 	if (ccb->ccb_cmd) {
    627      1.1   nonaka 		memcpy(&ccb->ccb_rsp, ccb->ccb_cmd, HVS_CMD_SIZE);
    628      1.1   nonaka 		ccb->ccb_cmd = &ccb->ccb_rsp;
    629      1.1   nonaka 	} else
    630      1.1   nonaka 		memset(&ccb->ccb_rsp, 0, HVS_CMD_SIZE);
    631      1.1   nonaka 
    632      1.1   nonaka 	*rv = 0;
    633      1.1   nonaka }
    634      1.1   nonaka 
    635      1.1   nonaka static int
    636      1.1   nonaka hvs_poll(struct hvs_softc *sc, struct vmbus_channel *chan, struct hvs_ccb *ccb)
    637      1.1   nonaka {
    638      1.1   nonaka 	void (*done)(struct hvs_ccb *);
    639      1.1   nonaka 	void *cookie;
    640      1.1   nonaka 	int s, rv = 1;
    641      1.1   nonaka 
    642      1.1   nonaka 	done = ccb->ccb_done;
    643      1.1   nonaka 	cookie = ccb->ccb_cookie;
    644      1.1   nonaka 
    645      1.1   nonaka 	ccb->ccb_done = hvs_poll_done;
    646      1.1   nonaka 	ccb->ccb_cookie = &rv;
    647      1.1   nonaka 
    648      1.1   nonaka 	if (hvs_start(sc, chan, ccb)) {
    649      1.1   nonaka 		ccb->ccb_cookie = cookie;
    650      1.1   nonaka 		ccb->ccb_done = done;
    651      1.1   nonaka 		return -1;
    652      1.1   nonaka 	}
    653      1.1   nonaka 
    654      1.1   nonaka 	while (rv == 1) {
    655      1.1   nonaka 		delay(10);
    656      1.1   nonaka 		s = splbio();
    657      1.1   nonaka 		hvs_intr(sc);
    658      1.1   nonaka 		splx(s);
    659      1.1   nonaka 	}
    660      1.1   nonaka 
    661      1.1   nonaka 	ccb->ccb_cookie = cookie;
    662      1.1   nonaka 	ccb->ccb_done = done;
    663      1.1   nonaka 	ccb->ccb_done(ccb);
    664      1.1   nonaka 
    665      1.1   nonaka 	return 0;
    666      1.1   nonaka }
    667      1.1   nonaka 
    668      1.1   nonaka static void
    669      1.1   nonaka hvs_intr(void *xsc)
    670      1.1   nonaka {
    671      1.1   nonaka 	struct hvs_softc *sc = xsc;
    672      1.1   nonaka 	struct hvs_ccb *ccb;
    673      1.1   nonaka 	union hvs_cmd cmd;
    674      1.1   nonaka 	uint64_t rid;
    675      1.1   nonaka 	uint32_t rlen;
    676      1.1   nonaka 	int error;
    677      1.1   nonaka 
    678      1.1   nonaka 	for (;;) {
    679      1.1   nonaka 		error = vmbus_channel_recv(sc->sc_chan, &cmd, sizeof(cmd),
    680      1.1   nonaka 		    &rlen, &rid, 0);
    681      1.1   nonaka 		switch (error) {
    682      1.1   nonaka 		case 0:
    683      1.1   nonaka 			break;
    684      1.1   nonaka 		case EAGAIN:
    685      1.1   nonaka 			/* No more messages to process */
    686      1.1   nonaka 			return;
    687      1.1   nonaka 		default:
    688      1.1   nonaka 			device_printf(sc->sc_dev,
    689      1.1   nonaka 			    "error %d while receiving a reply\n", error);
    690      1.1   nonaka 			return;
    691      1.1   nonaka 		}
    692      1.1   nonaka 		if (rlen != sizeof(cmd)) {
    693      1.1   nonaka 			device_printf(sc->sc_dev, "short read: %u\n", rlen);
    694      1.1   nonaka 			return;
    695      1.1   nonaka 		}
    696      1.1   nonaka 
    697      1.1   nonaka #ifdef HVS_DEBUG_IO
    698      1.1   nonaka 		printf("%s: rid %"PRIu64" operation %u flags %#x status %#x\n",
    699      1.1   nonaka 		    device_xname(sc->sc_dev), rid, cmd.cmd_op, cmd.cmd_flags,
    700      1.1   nonaka 		    cmd.cmd_status);
    701      1.1   nonaka #endif
    702      1.1   nonaka 
    703      1.1   nonaka 		switch (cmd.cmd_op) {
    704      1.1   nonaka 		case HVS_MSG_IODONE:
    705      1.1   nonaka 			if (rid >= sc->sc_nccb) {
    706      1.1   nonaka 				device_printf(sc->sc_dev,
    707      1.1   nonaka 				    "invalid response %#"PRIx64"\n", rid);
    708      1.1   nonaka 				continue;
    709      1.1   nonaka 			}
    710      1.1   nonaka 			ccb = &sc->sc_ccbs[rid];
    711      1.1   nonaka 			ccb->ccb_cmd = &cmd;
    712      1.1   nonaka 			ccb->ccb_done(ccb);
    713      1.1   nonaka 			break;
    714      1.1   nonaka 		case HVS_MSG_ENUMERATE:
    715      1.1   nonaka 			hvs_scsi_probe(sc);
    716      1.1   nonaka 			break;
    717      1.1   nonaka 		default:
    718      1.1   nonaka 			device_printf(sc->sc_dev,
    719      1.1   nonaka 			    "operation %u is not implemented\n", cmd.cmd_op);
    720      1.1   nonaka 			break;
    721      1.1   nonaka 		}
    722      1.1   nonaka 	}
    723      1.1   nonaka }
    724      1.1   nonaka 
    725      1.1   nonaka static int
    726      1.1   nonaka is_inquiry_valid(struct scsipi_inquiry_data *inq)
    727      1.1   nonaka {
    728      1.1   nonaka 
    729      1.1   nonaka 	if ((inq->device & SID_TYPE) == T_NODEVICE)
    730      1.1   nonaka 		return 0;
    731      1.1   nonaka 	if ((inq->device & SID_QUAL) == SID_QUAL_LU_NOT_SUPP)
    732      1.1   nonaka 		return 0;
    733      1.1   nonaka 	return 1;
    734      1.1   nonaka }
    735      1.1   nonaka 
    736      1.1   nonaka static void
    737      1.1   nonaka fixup_inquiry(struct scsipi_xfer *xs, struct hvs_srb *srb)
    738      1.1   nonaka {
    739      1.1   nonaka 	struct scsipi_periph *periph = xs->xs_periph;
    740      1.1   nonaka 	struct scsipi_channel *chan = periph->periph_channel;
    741      1.1   nonaka 	struct scsipi_adapter *adapt = chan->chan_adapter;
    742      1.1   nonaka 	struct hvs_softc *sc = device_private(adapt->adapt_dev);
    743      1.1   nonaka 	struct scsipi_inquiry_data *inq = (void *)xs->data;
    744      1.1   nonaka 	int datalen, resplen;
    745      1.1   nonaka 	char vendor[8];
    746      1.1   nonaka 
    747      1.1   nonaka 	resplen = srb->srb_datalen >= 5 ? inq->additional_length + 5 : 0;
    748      1.1   nonaka 	datalen = MIN(resplen, srb->srb_datalen);
    749      1.1   nonaka 
    750      1.1   nonaka 	/* Fixup wrong response from WS2012 */
    751      1.1   nonaka 	if (sc->sc_config->fixup_wrong_response &&
    752      1.1   nonaka 	    !is_inquiry_valid(inq) && datalen >= 4 &&
    753      1.1   nonaka 	    (inq->version == 0 || inq->response_format == 0)) {
    754      1.1   nonaka 		inq->version = 0x05; /* SPC-3 */
    755      1.1   nonaka 		inq->response_format = SID_FORMAT_ISO;
    756      1.1   nonaka 	} else if (datalen >= SCSIPI_INQUIRY_LENGTH_SCSI2) {
    757      1.1   nonaka 		/*
    758      1.1   nonaka 		 * Upgrade SPC2 to SPC3 if host is Win8 or WS2012 R2
    759      1.1   nonaka 		 * to support UNMAP feature.
    760      1.1   nonaka 		 */
    761      1.1   nonaka 		strnvisx(vendor, sizeof(vendor), inq->vendor, sizeof(vendor),
    762      1.1   nonaka 		    VIS_TRIM|VIS_SAFE|VIS_OCTAL);
    763      1.1   nonaka 		if (sc->sc_config->upgrade_spc2_to_spc3 &&
    764      1.1   nonaka 		    (inq->version & SID_ANSII) == 0x04 /* SPC-2 */ &&
    765      1.1   nonaka 		    !strncmp(vendor, "Msft", 4))
    766      1.1   nonaka 			inq->version = 0x05; /* SPC-3 */
    767      1.1   nonaka 	}
    768      1.1   nonaka }
    769      1.1   nonaka 
    770      1.1   nonaka static void
    771      1.1   nonaka hvs_scsi_cmd_done(struct hvs_ccb *ccb)
    772      1.1   nonaka {
    773      1.1   nonaka 	struct scsipi_xfer *xs = ccb->ccb_xfer;
    774      1.1   nonaka 	struct scsipi_periph *periph = xs->xs_periph;
    775      1.1   nonaka 	struct scsipi_channel *chan = periph->periph_channel;
    776      1.1   nonaka 	struct scsipi_adapter *adapt = chan->chan_adapter;
    777      1.1   nonaka 	struct hvs_softc *sc = device_private(adapt->adapt_dev);
    778      1.1   nonaka 	union hvs_cmd *cmd = ccb->ccb_cmd;
    779      1.1   nonaka 	struct hvs_srb *srb;
    780      1.1   nonaka 	bus_dmamap_t map;
    781      1.1   nonaka 	int error;
    782      1.1   nonaka 
    783      1.1   nonaka 	map = ccb->ccb_dmap;
    784      1.1   nonaka 	bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, XS2DMAPOST(xs));
    785      1.1   nonaka 	bus_dmamap_unload(sc->sc_dmat, map);
    786      1.1   nonaka 
    787      1.1   nonaka 	xs = ccb->ccb_xfer;
    788      1.1   nonaka 	srb = &cmd->io.cmd_srb;
    789      1.1   nonaka 
    790      1.1   nonaka 	xs->status = srb->srb_scsistatus & 0xff;
    791      1.1   nonaka 
    792      1.1   nonaka 	switch (xs->status) {
    793      1.1   nonaka 	case SCSI_OK:
    794      1.1   nonaka 		if ((srb->srb_iostatus & ~(SRB_STATUS_AUTOSENSE_VALID |
    795      1.1   nonaka 		    SRB_STATUS_QUEUE_FROZEN)) != SRB_STATUS_SUCCESS)
    796      1.1   nonaka 			error = XS_SELTIMEOUT;
    797      1.1   nonaka 		else
    798      1.1   nonaka 			error = XS_NOERROR;
    799      1.1   nonaka 		break;
    800      1.1   nonaka 	case SCSI_BUSY:
    801      1.1   nonaka 	case SCSI_QUEUE_FULL:
    802      1.1   nonaka 		device_printf(sc->sc_dev, "status %#x iostatus %#x (busy)\n",
    803      1.1   nonaka 		    srb->srb_scsistatus, srb->srb_iostatus);
    804      1.1   nonaka 		error = XS_BUSY;
    805      1.1   nonaka 		break;
    806      1.1   nonaka 	case SCSI_CHECK:
    807      1.1   nonaka 		if (srb->srb_iostatus & SRB_STATUS_AUTOSENSE_VALID) {
    808      1.1   nonaka 			memcpy(&xs->sense, srb->srb_data,
    809      1.1   nonaka 			    MIN(sizeof(xs->sense), srb->srb_senselen));
    810      1.1   nonaka 			error = XS_SENSE;
    811      1.1   nonaka 			break;
    812      1.1   nonaka 		}
    813      1.1   nonaka 		/* FALLTHROUGH */
    814      1.1   nonaka 	default:
    815      1.1   nonaka 		error = XS_DRIVER_STUFFUP;
    816      1.1   nonaka 		break;
    817      1.1   nonaka 	}
    818      1.1   nonaka 
    819      1.1   nonaka 	if (error == XS_NOERROR) {
    820      1.1   nonaka 		if (xs->cmd->opcode == INQUIRY)
    821      1.1   nonaka 			fixup_inquiry(xs, srb);
    822      1.1   nonaka 		else if (srb->srb_direction != SRB_DATA_NONE)
    823      1.1   nonaka 			xs->resid = xs->datalen - srb->srb_datalen;
    824      1.1   nonaka 	}
    825      1.1   nonaka 
    826      1.1   nonaka 	hvs_put_ccb(sc, ccb);
    827      1.1   nonaka 	hvs_scsi_done(xs, error);
    828      1.1   nonaka }
    829      1.1   nonaka 
    830      1.1   nonaka static void
    831      1.1   nonaka hvs_scsi_probe(void *arg)
    832      1.1   nonaka {
    833      1.1   nonaka 	struct hvs_softc *sc = arg;
    834      1.1   nonaka 
    835      1.1   nonaka 	if (sc->sc_scsibus != NULL)
    836  1.5.2.1  thorpej 		scsi_probe_bus(device_private(sc->sc_scsibus), -1, -1);
    837      1.1   nonaka }
    838      1.1   nonaka 
    839      1.1   nonaka static void
    840      1.1   nonaka hvs_scsi_done(struct scsipi_xfer *xs, int error)
    841      1.1   nonaka {
    842      1.1   nonaka 
    843      1.1   nonaka 	xs->error = error;
    844      1.1   nonaka 	scsipi_done(xs);
    845      1.1   nonaka }
    846      1.1   nonaka 
    847      1.1   nonaka static int
    848      1.1   nonaka hvs_connect(struct hvs_softc *sc)
    849      1.1   nonaka {
    850      1.1   nonaka 	union hvs_cmd ucmd;
    851      1.1   nonaka 	struct hvs_cmd_ver *cmd;
    852      1.1   nonaka 	struct hvs_chp *chp;
    853      1.1   nonaka 	struct hvs_ccb *ccb;
    854      1.1   nonaka #if notyet /* XXX subchannel */
    855      1.1   nonaka 	struct vmbus_softc *vsc;
    856      1.1   nonaka 	struct vmbus_channel **subchan;
    857      1.1   nonaka 	uint32_t version;
    858      1.1   nonaka 	uint16_t max_subch, req_subch;
    859      1.1   nonaka 	bool support_multichannel = false;
    860      1.1   nonaka #endif
    861      1.1   nonaka 	int i;
    862      1.1   nonaka 
    863      1.1   nonaka 	ccb = hvs_get_ccb(sc);
    864      1.1   nonaka 	if (ccb == NULL) {
    865      1.1   nonaka 		aprint_error_dev(sc->sc_dev, "failed to allocate ccb\n");
    866      1.1   nonaka 		return -1;
    867      1.1   nonaka 	}
    868      1.1   nonaka 
    869      1.1   nonaka 	ccb->ccb_done = hvs_empty_done;
    870      1.1   nonaka 
    871      1.1   nonaka 	cmd = (struct hvs_cmd_ver *)&ucmd;
    872      1.1   nonaka 
    873      1.1   nonaka 	/*
    874      1.1   nonaka 	 * Begin initialization
    875      1.1   nonaka 	 */
    876      1.1   nonaka 
    877      1.1   nonaka 	memset(&ucmd, 0, sizeof(ucmd));
    878      1.1   nonaka 
    879      1.1   nonaka 	cmd->cmd_op = HVS_REQ_STARTINIT;
    880      1.1   nonaka 	cmd->cmd_flags = VMBUS_CHANPKT_FLAG_RC;
    881      1.1   nonaka 
    882      1.1   nonaka 	ccb->ccb_cmd = &ucmd;
    883      1.1   nonaka 	if (hvs_poll(sc, sc->sc_chan, ccb)) {
    884      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    885      1.1   nonaka 		    "failed to send initialization command\n");
    886      1.1   nonaka 		goto error;
    887      1.1   nonaka 	}
    888      1.1   nonaka 	if (ccb->ccb_rsp.cmd_status != 0) {
    889      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    890      1.1   nonaka 		    "failed to initialize, status %#x\n",
    891      1.1   nonaka 		    ccb->ccb_rsp.cmd_status);
    892      1.1   nonaka 		goto error;
    893      1.1   nonaka 	}
    894      1.1   nonaka 
    895      1.1   nonaka 	/*
    896      1.1   nonaka 	 * Negotiate protocol version
    897      1.1   nonaka 	 */
    898      1.1   nonaka 
    899      1.1   nonaka 	memset(&ucmd, 0, sizeof(ucmd));
    900      1.1   nonaka 
    901      1.1   nonaka 	cmd->cmd_op = HVS_REQ_QUERYPROTO;
    902      1.1   nonaka 	cmd->cmd_flags = VMBUS_CHANPKT_FLAG_RC;
    903      1.1   nonaka 
    904      1.1   nonaka 	for (i = 0; i < __arraycount(hvs_config_list); i++) {
    905      1.1   nonaka 		cmd->cmd_ver = hvs_config_list[i].proto_version;
    906      1.1   nonaka 
    907      1.1   nonaka 		ccb->ccb_cmd = &ucmd;
    908      1.1   nonaka 		if (hvs_poll(sc, sc->sc_chan, ccb)) {
    909      1.1   nonaka 			aprint_error_dev(sc->sc_dev,
    910      1.1   nonaka 			    "failed to send protocol query\n");
    911      1.1   nonaka 			goto error;
    912      1.1   nonaka 		}
    913      1.1   nonaka 		if (ccb->ccb_rsp.cmd_status == 0) {
    914      1.1   nonaka 			sc->sc_config = &hvs_config_list[i];
    915      1.1   nonaka 			break;
    916      1.1   nonaka 		}
    917      1.1   nonaka 	}
    918      1.1   nonaka 	if (sc->sc_config == NULL) {
    919      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    920      1.1   nonaka 		    "failed to negotiate protocol version\n");
    921      1.1   nonaka 		goto error;
    922      1.1   nonaka 	}
    923      1.1   nonaka 
    924      1.1   nonaka 	/*
    925      1.1   nonaka 	 * Query channel properties
    926      1.1   nonaka 	 */
    927      1.1   nonaka 
    928      1.1   nonaka 	memset(&ucmd, 0, sizeof(ucmd));
    929      1.1   nonaka 
    930      1.1   nonaka 	cmd->cmd_op = HVS_REQ_QUERYPROPS;
    931      1.1   nonaka 	cmd->cmd_flags = VMBUS_CHANPKT_FLAG_RC;
    932      1.1   nonaka 
    933      1.1   nonaka 	ccb->ccb_cmd = &ucmd;
    934      1.1   nonaka 	if (hvs_poll(sc, sc->sc_chan, ccb)) {
    935      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    936      1.1   nonaka 		    "failed to send channel properties query\n");
    937      1.1   nonaka 		goto error;
    938      1.1   nonaka 	}
    939      1.1   nonaka 	if (ccb->ccb_rsp.cmd_op != HVS_MSG_IODONE ||
    940      1.1   nonaka 	    ccb->ccb_rsp.cmd_status != 0) {
    941      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    942      1.1   nonaka 		    "failed to obtain channel properties, status %#x\n",
    943      1.1   nonaka 		    ccb->ccb_rsp.cmd_status);
    944      1.1   nonaka 		goto error;
    945      1.1   nonaka 	}
    946      1.1   nonaka 	chp = &ccb->ccb_rsp.chp.cmd_chp;
    947      1.1   nonaka 
    948      1.1   nonaka 	DPRINTF("%s: proto %#x path %u target %u maxchan %u port %u "
    949      1.1   nonaka 	    "chflags %#x maxfer %u chanid %#"PRIx64"\n",
    950      1.1   nonaka 	    device_xname(sc->sc_dev), chp->chp_proto, chp->chp_path,
    951      1.1   nonaka 	    chp->chp_target, chp->chp_maxchan, chp->chp_port,
    952      1.1   nonaka 	    chp->chp_chflags, chp->chp_maxfer, chp->chp_chanid);
    953      1.1   nonaka 
    954      1.1   nonaka #if notyet /* XXX subchannel */
    955      1.1   nonaka 	max_subch = chp->chp_maxchan;
    956      1.1   nonaka 	if (hvs_chan_cnt > 0 && hvs_chan_cnt < (max_subch + 1))
    957      1.1   nonaka 		max_subch = hvs_chan_cnt - 1;
    958      1.1   nonaka 
    959      1.1   nonaka 	/* multi-channels feature is supported by WIN8 and above version */
    960      1.1   nonaka 	version = sc->sc_chan->ch_sc->sc_proto;
    961      1.1   nonaka 	if (version != VMBUS_VERSION_WIN7 && version != VMBUS_VERSION_WS2008 &&
    962      1.1   nonaka 	    ISSET(chp->chp_chflags, CHP_CHFLAGS_MULTI_CHANNEL))
    963      1.1   nonaka 		support_multichannel = true;
    964      1.1   nonaka #endif
    965      1.1   nonaka 
    966      1.1   nonaka 	/* XXX */
    967      1.1   nonaka 	sc->sc_bus = chp->chp_path;
    968      1.1   nonaka 	sc->sc_channel.chan_id = chp->chp_target;
    969      1.1   nonaka 
    970      1.1   nonaka 	/*
    971      1.1   nonaka 	 * Finish initialization
    972      1.1   nonaka 	 */
    973      1.1   nonaka 
    974      1.1   nonaka 	memset(&ucmd, 0, sizeof(ucmd));
    975      1.1   nonaka 
    976      1.1   nonaka 	cmd->cmd_op = HVS_REQ_FINISHINIT;
    977      1.1   nonaka 	cmd->cmd_flags = VMBUS_CHANPKT_FLAG_RC;
    978      1.1   nonaka 
    979      1.1   nonaka 	ccb->ccb_cmd = &ucmd;
    980      1.1   nonaka 	if (hvs_poll(sc, sc->sc_chan, ccb)) {
    981      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    982      1.1   nonaka 		    "failed to send initialization finish\n");
    983      1.1   nonaka 		goto error;
    984      1.1   nonaka 	}
    985      1.1   nonaka 	if (ccb->ccb_rsp.cmd_op != HVS_MSG_IODONE ||
    986      1.1   nonaka 	    ccb->ccb_rsp.cmd_status != 0) {
    987      1.1   nonaka 		aprint_error_dev(sc->sc_dev,
    988      1.1   nonaka 		    "failed to finish initialization, status %#x\n",
    989      1.1   nonaka 		    ccb->ccb_rsp.cmd_status);
    990      1.1   nonaka 		goto error;
    991      1.1   nonaka 	}
    992      1.1   nonaka 
    993      1.1   nonaka #if notyet /* XXX subchannel */
    994      1.1   nonaka 	if (support_multichannel && max_subch > 0 && ncpu > 1) {
    995      1.1   nonaka 		req_subch = MIN(max_subch, ncpu - 1);
    996      1.1   nonaka 
    997      1.1   nonaka 		memset(&ucmd, 0, sizeof(ucmd));
    998      1.1   nonaka 
    999      1.1   nonaka 		cmd->cmd_op = HVS_REQ_CREATEMULTICHANNELS;
   1000      1.1   nonaka 		cmd->cmd_flags = VMBUS_CHANPKT_FLAG_RC;
   1001      1.1   nonaka 		cmd->u.multi_chans_cnt = req_subch;
   1002      1.1   nonaka 
   1003      1.1   nonaka 		ccb->ccb_cmd = &ucmd;
   1004      1.1   nonaka 		if (hvs_poll(sc, sc->sc_chan, ccb)) {
   1005      1.1   nonaka 			aprint_error_dev(sc->sc_dev,
   1006      1.1   nonaka 			    "failed to send create multi-channel\n");
   1007      1.1   nonaka 			goto out;
   1008      1.1   nonaka 		}
   1009      1.1   nonaka 		if (ccb->ccb_rsp.cmd_op != HVS_MSG_IODONE ||
   1010      1.1   nonaka 		    ccb->ccb_rsp.cmd_status != 0) {
   1011      1.1   nonaka 			aprint_error_dev(sc->sc_dev,
   1012      1.1   nonaka 			    "failed to create multi-channel, status %#x\n",
   1013      1.1   nonaka 			    ccb->ccb_rsp.cmd_status);
   1014      1.1   nonaka 			goto out;
   1015      1.1   nonaka 		}
   1016      1.1   nonaka 
   1017      1.1   nonaka 		sc->sc_nchan = req_subch + 1;
   1018      1.1   nonaka 		subchan = vmbus_subchan_get(sc->sc_chan, req_subch);
   1019      1.1   nonaka 		for (i = 0; i < req_subch; i++)
   1020      1.1   nonaka 			hsv_subchan_attach(sc, subchan[i]);
   1021      1.1   nonaka 		vmbus_subchan_rel(subchan, req_subch);
   1022      1.1   nonaka 		aprint_normal_dev(sc->sc_dev, "using %u channels\n",
   1023      1.1   nonaka 		    sc->sc_nchan);
   1024      1.1   nonaka 	}
   1025      1.1   nonaka out:
   1026      1.1   nonaka #endif
   1027      1.1   nonaka 	hvs_put_ccb(sc, ccb);
   1028      1.1   nonaka 	return 0;
   1029      1.1   nonaka 
   1030      1.1   nonaka error:
   1031      1.1   nonaka 	hvs_put_ccb(sc, ccb);
   1032      1.1   nonaka 	return -1;
   1033      1.1   nonaka }
   1034      1.1   nonaka 
   1035      1.1   nonaka static void
   1036      1.1   nonaka hvs_empty_done(struct hvs_ccb *ccb)
   1037      1.1   nonaka {
   1038      1.1   nonaka 	/* nothing */
   1039      1.1   nonaka }
   1040      1.1   nonaka 
   1041      1.1   nonaka static int
   1042      1.1   nonaka hvs_alloc_ccbs(struct hvs_softc *sc)
   1043      1.1   nonaka {
   1044      1.1   nonaka 	const int dmaflags = cold ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
   1045      1.1   nonaka 	int i, error;
   1046      1.1   nonaka 
   1047      1.1   nonaka 	SIMPLEQ_INIT(&sc->sc_ccb_fq);
   1048      1.1   nonaka 	mutex_init(&sc->sc_ccb_fqlck, MUTEX_DEFAULT, IPL_BIO);
   1049      1.1   nonaka 
   1050      1.1   nonaka 	sc->sc_nccb = HVS_MAX_CCB;
   1051      1.1   nonaka 	sc->sc_ccbs = kmem_zalloc(sc->sc_nccb * sizeof(struct hvs_ccb),
   1052      1.2      chs 	    KM_SLEEP);
   1053      1.1   nonaka 
   1054      1.1   nonaka 	for (i = 0; i < sc->sc_nccb; i++) {
   1055      1.1   nonaka 		error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, HVS_MAX_SGE,
   1056      1.1   nonaka 		    PAGE_SIZE, PAGE_SIZE, dmaflags, &sc->sc_ccbs[i].ccb_dmap);
   1057      1.1   nonaka 		if (error) {
   1058      1.1   nonaka 			aprint_error_dev(sc->sc_dev,
   1059      1.1   nonaka 			    "failed to create a CCB memory map (%d)\n", error);
   1060      1.1   nonaka 			goto errout;
   1061      1.1   nonaka 		}
   1062      1.1   nonaka 
   1063      1.1   nonaka 		sc->sc_ccbs[i].ccb_sgl = kmem_zalloc(
   1064      1.1   nonaka 		    sizeof(struct vmbus_gpa_range) * (HVS_MAX_SGE + 1),
   1065      1.2      chs 		    KM_SLEEP);
   1066      1.1   nonaka 		sc->sc_ccbs[i].ccb_rid = i;
   1067      1.1   nonaka 		hvs_put_ccb(sc, &sc->sc_ccbs[i]);
   1068      1.1   nonaka 	}
   1069      1.1   nonaka 
   1070      1.1   nonaka 	return 0;
   1071      1.1   nonaka 
   1072      1.1   nonaka  errout:
   1073      1.1   nonaka 	hvs_free_ccbs(sc);
   1074      1.1   nonaka 	return -1;
   1075      1.1   nonaka }
   1076      1.1   nonaka 
   1077      1.1   nonaka static void
   1078      1.1   nonaka hvs_free_ccbs(struct hvs_softc *sc)
   1079      1.1   nonaka {
   1080      1.1   nonaka 	struct hvs_ccb *ccb;
   1081      1.1   nonaka 	int i;
   1082      1.1   nonaka 
   1083      1.1   nonaka 	for (i = 0; i < sc->sc_nccb; i++) {
   1084      1.1   nonaka 		ccb = &sc->sc_ccbs[i];
   1085      1.1   nonaka 		if (ccb->ccb_dmap == NULL)
   1086      1.1   nonaka 			continue;
   1087      1.1   nonaka 
   1088      1.3   nonaka 		bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmap,
   1089      1.3   nonaka 		    0, ccb->ccb_dmap->dm_mapsize,
   1090      1.1   nonaka 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1091      1.1   nonaka 		bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmap);
   1092      1.1   nonaka 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmap);
   1093      1.1   nonaka 
   1094      1.1   nonaka 		kmem_free(ccb->ccb_sgl,
   1095      1.1   nonaka 		    sizeof(struct vmbus_gpa_range) * (HVS_MAX_SGE + 1));
   1096      1.1   nonaka 	}
   1097      1.1   nonaka 
   1098      1.1   nonaka 	kmem_free(sc->sc_ccbs, sc->sc_nccb * sizeof(struct hvs_ccb));
   1099      1.1   nonaka 	sc->sc_ccbs = NULL;
   1100      1.1   nonaka 	sc->sc_nccb = 0;
   1101      1.1   nonaka }
   1102      1.1   nonaka 
   1103      1.1   nonaka static struct hvs_ccb *
   1104      1.1   nonaka hvs_get_ccb(struct hvs_softc *sc)
   1105      1.1   nonaka {
   1106      1.1   nonaka 	struct hvs_ccb *ccb;
   1107      1.1   nonaka 
   1108      1.1   nonaka 	mutex_enter(&sc->sc_ccb_fqlck);
   1109      1.1   nonaka 	ccb = SIMPLEQ_FIRST(&sc->sc_ccb_fq);
   1110      1.1   nonaka 	if (ccb != NULL)
   1111      1.1   nonaka 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_fq, ccb_link);
   1112      1.1   nonaka 	mutex_exit(&sc->sc_ccb_fqlck);
   1113      1.1   nonaka 
   1114      1.1   nonaka 	return ccb;
   1115      1.1   nonaka }
   1116      1.1   nonaka 
   1117      1.1   nonaka static void
   1118      1.1   nonaka hvs_put_ccb(struct hvs_softc *sc, struct hvs_ccb *ccb)
   1119      1.1   nonaka {
   1120      1.1   nonaka 
   1121      1.1   nonaka 	ccb->ccb_cmd = NULL;
   1122      1.1   nonaka 	ccb->ccb_xfer = NULL;
   1123      1.1   nonaka 	ccb->ccb_done = NULL;
   1124      1.1   nonaka 	ccb->ccb_cookie = NULL;
   1125      1.1   nonaka 	ccb->ccb_nsge = 0;
   1126      1.1   nonaka 
   1127      1.1   nonaka 	mutex_enter(&sc->sc_ccb_fqlck);
   1128      1.1   nonaka 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_fq, ccb, ccb_link);
   1129      1.1   nonaka 	mutex_exit(&sc->sc_ccb_fqlck);
   1130      1.1   nonaka }
   1131