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) |
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 | |
139 | typedef void (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *, |
140 | int, int, u_int, int, umass_callback, void *); |
141 | typedef void (*umass_wire_reset)(struct umass_softc *, int); |
142 | typedef void (*umass_wire_state)(struct usbd_xfer *, void *, |
143 | usbd_status); |
144 | |
145 | struct umass_wire_methods { |
146 | umass_wire_xfer wire_xfer; |
147 | umass_wire_reset wire_reset; |
148 | umass_wire_state wire_state; |
149 | }; |
150 | |
151 | struct umassbus_softc { |
152 | device_t sc_child; /* child device, for detach */ |
153 | }; |
154 | |
155 | /* the per device structure */ |
156 | struct 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 | |