117359Swosch/*- 217359Swosch * Copyright (c) 2012, Bryan Venteicher <bryanv@FreeBSD.org> 317359Swosch * All rights reserved. 417359Swosch * 517359Swosch * Redistribution and use in source and binary forms, with or without 617359Swosch * modification, are permitted provided that the following conditions 717359Swosch * are met: 817359Swosch * 1. Redistributions of source code must retain the above copyright 917359Swosch * notice unmodified, this list of conditions, and the following 1017359Swosch * disclaimer. 1117359Swosch * 2. Redistributions in binary form must reproduce the above copyright 1217359Swosch * notice, this list of conditions and the following disclaimer in the 1317359Swosch * documentation and/or other materials provided with the distribution. 1417359Swosch * 1517359Swosch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1617359Swosch * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1717359Swosch * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1817359Swosch * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1917359Swosch * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2017359Swosch * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2117359Swosch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2217359Swosch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2317359Swosch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2417359Swosch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2517359Swosch * 2617359Swosch * $FreeBSD: releng/10.2/sys/dev/virtio/scsi/virtio_scsivar.h 252707 2013-07-04 17:57:26Z bryanv $ 2717359Swosch */ 2817359Swosch 2917359Swosch#ifndef _VIRTIO_SCSIVAR_H 3017359Swosch#define _VIRTIO_SCSIVAR_H 3117359Swosch 3217359Swoschstruct vtscsi_softc; 3317359Swoschstruct vtscsi_request; 3417359Swosch 3517359Swoschtypedef void vtscsi_request_cb_t(struct vtscsi_softc *, 3617359Swosch struct vtscsi_request *); 3717359Swosch 3817359Swoschstruct vtscsi_statistics { 3917359Swosch unsigned long scsi_cmd_timeouts; 4017359Swosch unsigned long dequeue_no_requests; 4117359Swosch}; 4217359Swosch 4317359Swoschstruct vtscsi_softc { 4417359Swosch device_t vtscsi_dev; 4517359Swosch struct mtx vtscsi_mtx; 4617359Swosch uint64_t vtscsi_features; 4717359Swosch 4817359Swosch uint16_t vtscsi_flags; 4917359Swosch#define VTSCSI_FLAG_INDIRECT 0x0001 5017359Swosch#define VTSCSI_FLAG_BIDIRECTIONAL 0x0002 5117359Swosch#define VTSCSI_FLAG_HOTPLUG 0x0004 5217359Swosch#define VTSCSI_FLAG_RESET 0x0008 5317359Swosch#define VTSCSI_FLAG_DETACH 0x0010 5417359Swosch 5517359Swosch uint16_t vtscsi_frozen; 5617359Swosch#define VTSCSI_FROZEN_NO_REQUESTS 0x01 5717359Swosch#define VTSCSI_FROZEN_REQUEST_VQ_FULL 0x02 5817359Swosch 5917359Swosch struct sglist *vtscsi_sglist; 6017359Swosch 6117359Swosch struct virtqueue *vtscsi_control_vq; 6217359Swosch struct virtqueue *vtscsi_event_vq; 6317359Swosch struct virtqueue *vtscsi_request_vq; 6417359Swosch 6517359Swosch struct cam_sim *vtscsi_sim; 6617359Swosch struct cam_path *vtscsi_path; 6717359Swosch 6817359Swosch int vtscsi_debug; 6917359Swosch int vtscsi_nrequests; 7017359Swosch int vtscsi_max_nsegs; 7117359Swosch int vtscsi_event_buf_size; 7217359Swosch 7317359Swosch TAILQ_HEAD(,vtscsi_request) 7417359Swosch vtscsi_req_free; 7517359Swosch 7617359Swosch uint16_t vtscsi_max_channel; 7717359Swosch uint16_t vtscsi_max_target; 7817359Swosch uint32_t vtscsi_max_lun; 7917359Swosch 8017359Swosch#define VTSCSI_NUM_EVENT_BUFS 4 8117359Swosch struct virtio_scsi_event 8217359Swosch vtscsi_event_bufs[VTSCSI_NUM_EVENT_BUFS]; 8317359Swosch 8417359Swosch struct vtscsi_statistics vtscsi_stats; 8517359Swosch}; 8617359Swosch 8717359Swoschenum vtscsi_request_state { 8817359Swosch VTSCSI_REQ_STATE_FREE, 8917359Swosch VTSCSI_REQ_STATE_INUSE, 9017359Swosch VTSCSI_REQ_STATE_ABORTED, 9117359Swosch VTSCSI_REQ_STATE_TIMEDOUT 9217359Swosch}; 9317359Swosch 9418194Ssosstruct vtscsi_request { 9517359Swosch struct vtscsi_softc *vsr_softc; 9617359Swosch union ccb *vsr_ccb; 9717359Swosch vtscsi_request_cb_t *vsr_complete; 9817359Swosch 9917359Swosch void *vsr_ptr0; 10017359Swosch/* Request when aborting a timedout command. */ 10117359Swosch#define vsr_timedout_req vsr_ptr0 10217359Swosch 10317359Swosch enum vtscsi_request_state vsr_state; 10417359Swosch 10517359Swosch uint16_t vsr_flags; 10617359Swosch#define VTSCSI_REQ_FLAG_POLLED 0x01 10717359Swosch#define VTSCSI_REQ_FLAG_COMPLETE 0x02 10817359Swosch#define VTSCSI_REQ_FLAG_TIMEOUT_SET 0x04 10917359Swosch 11017359Swosch union { 11117359Swosch struct virtio_scsi_cmd_req cmd; 11217359Swosch struct virtio_scsi_ctrl_tmf_req tmf; 11317359Swosch struct virtio_scsi_ctrl_an_req an; 11417359Swosch } vsr_ureq; 11517359Swosch#define vsr_cmd_req vsr_ureq.cmd 11617359Swosch#define vsr_tmf_req vsr_ureq.tmf 11717359Swosch#define vsr_an_req vsr_ureq.an 11817359Swosch 11917359Swosch /* Make request and response non-contiguous. */ 12017359Swosch uint32_t vsr_pad; 12117359Swosch 12217359Swosch union { 12318194Ssos struct virtio_scsi_cmd_resp cmd; 124 struct virtio_scsi_ctrl_tmf_resp tmf; 125 struct virtio_scsi_ctrl_an_resp an; 126 } vsr_uresp; 127#define vsr_cmd_resp vsr_uresp.cmd 128#define vsr_tmf_resp vsr_uresp.tmf 129#define vsr_an_resp vsr_uresp.an 130 131 struct callout vsr_callout; 132 133 TAILQ_ENTRY(vtscsi_request) vsr_link; 134}; 135 136/* Private field in the CCB header that points to our request. */ 137#define ccbh_vtscsi_req spriv_ptr0 138 139/* Features desired/implemented by this driver. */ 140#define VTSCSI_FEATURES \ 141 (VIRTIO_SCSI_F_HOTPLUG | \ 142 VIRTIO_RING_F_INDIRECT_DESC) 143 144#define VTSCSI_MTX(_sc) &(_sc)->vtscsi_mtx 145#define VTSCSI_LOCK_INIT(_sc, _name) mtx_init(VTSCSI_MTX(_sc), _name, \ 146 "VTSCSI Lock", MTX_DEF) 147#define VTSCSI_LOCK(_sc) mtx_lock(VTSCSI_MTX(_sc)) 148#define VTSCSI_UNLOCK(_sc) mtx_unlock(VTSCSI_MTX(_sc)) 149#define VTSCSI_LOCK_OWNED(_sc) mtx_assert(VTSCSI_MTX(_sc), MA_OWNED) 150#define VTSCSI_LOCK_NOTOWNED(_sc) mtx_assert(VTSCSI_MTX(_sc), MA_NOTOWNED) 151#define VTSCSI_LOCK_DESTROY(_sc) mtx_destroy(VTSCSI_MTX(_sc)) 152 153/* 154 * Reasons for either freezing or thawing the SIMQ. 155 * 156 * VirtIO SCSI is a bit unique in the sense that SCSI and TMF 157 * commands go over different queues. Both queues are fed by 158 * the same SIMQ, but we only freeze the SIMQ when the request 159 * (SCSI) virtqueue is full, not caring if the control (TMF) 160 * virtqueue unlikely gets full. However, both queues share the 161 * same pool of requests, so the completion of a TMF command 162 * could cause the SIMQ to be unfrozen. 163 */ 164#define VTSCSI_REQUEST 0x01 165#define VTSCSI_REQUEST_VQ 0x02 166 167/* Debug trace levels. */ 168#define VTSCSI_INFO 0x01 169#define VTSCSI_ERROR 0x02 170#define VTSCSI_TRACE 0x04 171 172#define vtscsi_dprintf(_sc, _level, _msg, _args ...) do { \ 173 if ((_sc)->vtscsi_debug & (_level)) \ 174 device_printf((_sc)->vtscsi_dev, "%s: "_msg, \ 175 __FUNCTION__, ##_args); \ 176} while (0) 177 178#define vtscsi_dprintf_req(_req, _level, _msg, _args ...) do { \ 179 struct vtscsi_softc *__sc = (_req)->vsr_softc; \ 180 if ((__sc)->vtscsi_debug & (_level)) \ 181 vtscsi_printf_req(_req, __FUNCTION__, _msg, ##_args); \ 182} while (0) 183 184/* 185 * Set the status field in a CCB, optionally clearing non CCB_STATUS_* flags. 186 */ 187#define vtscsi_set_ccb_status(_ccbh, _status, _mask) do { \ 188 KASSERT(((_mask) & CAM_STATUS_MASK) == 0, \ 189 ("%s:%d bad mask: 0x%x", __FUNCTION__, __LINE__, (_mask))); \ 190 (_ccbh)->status &= ~(CAM_STATUS_MASK | (_mask)); \ 191 (_ccbh)->status |= (_status); \ 192} while (0) 193 194/* 195 * One segment each for the request and the response. 196 */ 197#define VTSCSI_MIN_SEGMENTS 2 198 199/* 200 * Allocate additional requests for internal use such 201 * as TM commands (e.g. aborting timedout commands). 202 */ 203#define VTSCSI_RESERVED_REQUESTS 10 204 205/* 206 * Specification doesn't say, use traditional SCSI default. 207 */ 208#define VTSCSI_INITIATOR_ID 7 209 210/* 211 * How to wait (or not) for request completion. 212 */ 213#define VTSCSI_EXECUTE_ASYNC 0 214#define VTSCSI_EXECUTE_POLL 1 215 216#endif /* _VIRTIO_SCSIVAR_H */ 217