1/* $NetBSD: umassvar.h,v 1.38 2016/07/03 07:27:37 skrll 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)
34extern 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 */
78typedef 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 */
94typedef 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
111typedef unsigned char umass_cbi_cbl_t[16]; /* Command block */
112
113typedef 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
131struct umass_softc; /* see below */
132
133typedef 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
139typedef void (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *,
140 int, int, u_int, int, umass_callback, void *);
141typedef void (*umass_wire_reset)(struct umass_softc *, int);
142typedef void (*umass_wire_state)(struct usbd_xfer *, void *,
143 usbd_status);
144
145struct umass_wire_methods {
146 umass_wire_xfer wire_xfer;
147 umass_wire_reset wire_reset;
148 umass_wire_state wire_state;
149};
150
151struct umassbus_softc {
152 device_t sc_child; /* child device, for detach */
153};
154
155/* the per device structure */
156struct umass_softc {
157 device_t sc_dev; /* base device */
158 struct usbd_device * sc_udev; /* device */
159 struct usbd_interface * sc_iface; /* interface */
160 int sc_ifaceno; /* interface number */
161
162 uint8_t sc_epaddr[UMASS_NEP];
163 struct usbd_pipe * sc_pipe[UMASS_NEP];
164 usb_device_request_t sc_req;
165
166 const struct umass_wire_methods *sc_methods;
167
168 kmutex_t sc_lock;
169 kcondvar_t sc_detach_cv;
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_refcnt;
279 int sc_sense;
280
281 struct umassbus_softc *bus; /* bus dependent data */
282};
283
284#define UMASS_MAX_TRANSFER_SIZE MAXPHYS
285