1/** @file
2  Definition of the command set of USB Mass Storage Specification
3  for Bootability, Revision 1.0.
4
5Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
6This program and the accompanying materials
7are licensed and made available under the terms and conditions of the BSD License
8which accompanies this distribution.  The full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16#ifndef _EFI_USB_MASS_BOOT_H_
17#define _EFI_USB_MASS_BOOT_H_
18
19//
20// The opcodes of various USB boot commands:
21// INQUIRY/REQUEST_SENSE are "No Timeout Commands" as specified
22// by Multi-Media Commands (MMC) set.
23// Others are "Group 1 Timeout Commands". That is,
24// they should be retried if driver is ready.
25//
26#define USB_BOOT_INQUIRY_OPCODE         0x12
27#define USB_BOOT_REQUEST_SENSE_OPCODE   0x03
28#define USB_BOOT_MODE_SENSE10_OPCODE    0x5A
29#define USB_BOOT_READ_CAPACITY_OPCODE   0x25
30#define USB_BOOT_TEST_UNIT_READY_OPCODE 0x00
31#define USB_BOOT_READ10_OPCODE          0x28
32#define USB_BOOT_WRITE10_OPCODE         0x2A
33
34#define USB_SCSI_MODE_SENSE6_OPCODE     0x1A
35
36//
37// The Sense Key part of the sense data. Sense data has three levels:
38// Sense key, Additional Sense Code and Additional Sense Code Qualifier
39//
40#define USB_BOOT_SENSE_NO_SENSE         0x00 ///< No sense key
41#define USB_BOOT_SENSE_RECOVERED        0x01 ///< Last command succeed with recovery actions
42#define USB_BOOT_SENSE_NOT_READY        0x02 ///< Device not ready
43#define USB_BOOT_SNESE_MEDIUM_ERROR     0X03 ///< Failed probably because flaw in the media
44#define USB_BOOT_SENSE_HARDWARE_ERROR   0X04 ///< Non-recoverable hardware failure
45#define USB_BOOT_SENSE_ILLEGAL_REQUEST  0X05 ///< Illegal parameters in the request
46#define USB_BOOT_SENSE_UNIT_ATTENTION   0X06 ///< Removable medium may have been changed
47#define USB_BOOT_SENSE_DATA_PROTECT     0X07 ///< Write protected
48#define USB_BOOT_SENSE_BLANK_CHECK      0X08 ///< Blank/non-blank medium while reading/writing
49#define USB_BOOT_SENSE_VENDOR           0X09 ///< Vendor specific sense key
50#define USB_BOOT_SENSE_ABORTED          0X0B ///< Command aborted by the device
51#define USB_BOOT_SENSE_VOLUME_OVERFLOW  0x0D ///< Partition overflow
52#define USB_BOOT_SENSE_MISCOMPARE       0x0E ///< Source data mis-match while verfying.
53
54#define USB_BOOT_ASC_NOT_READY          0x04
55#define USB_BOOT_ASC_NO_MEDIA           0x3A
56#define USB_BOOT_ASC_MEDIA_CHANGE       0x28
57
58//
59// Supported PDT codes, or Peripheral Device Type
60//
61#define USB_PDT_DIRECT_ACCESS           0x00       ///< Direct access device
62#define USB_PDT_CDROM                   0x05       ///< CDROM
63#define USB_PDT_OPTICAL                 0x07       ///< Non-CD optical disks
64#define USB_PDT_SIMPLE_DIRECT           0x0E       ///< Simplified direct access device
65
66//
67// Other parameters, Max carried size is 512B * 128 = 64KB
68//
69#define USB_BOOT_IO_BLOCKS              128
70
71//
72// Retry mass command times, set by experience
73//
74#define USB_BOOT_COMMAND_RETRY          5
75
76//
77// Wait for unit ready command, set by experience
78//
79#define USB_BOOT_RETRY_UNIT_READY_STALL (500 * USB_MASS_1_MILLISECOND)
80
81//
82// Mass command timeout, refers to specification[USB20-9.2.6.1]
83//
84// USB2.0 Spec define the up-limit timeout 5s for all command. USB floppy,
85// USB CD-Rom and iPod devices are much slower than USB key when reponse
86// most of commands, So we set 5s as timeout here.
87//
88#define USB_BOOT_GENERAL_CMD_TIMEOUT    (5 * USB_MASS_1_SECOND)
89
90//
91// The required commands are INQUIRY, READ CAPACITY, TEST UNIT READY,
92// READ10, WRITE10, and REQUEST SENSE. The BLOCK_IO protocol uses LBA
93// so it isn't necessary to issue MODE SENSE / READ FORMAT CAPACITY
94// command to retrieve the disk gemotrics.
95//
96#pragma pack(1)
97typedef struct {
98  UINT8             OpCode;
99  UINT8             Lun;            ///< Lun (high 3 bits)
100  UINT8             Reserved0[2];
101  UINT8             AllocLen;
102  UINT8             Reserved1;
103  UINT8             Pad[6];
104} USB_BOOT_INQUIRY_CMD;
105
106typedef struct {
107  UINT8             Pdt;            ///< Peripheral Device Type (low 5 bits)
108  UINT8             Removable;      ///< Removable Media (highest bit)
109  UINT8             Reserved0[2];
110  UINT8             AddLen;         ///< Additional length
111  UINT8             Reserved1[3];
112  UINT8             VendorID[8];
113  UINT8             ProductID[16];
114  UINT8             ProductRevision[4];
115} USB_BOOT_INQUIRY_DATA;
116
117typedef struct {
118  UINT8             OpCode;
119  UINT8             Lun;
120  UINT8             Reserved0[8];
121  UINT8             Pad[2];
122} USB_BOOT_READ_CAPACITY_CMD;
123
124typedef struct {
125  UINT8             LastLba[4];
126  UINT8             BlockLen[4];
127} USB_BOOT_READ_CAPACITY_DATA;
128
129typedef struct {
130  UINT8             OpCode;
131  UINT8             Lun;
132  UINT8             Reserved[4];
133  UINT8             Pad[6];
134} USB_BOOT_TEST_UNIT_READY_CMD;
135
136typedef struct {
137  UINT8             OpCode;
138  UINT8             Lun;
139  UINT8             PageCode;
140  UINT8             Reserved0[4];
141  UINT8             ParaListLenMsb;
142  UINT8             ParaListLenLsb;
143  UINT8             Reserved1;
144  UINT8             Pad[2];
145} USB_BOOT_MODE_SENSE10_CMD;
146
147typedef struct {
148  UINT8             ModeDataLenMsb;
149  UINT8             ModeDataLenLsb;
150  UINT8             Reserved0[4];
151  UINT8             BlkDesLenMsb;
152  UINT8             BlkDesLenLsb;
153} USB_BOOT_MODE_SENSE10_PARA_HEADER;
154
155typedef struct {
156  UINT8             OpCode;
157  UINT8             Lun;            ///< Lun (High 3 bits)
158  UINT8             Lba[4];         ///< Logical block address
159  UINT8             Reserved0;
160  UINT8             TransferLen[2]; ///< Transfer length
161  UINT8             Reserverd1;
162  UINT8             Pad[2];
163} USB_BOOT_READ10_CMD;
164
165typedef struct {
166  UINT8             OpCode;
167  UINT8             Lun;
168  UINT8             Lba[4];
169  UINT8             Reserved0;
170  UINT8             TransferLen[2];
171  UINT8             Reserverd1;
172  UINT8             Pad[2];
173} USB_BOOT_WRITE10_CMD;
174
175typedef struct {
176  UINT8             OpCode;
177  UINT8             Lun;            ///< Lun (High 3 bits)
178  UINT8             Reserved0[2];
179  UINT8             AllocLen;       ///< Allocation length
180  UINT8             Reserved1;
181  UINT8             Pad[6];
182} USB_BOOT_REQUEST_SENSE_CMD;
183
184typedef struct {
185  UINT8             ErrorCode;
186  UINT8             Reserved0;
187  UINT8             SenseKey;       ///< Sense key (low 4 bits)
188  UINT8             Infor[4];
189  UINT8             AddLen;         ///< Additional Sense length, 10
190  UINT8             Reserved1[4];
191  UINT8             Asc;            ///< Additional Sense Code
192  UINT8             Ascq;           ///< Additional Sense Code Qualifier
193  UINT8             Reserverd2[4];
194} USB_BOOT_REQUEST_SENSE_DATA;
195
196typedef struct {
197  UINT8             OpCode;
198  UINT8             Lun;
199  UINT8             PageCode;
200  UINT8             Reserved0;
201  UINT8             AllocateLen;
202  UINT8             Control;
203} USB_SCSI_MODE_SENSE6_CMD;
204
205typedef struct {
206  UINT8             ModeDataLen;
207  UINT8             MediumType;
208  UINT8             DevicePara;
209  UINT8             BlkDesLen;
210} USB_SCSI_MODE_SENSE6_PARA_HEADER;
211#pragma pack()
212
213//
214// Convert a LUN number to that in the command
215//
216#define USB_BOOT_LUN(Lun) ((Lun) << 5)
217
218//
219// Get the removable, PDT, and sense key bits from the command data
220//
221#define USB_BOOT_REMOVABLE(RmbByte) (((RmbByte) & BIT7) != 0)
222#define USB_BOOT_PDT(Pdt)           ((Pdt) & 0x1f)
223#define USB_BOOT_SENSE_KEY(Key)     ((Key) & 0x0f)
224
225/**
226  Get the parameters for the USB mass storage media.
227
228  This function get the parameters for the USB mass storage media,
229  It is used both to initialize the media during the Start() phase
230  of Driver Binding Protocol and to re-initialize it when the media is
231  changed. Althought the RemoveableMedia is unlikely to change,
232  it is also included here.
233
234  @param  UsbMass                The device to retrieve disk gemotric.
235
236  @retval EFI_SUCCESS            The disk gemotric is successfully retrieved.
237  @retval Other                  Failed to get the parameters.
238
239**/
240EFI_STATUS
241UsbBootGetParams (
242  IN USB_MASS_DEVICE          *UsbMass
243  );
244
245/**
246  Execute TEST UNIT READY command to check if the device is ready.
247
248  @param  UsbMass                The device to test
249
250  @retval EFI_SUCCESS            The device is ready.
251  @retval Others                 Device not ready.
252
253**/
254EFI_STATUS
255UsbBootIsUnitReady (
256  IN USB_MASS_DEVICE          *UsbMass
257  );
258
259/**
260  Detect whether the removable media is present and whether it has changed.
261
262  @param  UsbMass                The device to check.
263
264  @retval EFI_SUCCESS            The media status is successfully checked.
265  @retval Other                  Failed to detect media.
266
267**/
268EFI_STATUS
269UsbBootDetectMedia (
270  IN  USB_MASS_DEVICE       *UsbMass
271  );
272
273/**
274  Read some blocks from the device.
275
276  @param  UsbMass                The USB mass storage device to read from
277  @param  Lba                    The start block number
278  @param  TotalBlock             Total block number to read
279  @param  Buffer                 The buffer to read to
280
281  @retval EFI_SUCCESS            Data are read into the buffer
282  @retval Others                 Failed to read all the data
283
284**/
285EFI_STATUS
286UsbBootReadBlocks (
287  IN  USB_MASS_DEVICE         *UsbMass,
288  IN  UINT32                  Lba,
289  IN  UINTN                   TotalBlock,
290  OUT UINT8                   *Buffer
291  );
292
293/**
294  Write some blocks to the device.
295
296  @param  UsbMass                The USB mass storage device to write to
297  @param  Lba                    The start block number
298  @param  TotalBlock             Total block number to write
299  @param  Buffer                 Pointer to the source buffer for the data.
300
301  @retval EFI_SUCCESS            Data are written into the buffer
302  @retval Others                 Failed to write all the data
303
304**/
305EFI_STATUS
306UsbBootWriteBlocks (
307  IN  USB_MASS_DEVICE         *UsbMass,
308  IN  UINT32                  Lba,
309  IN  UINTN                   TotalBlock,
310  IN  UINT8                   *Buffer
311  );
312
313/**
314  Read some blocks from the device by SCSI 16 byte cmd.
315
316  @param  UsbMass                The USB mass storage device to read from
317  @param  Lba                    The start block number
318  @param  TotalBlock             Total block number to read
319  @param  Buffer                 The buffer to read to
320
321  @retval EFI_SUCCESS            Data are read into the buffer
322  @retval Others                 Failed to read all the data
323
324**/
325EFI_STATUS
326UsbBootReadBlocks16 (
327  IN  USB_MASS_DEVICE       *UsbMass,
328  IN  UINT64                Lba,
329  IN  UINTN                 TotalBlock,
330  OUT UINT8                 *Buffer
331  );
332
333/**
334  Write some blocks to the device by SCSI 16 byte cmd.
335
336  @param  UsbMass                The USB mass storage device to write to
337  @param  Lba                    The start block number
338  @param  TotalBlock             Total block number to write
339  @param  Buffer                 Pointer to the source buffer for the data.
340
341  @retval EFI_SUCCESS            Data are written into the buffer
342  @retval Others                 Failed to write all the data
343
344**/
345EFI_STATUS
346UsbBootWriteBlocks16 (
347  IN  USB_MASS_DEVICE         *UsbMass,
348  IN  UINT64                  Lba,
349  IN  UINTN                   TotalBlock,
350  IN  UINT8                   *Buffer
351  );
352
353
354/**
355  Use the USB clear feature control transfer to clear the endpoint stall condition.
356
357  @param  UsbIo                  The USB I/O Protocol instance
358  @param  EndpointAddr           The endpoint to clear stall for
359
360  @retval EFI_SUCCESS            The endpoint stall condition is cleared.
361  @retval Others                 Failed to clear the endpoint stall condition.
362
363**/
364EFI_STATUS
365UsbClearEndpointStall (
366  IN EFI_USB_IO_PROTOCOL    *UsbIo,
367  IN UINT8                  EndpointAddr
368  );
369
370#endif
371
372