1 /* Driver for USB Mass Storage compliant devices
3 * $Id: protocol.c,v 1.7 2000/11/13 22:28:33 mdharm Exp $
5 * Current development and maintenance by:
6 * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
8 * Developed with the assistance of:
9 * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
12 * (c) 1999 Michael Gee (michael@linuxspecific.com)
14 * This driver is based on the 'USB Mass Storage Class' document. This
15 * describes in detail the protocol used to communicate with such
16 * devices. Clearly, the designers had SCSI and ATAPI commands in
17 * mind when they created this document. The commands are all very
18 * similar to commands in the SCSI-II and ATAPI specifications.
20 * It is important to note that in a number of cases this class
21 * exhibits class-specific exemptions from the USB specification.
22 * Notably the usage of NAK, STALL and ACK differs from the norm, in
23 * that they are used to communicate wait, failed and OK on commands.
25 * Also, for certain devices, the interrupt endpoint is used to convey
26 * status of a command.
28 * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
29 * information about this driver.
31 * This program is free software; you can redistribute it and/or modify it
32 * under the terms of the GNU General Public License as published by the
33 * Free Software Foundation; either version 2, or (at your option) any
36 * This program is distributed in the hope that it will be useful, but
37 * WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 * General Public License for more details.
41 * You should have received a copy of the GNU General Public License along
42 * with this program; if not, write to the Free Software Foundation, Inc.,
43 * 675 Mass Ave, Cambridge, MA 02139, USA.
50 #include "transport.h"
52 /***********************************************************************
54 ***********************************************************************/
56 /* Fix-up the return data from an INQUIRY command to show
57 * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us
59 void fix_inquiry_data(Scsi_Cmnd
*srb
)
61 unsigned char *data_ptr
;
63 /* verify that it's an INQUIRY command */
64 if (srb
->cmnd
[0] != INQUIRY
)
67 US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2\n");
69 /* find the location of the data */
71 struct scatterlist
*sg
;
73 sg
= (struct scatterlist
*) srb
->request_buffer
;
74 data_ptr
= (unsigned char *) sg
[0].address
;
76 data_ptr
= (unsigned char *)srb
->request_buffer
;
78 /* Change the SCSI revision number */
82 /***********************************************************************
84 ***********************************************************************/
86 void usb_stor_qic157_command(Scsi_Cmnd
*srb
, struct us_data
*us
)
88 /* Pad the ATAPI command with zeros
89 * NOTE: This only works because a Scsi_Cmnd struct field contains
90 * a unsigned char cmnd[12], so we know we have storage available
92 for (; srb
->cmd_len
<12; srb
->cmd_len
++)
93 srb
->cmnd
[srb
->cmd_len
] = 0;
95 /* set command length to 12 bytes */
98 /* send the command to the transport layer */
99 usb_stor_invoke_transport(srb
, us
);
101 /* fix the INQUIRY data if necessary */
102 fix_inquiry_data(srb
);
105 void usb_stor_ATAPI_command(Scsi_Cmnd
*srb
, struct us_data
*us
)
109 /* Fix some commands -- this is a form of mode translation
110 * ATAPI devices only accept 12 byte long commands
112 * NOTE: This only works because a Scsi_Cmnd struct field contains
113 * a unsigned char cmnd[12], so we know we have storage available
116 /* Pad the ATAPI command with zeros */
117 for (; srb
->cmd_len
<12; srb
->cmd_len
++)
118 srb
->cmnd
[srb
->cmd_len
] = 0;
120 /* set command length to 12 bytes */
123 /* determine the correct (or minimum) data length for these commands */
124 switch (srb
->cmnd
[0]) {
126 /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
129 /* save the command so we can tell what it was */
130 old_cmnd
= srb
->cmnd
[0];
135 srb
->cmnd
[8] = srb
->cmnd
[4];
141 srb
->cmnd
[2] = srb
->cmnd
[2];
142 srb
->cmnd
[1] = srb
->cmnd
[1];
143 srb
->cmnd
[0] = srb
->cmnd
[0] | 0x40;
146 /* change READ_6/WRITE_6 to READ_10/WRITE_10, which
147 * are ATAPI commands */
153 srb
->cmnd
[8] = srb
->cmnd
[4];
156 srb
->cmnd
[5] = srb
->cmnd
[3];
157 srb
->cmnd
[4] = srb
->cmnd
[2];
158 srb
->cmnd
[3] = srb
->cmnd
[1] & 0x1F;
160 srb
->cmnd
[1] = srb
->cmnd
[1] & 0xE0;
161 srb
->cmnd
[0] = srb
->cmnd
[0] | 0x20;
163 } /* end switch on cmnd[0] */
165 /* convert MODE_SELECT data here */
166 if (old_cmnd
== MODE_SELECT
)
167 usb_stor_scsiSense6to10(srb
);
169 /* send the command to the transport layer */
170 usb_stor_invoke_transport(srb
, us
);
172 /* Fix the MODE_SENSE data if we translated the command */
173 if ((old_cmnd
== MODE_SENSE
) && (status_byte(srb
->result
) == GOOD
))
174 usb_stor_scsiSense10to6(srb
);
176 /* fix the INQUIRY data if necessary */
177 fix_inquiry_data(srb
);
181 void usb_stor_ufi_command(Scsi_Cmnd
*srb
, struct us_data
*us
)
185 /* fix some commands -- this is a form of mode translation
186 * UFI devices only accept 12 byte long commands
188 * NOTE: This only works because a Scsi_Cmnd struct field contains
189 * a unsigned char cmnd[12], so we know we have storage available
192 /* set command length to 12 bytes (this affects the transport layer) */
195 /* determine the correct (or minimum) data length for these commands */
196 switch (srb
->cmnd
[0]) {
198 /* for INQUIRY, UFI devices only ever return 36 bytes */
203 /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
206 /* save the command so we can tell what it was */
207 old_cmnd
= srb
->cmnd
[0];
213 /* if we're sending data, we send all. If getting data,
215 if (srb
->cmnd
[0] == MODE_SELECT
)
216 srb
->cmnd
[8] = srb
->cmnd
[4];
225 srb
->cmnd
[2] = srb
->cmnd
[2];
226 srb
->cmnd
[1] = srb
->cmnd
[1];
227 srb
->cmnd
[0] = srb
->cmnd
[0] | 0x40;
230 /* again, for MODE_SENSE_10, we get the minimum (8) */
236 /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
241 /* change READ_6/WRITE_6 to READ_10/WRITE_10, which
242 * are UFI commands */
248 srb
->cmnd
[8] = srb
->cmnd
[4];
251 srb
->cmnd
[5] = srb
->cmnd
[3];
252 srb
->cmnd
[4] = srb
->cmnd
[2];
253 srb
->cmnd
[3] = srb
->cmnd
[1] & 0x1F;
255 srb
->cmnd
[1] = srb
->cmnd
[1] & 0xE0;
256 srb
->cmnd
[0] = srb
->cmnd
[0] | 0x20;
258 } /* end switch on cmnd[0] */
260 /* convert MODE_SELECT data here */
261 if (old_cmnd
== MODE_SELECT
)
262 usb_stor_scsiSense6to10(srb
);
264 /* send the command to the transport layer */
265 usb_stor_invoke_transport(srb
, us
);
267 /* Fix the MODE_SENSE data if we translated the command */
268 if ((old_cmnd
== MODE_SENSE
) && (status_byte(srb
->result
) == GOOD
))
269 usb_stor_scsiSense10to6(srb
);
271 /* Fix the data for an INQUIRY, if necessary */
272 fix_inquiry_data(srb
);
275 void usb_stor_transparent_scsi_command(Scsi_Cmnd
*srb
, struct us_data
*us
)
277 /* This code supports devices which do not support {READ|WRITE}_6
278 * Apparently, neither Windows or MacOS will use these commands,
279 * so some devices do not support them
281 if (us
->flags
& US_FL_MODE_XLATE
) {
283 /* translate READ_6 to READ_10 */
284 if (srb
->cmnd
[0] == 0x08) {
286 /* get the control */
287 srb
->cmnd
[9] = us
->srb
->cmnd
[5];
290 srb
->cmnd
[8] = us
->srb
->cmnd
[6];
293 /* set the reserved area to 0 */
297 srb
->cmnd
[5] = us
->srb
->cmnd
[3];
298 srb
->cmnd
[4] = us
->srb
->cmnd
[2];
302 /* LUN and other info in cmnd[1] can stay */
304 /* fix command code */
307 US_DEBUGP("Changing READ_6 to READ_10\n");
308 US_DEBUG(usb_stor_show_command(srb
));
311 /* translate WRITE_6 to WRITE_10 */
312 if (srb
->cmnd
[0] == 0x0A) {
314 /* get the control */
315 srb
->cmnd
[9] = us
->srb
->cmnd
[5];
318 srb
->cmnd
[8] = us
->srb
->cmnd
[4];
321 /* set the reserved area to 0 */
325 srb
->cmnd
[5] = us
->srb
->cmnd
[3];
326 srb
->cmnd
[4] = us
->srb
->cmnd
[2];
330 /* LUN and other info in cmnd[1] can stay */
332 /* fix command code */
335 US_DEBUGP("Changing WRITE_6 to WRITE_10\n");
336 US_DEBUG(usb_stor_show_command(us
->srb
));
338 } /* if (us->flags & US_FL_MODE_XLATE) */
340 /* send the command to the transport layer */
341 usb_stor_invoke_transport(srb
, us
);
343 /* fix the INQUIRY data if necessary */
344 fix_inquiry_data(srb
);