1 /* $NetBSD: umassvar.h,v 1.40 2021/12/31 14:24:16 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>, 5 * Nick Hibma <n_hibma@freebsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: src/sys/dev/usb/umass.c,v 1.13 2000/03/26 01:39:12 n_hibma Exp $ 30 */ 31 32 #ifdef UMASS_DEBUG 33 #define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0) 34 extern int umassdebug; 35 #else 36 #define umassdebug 0 37 #define DIF(m, x) /* nop */ 38 #endif 39 40 #define DPRINTFM(M,FMT,A,B,C,D) USBHIST_LOGM(umassdebug,M,FMT,A,B,C,D) 41 #define UMASSHIST_FUNC() USBHIST_FUNC() 42 #define UMASSHIST_CALLED(name) USBHIST_CALLED(umassdebug) 43 44 #define UDMASS_UPPER 0x00008000 /* upper layer */ 45 #define UDMASS_GEN 0x00010000 /* general */ 46 #define UDMASS_SCSI 0x00020000 /* scsi */ 47 #define UDMASS_UFI 0x00040000 /* ufi command set */ 48 #define UDMASS_8070 0x00080000 /* 8070i command set */ 49 #define UDMASS_USB 0x00100000 /* USB general */ 50 #define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */ 51 #define UDMASS_CBI 0x00400000 /* CBI transfers */ 52 #define UDMASS_ALL 0xffff0000 /* all of the above */ 53 54 #define UDMASS_XFER 0x40000000 /* all transfers */ 55 #define UDMASS_CMD 0x80000000 56 57 /* Generic definitions */ 58 59 #define UFI_COMMAND_LENGTH 12 60 61 /* Direction for umass_*_transfer */ 62 #define DIR_NONE 0 63 #define DIR_IN 1 64 #define DIR_OUT 2 65 66 /* Endpoints for umass */ 67 #define UMASS_BULKIN 0 68 #define UMASS_BULKOUT 1 69 #define UMASS_INTRIN 2 70 #define UMASS_NEP 3 71 72 /* Bulk-Only features */ 73 74 #define UR_BBB_RESET 0xff /* Bulk-Only reset */ 75 #define UR_BBB_GET_MAX_LUN 0xfe 76 77 /* Command Block Wrapper */ 78 typedef struct { 79 uDWord dCBWSignature; 80 #define CBWSIGNATURE 0x43425355 81 uDWord dCBWTag; 82 uDWord dCBWDataTransferLength; 83 uByte bCBWFlags; 84 #define CBWFLAGS_OUT 0x00 85 #define CBWFLAGS_IN 0x80 86 uByte bCBWLUN; 87 uByte bCDBLength; 88 #define CBWCDBLENGTH 16 89 uByte CBWCDB[CBWCDBLENGTH]; 90 } umass_bbb_cbw_t; 91 #define UMASS_BBB_CBW_SIZE 31 92 93 /* Command Status Wrapper */ 94 typedef struct { 95 uDWord dCSWSignature; 96 #define CSWSIGNATURE 0x53425355 97 #define CSWSIGNATURE_OLYMPUS_C1 0x55425355 98 uDWord dCSWTag; 99 uDWord dCSWDataResidue; 100 uByte bCSWStatus; 101 #define CSWSTATUS_GOOD 0x0 102 #define CSWSTATUS_FAILED 0x1 103 #define CSWSTATUS_PHASE 0x2 104 } umass_bbb_csw_t; 105 #define UMASS_BBB_CSW_SIZE 13 106 107 /* CBI features */ 108 109 #define UR_CBI_ADSC 0x00 110 111 typedef unsigned char umass_cbi_cbl_t[16]; /* Command block */ 112 113 typedef union { 114 struct { 115 uByte type; 116 #define IDB_TYPE_CCI 0x00 117 uByte value; 118 #define IDB_VALUE_PASS 0x00 119 #define IDB_VALUE_FAIL 0x01 120 #define IDB_VALUE_PHASE 0x02 121 #define IDB_VALUE_PERSISTENT 0x03 122 #define IDB_VALUE_STATUS_MASK 0x03 123 } common; 124 125 struct { 126 uByte asc; 127 uByte ascq; 128 } ufi; 129 } umass_cbi_sbl_t; 130 131 struct umass_softc; /* see below */ 132 133 typedef void (*umass_callback)(struct umass_softc *, void *, int, int); 134 #define STATUS_CMD_OK 0 /* everything ok */ 135 #define STATUS_CMD_UNKNOWN 1 /* will have to fetch sense */ 136 #define STATUS_CMD_FAILED 2 /* transfer was ok, command failed */ 137 #define STATUS_WIRE_FAILED 3 /* couldn't even get command across */ 138 #define STATUS_TIMEOUT 4 /* transfer aborted */ 139 140 typedef void (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *, 141 int, int, u_int, int, umass_callback, void *); 142 typedef void (*umass_wire_reset)(struct umass_softc *, int); 143 typedef void (*umass_wire_state)(struct usbd_xfer *, void *, 144 usbd_status); 145 146 struct umass_wire_methods { 147 umass_wire_xfer wire_xfer; 148 umass_wire_reset wire_reset; 149 umass_wire_state wire_state; 150 }; 151 152 struct umassbus_softc { 153 device_t sc_child; /* child device, for detach */ 154 }; 155 156 /* the per device structure */ 157 struct umass_softc { 158 device_t sc_dev; /* base device */ 159 struct usbd_device * sc_udev; /* device */ 160 struct usbd_interface * sc_iface; /* interface */ 161 int sc_ifaceno; /* interface number */ 162 163 uint8_t sc_epaddr[UMASS_NEP]; 164 struct usbd_pipe * sc_pipe[UMASS_NEP]; 165 usb_device_request_t sc_req; 166 167 const struct umass_wire_methods *sc_methods; 168 169 kmutex_t sc_lock; 170 171 uint8_t sc_wire; /* wire protocol */ 172 #define UMASS_WPROTO_UNSPEC 0 173 #define UMASS_WPROTO_BBB 1 174 #define UMASS_WPROTO_CBI 2 175 #define UMASS_WPROTO_CBI_I 3 176 177 uint8_t sc_cmd; /* command protocol */ 178 #define UMASS_CPROTO_UNSPEC 0 179 #define UMASS_CPROTO_SCSI 1 180 #define UMASS_CPROTO_ATAPI 2 181 #define UMASS_CPROTO_UFI 3 182 #define UMASS_CPROTO_RBC 4 183 #define UMASS_CPROTO_ISD_ATA 5 184 185 uint32_t sc_quirks; 186 #define UMASS_QUIRK_WRONG_CSWSIG 0x00000001 187 #define UMASS_QUIRK_WRONG_CSWTAG 0x00000002 188 #define UMASS_QUIRK_RBC_PAD_TO_12 0x00000004 189 #define UMASS_QUIRK_NOGETMAXLUN 0x00000008 190 191 #define UMASS_QUIRK_USE_DEFAULTMATCH -1 192 193 uint32_t sc_busquirks; 194 195 /* Bulk specific variables for transfers in progress */ 196 umass_bbb_cbw_t cbw; /* command block wrapper */ 197 umass_bbb_csw_t csw; /* command status wrapper*/ 198 /* CBI specific variables for transfers in progress */ 199 umass_cbi_cbl_t cbl; /* command block */ 200 umass_cbi_sbl_t sbl; /* status block */ 201 202 /* xfer handles 203 * Most of our operations are initiated from interrupt context, so 204 * we need to avoid using the one that is in use. We have to avoid 205 * allocating them in the interrupt context as well. 206 */ 207 /* indices into array below */ 208 #define XFER_BBB_CBW 0 /* Bulk-Only */ 209 #define XFER_BBB_DATAIN 1 210 #define XFER_BBB_DATAOUT 2 211 #define XFER_BBB_DCLEAR 3 212 #define XFER_BBB_CSW1 4 213 #define XFER_BBB_CSW2 5 214 #define XFER_BBB_SCLEAR 6 215 #define XFER_BBB_RESET1 7 216 #define XFER_BBB_RESET2 8 217 #define XFER_BBB_RESET3 9 218 219 #define XFER_CBI_CB 0 /* CBI */ 220 #define XFER_CBI_DATAIN 1 221 #define XFER_CBI_DATAOUT 2 222 #define XFER_CBI_STATUS 3 223 #define XFER_CBI_DCLEAR 4 224 #define XFER_CBI_SCLEAR 5 225 #define XFER_CBI_RESET1 6 226 #define XFER_CBI_RESET2 7 227 #define XFER_CBI_RESET3 8 228 229 #define XFER_NR 10 /* maximum number */ 230 231 struct usbd_xfer *transfer_xfer[XFER_NR]; /* for ctrl xfers */ 232 233 void *datain_buffer; 234 void *dataout_buffer; 235 void *cmd_buffer; 236 void *s1_buffer; 237 void *s2_buffer; 238 239 int transfer_dir; /* data direction */ 240 void *transfer_data; /* data buffer */ 241 int transfer_datalen; /* (maximum) length */ 242 int transfer_actlen; /* actual length */ 243 umass_callback transfer_cb; /* callback */ 244 void *transfer_priv; /* for callback */ 245 int transfer_status; 246 247 int transfer_state; 248 #define TSTATE_IDLE 0 249 #define TSTATE_BBB_COMMAND 1 /* CBW transfer */ 250 #define TSTATE_BBB_DATA 2 /* Data transfer */ 251 #define TSTATE_BBB_DCLEAR 3 /* clear endpt stall */ 252 #define TSTATE_BBB_STATUS1 4 /* clear endpt stall */ 253 #define TSTATE_BBB_SCLEAR 5 /* clear endpt stall */ 254 #define TSTATE_BBB_STATUS2 6 /* CSW transfer */ 255 #define TSTATE_BBB_RESET1 7 /* reset command */ 256 #define TSTATE_BBB_RESET2 8 /* in clear stall */ 257 #define TSTATE_BBB_RESET3 9 /* out clear stall */ 258 #define TSTATE_CBI_COMMAND 10 /* command transfer */ 259 #define TSTATE_CBI_DATA 11 /* data transfer */ 260 #define TSTATE_CBI_STATUS 12 /* status transfer */ 261 #define TSTATE_CBI_DCLEAR 13 /* clear ep stall */ 262 #define TSTATE_CBI_SCLEAR 14 /* clear ep stall */ 263 #define TSTATE_CBI_RESET1 15 /* reset command */ 264 #define TSTATE_CBI_RESET2 16 /* in clear stall */ 265 #define TSTATE_CBI_RESET3 17 /* out clear stall */ 266 #define TSTATE_STATES 18 /* # of states above */ 267 268 269 int timeout; /* in msecs */ 270 271 uint8_t maxlun; /* max lun supported */ 272 273 #ifdef UMASS_DEBUG 274 struct timeval tv; 275 #endif 276 277 char sc_dying; 278 int sc_sense; 279 280 struct umassbus_softc *bus; /* bus dependent data */ 281 }; 282 283 #define UMASS_MAX_TRANSFER_SIZE MAXPHYS 284