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