Home | History | Annotate | Line # | Download | only in usb
      1 /*	$NetBSD: umassvar.h,v 1.40 2021/12/31 14:24:16 riastradh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999 MAEKAWA Masahide <bishop (at) rr.iij4u.or.jp>,
      5  *		      Nick Hibma <n_hibma (at) 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