xref: /netbsd-src/sys/dev/usb/umassvar.h (revision f3b3760cdb540602cb6697147639e32b33c71687)
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