2 Implementation of the command set of USB Mass Storage Specification
3 for Bootability, Revision 1.0.
5 Copyright (c) 2007 - 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UsbMassImpl.h"
19 Execute REQUEST SENSE Command to retrieve sense data from device.
21 @param UsbMass The device whose sense data is requested.
23 @retval EFI_SUCCESS The command is excuted successfully.
24 @retval EFI_DEVICE_ERROR Failed to request sense.
25 @retval EFI_NO_RESPONSE The device media doesn't response this request.
26 @retval EFI_INVALID_PARAMETER The command has some invalid parameters.
27 @retval EFI_WRITE_PROTECTED The device is write protected.
28 @retval EFI_MEDIA_CHANGED The device media has been changed.
33 IN USB_MASS_DEVICE
*UsbMass
36 USB_BOOT_REQUEST_SENSE_CMD SenseCmd
;
37 USB_BOOT_REQUEST_SENSE_DATA SenseData
;
38 EFI_BLOCK_IO_MEDIA
*Media
;
39 USB_MASS_TRANSPORT
*Transport
;
43 Transport
= UsbMass
->Transport
;
46 // Request the sense data from the device
48 ZeroMem (&SenseCmd
, sizeof (USB_BOOT_REQUEST_SENSE_CMD
));
49 ZeroMem (&SenseData
, sizeof (USB_BOOT_REQUEST_SENSE_DATA
));
51 SenseCmd
.OpCode
= USB_BOOT_REQUEST_SENSE_OPCODE
;
52 SenseCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
53 SenseCmd
.AllocLen
= sizeof (USB_BOOT_REQUEST_SENSE_DATA
);
55 Status
= Transport
->ExecCommand (
58 sizeof (USB_BOOT_REQUEST_SENSE_CMD
),
61 sizeof (USB_BOOT_REQUEST_SENSE_DATA
),
63 USB_BOOT_GENERAL_CMD_TIMEOUT
,
66 if (EFI_ERROR (Status
) || CmdResult
!= USB_MASS_CMD_SUCCESS
) {
67 DEBUG ((EFI_D_ERROR
, "UsbBootRequestSense: (%r) CmdResult=0x%x\n", Status
, CmdResult
));
72 // If sense data is retrieved successfully, interpret the sense data
73 // and update the media status if necessary.
75 Media
= &UsbMass
->BlockIoMedia
;
77 switch (USB_BOOT_SENSE_KEY (SenseData
.SenseKey
)) {
79 case USB_BOOT_SENSE_NO_SENSE
:
80 Status
= EFI_NO_RESPONSE
;
83 case USB_BOOT_SENSE_RECOVERED
:
85 // Suppose hardware can handle this case, and recover later by itself
87 Status
= EFI_NOT_READY
;
90 case USB_BOOT_SENSE_NOT_READY
:
91 Status
= EFI_DEVICE_ERROR
;
92 if (SenseData
.ASC
== USB_BOOT_ASC_NO_MEDIA
) {
93 Media
->MediaPresent
= FALSE
;
94 Status
= EFI_NO_MEDIA
;
95 } else if (SenseData
.ASC
== USB_BOOT_ASC_NOT_READY
) {
96 Status
= EFI_NOT_READY
;
100 case USB_BOOT_SENSE_ILLEGAL_REQUEST
:
101 Status
= EFI_INVALID_PARAMETER
;
104 case USB_BOOT_SENSE_UNIT_ATTENTION
:
105 Status
= EFI_DEVICE_ERROR
;
106 if (SenseData
.ASC
== USB_BOOT_ASC_MEDIA_CHANGE
) {
108 // If MediaChange, reset ReadOnly and new MediaId
110 Status
= EFI_MEDIA_CHANGED
;
111 Media
->ReadOnly
= FALSE
;
116 case USB_BOOT_SENSE_DATA_PROTECT
:
117 Status
= EFI_WRITE_PROTECTED
;
118 Media
->ReadOnly
= TRUE
;
122 Status
= EFI_DEVICE_ERROR
;
126 DEBUG ((EFI_D_INFO
, "UsbBootRequestSense: (%r) with sense key %x/%x/%x\n",
128 USB_BOOT_SENSE_KEY (SenseData
.SenseKey
),
138 Execute the USB mass storage bootability commands.
140 This function executes the USB mass storage bootability commands.
141 If execution failed, retrieve the error by REQUEST_SENSE, then
142 update the device's status, such as ReadyOnly.
144 @param UsbMass The device to issue commands to
145 @param Cmd The command to execute
146 @param CmdLen The length of the command
147 @param DataDir The direction of data transfer
148 @param Data The buffer to hold the data
149 @param DataLen The length of expected data
150 @param Timeout The timeout used to transfer
152 @retval EFI_SUCCESS Command is excuted successfully
153 @retval Others Command execution failed.
158 IN USB_MASS_DEVICE
*UsbMass
,
161 IN EFI_USB_DATA_DIRECTION DataDir
,
167 USB_MASS_TRANSPORT
*Transport
;
171 Transport
= UsbMass
->Transport
;
172 Status
= Transport
->ExecCommand (
184 // If ExecCommand() returns no error and CmdResult is success,
185 // then the commnad transfer is successful.
187 if ((CmdResult
== USB_MASS_CMD_SUCCESS
) && !EFI_ERROR (Status
)) {
191 DEBUG ((EFI_D_INFO
, "UsbBootExecCmd: Fail to Exec 0x%x Cmd /w %r\n",
192 *(UINT8
*)Cmd
,Status
));
195 // If command execution failed, then retrieve error info via sense request.
197 return UsbBootRequestSense (UsbMass
);
202 Execute the USB mass storage bootability commands with retrial.
204 This function executes USB mass storage bootability commands.
205 If the device isn't ready, wait for it. If the device is ready
206 and error occurs, retry the command again until it exceeds the
207 limit of retrial times.
209 @param UsbMass The device to issue commands to
210 @param Cmd The command to execute
211 @param CmdLen The length of the command
212 @param DataDir The direction of data transfer
213 @param Data The buffer to hold the data
214 @param DataLen The length of expected data
215 @param Timeout The timeout used to transfer
217 @retval EFI_SUCCESS The command is executed successfully.
218 @retval EFI_MEDIA_CHANGED The device media has been changed.
219 @retval Others Command execution failed after retrial.
223 UsbBootExecCmdWithRetry (
224 IN USB_MASS_DEVICE
*UsbMass
,
227 IN EFI_USB_DATA_DIRECTION DataDir
,
236 Status
= EFI_SUCCESS
;
238 for (Retry
= 0; Retry
< USB_BOOT_COMMAND_RETRY
; Retry
++) {
240 Status
= UsbBootExecCmd (
249 if (Status
== EFI_SUCCESS
|| Status
== EFI_MEDIA_CHANGED
) {
253 // If the device isn't ready, just wait for it without limit on retrial times.
255 if (Status
== EFI_NOT_READY
) {
265 Execute TEST UNIT READY command to check if the device is ready.
267 @param UsbMass The device to test
269 @retval EFI_SUCCESS The device is ready.
270 @retval Others Device not ready.
275 IN USB_MASS_DEVICE
*UsbMass
278 USB_BOOT_TEST_UNIT_READY_CMD TestCmd
;
280 ZeroMem (&TestCmd
, sizeof (USB_BOOT_TEST_UNIT_READY_CMD
));
282 TestCmd
.OpCode
= USB_BOOT_TEST_UNIT_READY_OPCODE
;
283 TestCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
285 return UsbBootExecCmdWithRetry (
288 sizeof (USB_BOOT_TEST_UNIT_READY_CMD
),
292 USB_BOOT_GENERAL_CMD_TIMEOUT
298 Execute INQUIRY Command to request information regarding parameters of
299 the device be sent to the host computer.
301 @param UsbMass The device to inquire.
303 @retval EFI_SUCCESS INQUIRY Command is executed successfully.
304 @retval Others INQUIRY Command is not executed successfully.
309 IN USB_MASS_DEVICE
*UsbMass
312 USB_BOOT_INQUIRY_CMD InquiryCmd
;
313 USB_BOOT_INQUIRY_DATA InquiryData
;
314 EFI_BLOCK_IO_MEDIA
*Media
;
317 Media
= &(UsbMass
->BlockIoMedia
);
319 ZeroMem (&InquiryCmd
, sizeof (USB_BOOT_INQUIRY_CMD
));
320 ZeroMem (&InquiryData
, sizeof (USB_BOOT_INQUIRY_DATA
));
322 InquiryCmd
.OpCode
= USB_BOOT_INQUIRY_OPCODE
;
323 InquiryCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
324 InquiryCmd
.AllocLen
= sizeof (InquiryData
);
326 Status
= UsbBootExecCmdWithRetry (
329 sizeof (USB_BOOT_INQUIRY_CMD
),
332 sizeof (USB_BOOT_INQUIRY_DATA
),
333 USB_BOOT_GENERAL_CMD_TIMEOUT
335 if (EFI_ERROR (Status
)) {
340 // Get information from PDT (Peripheral Device Type) field and Removable Medium Bit
341 // from the inquiry data.
343 UsbMass
->Pdt
= (UINT8
) (USB_BOOT_PDT (InquiryData
.Pdt
));
344 Media
->RemovableMedia
= (BOOLEAN
) (USB_BOOT_REMOVABLE (InquiryData
.Removable
));
346 // Set block size to the default value of 512 Bytes, in case no media is present at first time.
348 Media
->BlockSize
= 0x0200;
355 Execute READ CAPACITY command to request information regarding
356 the capacity of the installed medium of the device.
358 This function executes READ CAPACITY command to get the capacity
359 of the USB mass storage media, including the presence, block size,
360 and last block number.
362 @param UsbMass The device to retireve disk gemotric.
364 @retval EFI_SUCCESS The disk geometry is successfully retrieved.
365 @retval EFI_NOT_READY The returned block size is zero.
366 @retval Other READ CAPACITY command execution failed.
370 UsbBootReadCapacity (
371 IN USB_MASS_DEVICE
*UsbMass
374 USB_BOOT_READ_CAPACITY_CMD CapacityCmd
;
375 USB_BOOT_READ_CAPACITY_DATA CapacityData
;
376 EFI_BLOCK_IO_MEDIA
*Media
;
379 Media
= &UsbMass
->BlockIoMedia
;
381 ZeroMem (&CapacityCmd
, sizeof (USB_BOOT_READ_CAPACITY_CMD
));
382 ZeroMem (&CapacityData
, sizeof (USB_BOOT_READ_CAPACITY_DATA
));
384 CapacityCmd
.OpCode
= USB_BOOT_READ_CAPACITY_OPCODE
;
385 CapacityCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
387 Status
= UsbBootExecCmdWithRetry (
390 sizeof (USB_BOOT_READ_CAPACITY_CMD
),
393 sizeof (USB_BOOT_READ_CAPACITY_DATA
),
394 USB_BOOT_GENERAL_CMD_TIMEOUT
396 if (EFI_ERROR (Status
)) {
401 // Get the information on media presence, block size, and last block number
402 // from READ CAPACITY data.
404 Media
->MediaPresent
= TRUE
;
405 Media
->LastBlock
= SwapBytes32 (ReadUnaligned32 ((CONST UINT32
*) CapacityData
.LastLba
));
406 Media
->BlockSize
= SwapBytes32 (ReadUnaligned32 ((CONST UINT32
*) CapacityData
.BlockLen
));
408 if (Media
->BlockSize
== 0) {
409 return EFI_NOT_READY
;
412 DEBUG ((EFI_D_INFO
, "UsbBootReadCapacity Success LBA=%ld BlockSize=%d\n",
413 Media
->LastBlock
, Media
->BlockSize
));
419 Retrieves SCSI mode sense information via MODE SENSE(6) command.
421 @param UsbMass The device whose sense data is requested.
423 @retval EFI_SUCCESS SCSI mode sense information retrieved successfully.
424 @retval Other Command execution failed.
429 IN USB_MASS_DEVICE
*UsbMass
433 USB_SCSI_MODE_SENSE6_CMD ModeSenseCmd
;
434 USB_SCSI_MODE_SENSE6_PARA_HEADER ModeParaHeader
;
435 EFI_BLOCK_IO_MEDIA
*Media
;
437 Media
= &UsbMass
->BlockIoMedia
;
439 ZeroMem (&ModeSenseCmd
, sizeof (USB_SCSI_MODE_SENSE6_CMD
));
440 ZeroMem (&ModeParaHeader
, sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER
));
443 // MODE SENSE(6) command is defined in Section 8.2.10 of SCSI-2 Spec
445 ModeSenseCmd
.OpCode
= USB_SCSI_MODE_SENSE6_OPCODE
;
446 ModeSenseCmd
.Lun
= (UINT8
) USB_BOOT_LUN (UsbMass
->Lun
);
447 ModeSenseCmd
.PageCode
= 0x3F;
448 ModeSenseCmd
.AllocateLen
= (UINT8
) sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER
);
450 Status
= UsbBootExecCmdWithRetry (
453 sizeof (USB_SCSI_MODE_SENSE6_CMD
),
456 sizeof (USB_SCSI_MODE_SENSE6_PARA_HEADER
),
457 USB_BOOT_GENERAL_CMD_TIMEOUT
461 // Format of device-specific parameter byte of the mode parameter header is defined in
462 // Section 8.2.10 of SCSI-2 Spec.
463 // BIT7 of this byte is indicates whether the medium is write protected.
465 if (!EFI_ERROR (Status
)) {
466 Media
->ReadOnly
= (BOOLEAN
) ((ModeParaHeader
.DevicePara
& BIT7
) != 0);
474 Get the parameters for the USB mass storage media.
476 This function get the parameters for the USB mass storage media,
477 It is used both to initialize the media during the Start() phase
478 of Driver Binding Protocol and to re-initialize it when the media is
479 changed. Althought the RemoveableMedia is unlikely to change,
480 it is also included here.
482 @param UsbMass The device to retrieve disk gemotric.
484 @retval EFI_SUCCESS The disk gemotric is successfully retrieved.
485 @retval Other Failed to get the parameters.
490 IN USB_MASS_DEVICE
*UsbMass
493 EFI_BLOCK_IO_MEDIA
*Media
;
497 Media
= &(UsbMass
->BlockIoMedia
);
498 CmdSet
= ((EFI_USB_INTERFACE_DESCRIPTOR
*) (UsbMass
->Context
))->InterfaceSubClass
;
500 Status
= UsbBootInquiry (UsbMass
);
501 if (EFI_ERROR (Status
)) {
502 DEBUG ((EFI_D_ERROR
, "UsbBootGetParams: UsbBootInquiry (%r)\n", Status
));
507 // Don't use the Removable bit in inquiry data to test whether the media
508 // is removable because many flash disks wrongly set this bit.
510 if ((UsbMass
->Pdt
== USB_PDT_CDROM
) || (UsbMass
->Pdt
== USB_PDT_OPTICAL
)) {
512 // CD-Rom device and Non-CD optical device
514 UsbMass
->OpticalStorage
= TRUE
;
516 // Default value 2048 Bytes, in case no media present at first time
518 Media
->BlockSize
= 0x0800;
521 if ((UsbMass
->Pdt
!= USB_PDT_CDROM
) && (CmdSet
== USB_MASS_STORE_SCSI
)) {
523 // ModeSense is required for the device with PDT of 0x00/0x07/0x0E,
524 // which is from [MassStorageBootabilitySpec-Page7].
525 // ModeSense(10) is useless here, while ModeSense(6) defined in SCSI
526 // could get the information of WriteProtected.
527 // Since not all device support this command, so skip if fail.
529 UsbScsiModeSense (UsbMass
);
532 return UsbBootReadCapacity (UsbMass
);
537 Detect whether the removable media is present and whether it has changed.
539 @param UsbMass The device to check.
541 @retval EFI_SUCCESS The media status is successfully checked.
542 @retval Other Failed to detect media.
547 IN USB_MASS_DEVICE
*UsbMass
550 EFI_BLOCK_IO_MEDIA OldMedia
;
551 EFI_BLOCK_IO_MEDIA
*Media
;
556 Media
= &UsbMass
->BlockIoMedia
;
558 CopyMem (&OldMedia
, &(UsbMass
->BlockIoMedia
), sizeof (EFI_BLOCK_IO_MEDIA
));
560 CmdSet
= ((EFI_USB_INTERFACE_DESCRIPTOR
*) (UsbMass
->Context
))->InterfaceSubClass
;
562 Status
= UsbBootIsUnitReady (UsbMass
);
563 if (EFI_ERROR (Status
)) {
567 if ((UsbMass
->Pdt
!= USB_PDT_CDROM
) && (CmdSet
== USB_MASS_STORE_SCSI
)) {
569 // MODE SENSE is required for the device with PDT of 0x00/0x07/0x0E,
570 // according to Section 4 of USB Mass Storage Specification for Bootability.
571 // MODE SENSE(10) is useless here, while MODE SENSE(6) defined in SCSI
572 // could get the information of Write Protected.
573 // Since not all device support this command, skip if fail.
575 UsbScsiModeSense (UsbMass
);
578 Status
= UsbBootReadCapacity (UsbMass
);
579 if (EFI_ERROR (Status
)) {
580 DEBUG ((EFI_D_ERROR
, "UsbBootDetectMedia: UsbBootReadCapacity (%r)\n", Status
));
588 // Detect whether it is necessary to reinstall the Block I/O Protocol.
590 // MediaId may change in RequestSense for MediaChanged
591 // MediaPresent may change in RequestSense for NoMedia
592 // MediaReadOnly may change in RequestSense for WriteProtected or MediaChanged
593 // MediaPresent/BlockSize/LastBlock may change in ReadCapacity
595 if ((Media
->MediaId
!= OldMedia
.MediaId
) ||
596 (Media
->MediaPresent
!= OldMedia
.MediaPresent
) ||
597 (Media
->ReadOnly
!= OldMedia
.ReadOnly
) ||
598 (Media
->BlockSize
!= OldMedia
.BlockSize
) ||
599 (Media
->LastBlock
!= OldMedia
.LastBlock
)) {
602 // This function is called by Block I/O Protocol APIs, which run at TPL_NOTIFY.
603 // Here we temporarily restore TPL to TPL_CALLBACK to invoke ReinstallProtocolInterface().
605 OldTpl
= EfiGetCurrentTpl ();
606 gBS
->RestoreTPL (TPL_CALLBACK
);
608 gBS
->ReinstallProtocolInterface (
610 &gEfiBlockIoProtocolGuid
,
615 ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK
);
616 gBS
->RaiseTPL (OldTpl
);
619 // Update MediaId after reinstalling Block I/O Protocol.
621 if (Media
->MediaPresent
!= OldMedia
.MediaPresent
) {
622 if (Media
->MediaPresent
) {
629 if ((Media
->ReadOnly
!= OldMedia
.ReadOnly
) ||
630 (Media
->BlockSize
!= OldMedia
.BlockSize
) ||
631 (Media
->LastBlock
!= OldMedia
.LastBlock
)) {
641 Read some blocks from the device.
643 @param UsbMass The USB mass storage device to read from
644 @param Lba The start block number
645 @param TotalBlock Total block number to read
646 @param Buffer The buffer to read to
648 @retval EFI_SUCCESS Data are read into the buffer
649 @retval Others Failed to read all the data
654 IN USB_MASS_DEVICE
*UsbMass
,
660 USB_BOOT_READ10_CMD ReadCmd
;
667 BlockSize
= UsbMass
->BlockIoMedia
.BlockSize
;
668 Status
= EFI_SUCCESS
;
670 while (TotalBlock
> 0) {
672 // Split the total blocks into smaller pieces to ease the pressure
673 // on the device. We must split the total block because the READ10
674 // command only has 16 bit transfer length (in the unit of block).
676 Count
= (UINT16
)((TotalBlock
< USB_BOOT_IO_BLOCKS
) ? TotalBlock
: USB_BOOT_IO_BLOCKS
);
677 ByteSize
= (UINT32
)Count
* BlockSize
;
680 // USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]
682 Timeout
= (UINT32
) USB_BOOT_GENERAL_CMD_TIMEOUT
;
685 // Fill in the command then execute
687 ZeroMem (&ReadCmd
, sizeof (USB_BOOT_READ10_CMD
));
689 ReadCmd
.OpCode
= USB_BOOT_READ10_OPCODE
;
690 ReadCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
691 WriteUnaligned32 ((UINT32
*) ReadCmd
.Lba
, SwapBytes32 (Lba
));
692 WriteUnaligned16 ((UINT16
*) ReadCmd
.TransferLen
, SwapBytes16 (Count
));
694 Status
= UsbBootExecCmdWithRetry (
697 sizeof (USB_BOOT_READ10_CMD
),
703 if (EFI_ERROR (Status
)) {
708 Buffer
+= Count
* BlockSize
;
717 Write some blocks to the device.
719 @param UsbMass The USB mass storage device to write to
720 @param Lba The start block number
721 @param TotalBlock Total block number to write
722 @param Buffer Pointer to the source buffer for the data.
724 @retval EFI_SUCCESS Data are written into the buffer
725 @retval Others Failed to write all the data
730 IN USB_MASS_DEVICE
*UsbMass
,
736 USB_BOOT_WRITE10_CMD WriteCmd
;
743 BlockSize
= UsbMass
->BlockIoMedia
.BlockSize
;
744 Status
= EFI_SUCCESS
;
746 while (TotalBlock
> 0) {
748 // Split the total blocks into smaller pieces to ease the pressure
749 // on the device. We must split the total block because the WRITE10
750 // command only has 16 bit transfer length (in the unit of block).
752 Count
= (UINT16
)((TotalBlock
< USB_BOOT_IO_BLOCKS
) ? TotalBlock
: USB_BOOT_IO_BLOCKS
);
753 ByteSize
= (UINT32
)Count
* BlockSize
;
756 // USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]
758 Timeout
= (UINT32
) USB_BOOT_GENERAL_CMD_TIMEOUT
;
761 // Fill in the write10 command block
763 ZeroMem (&WriteCmd
, sizeof (USB_BOOT_WRITE10_CMD
));
765 WriteCmd
.OpCode
= USB_BOOT_WRITE10_OPCODE
;
766 WriteCmd
.Lun
= (UINT8
) (USB_BOOT_LUN (UsbMass
->Lun
));
767 WriteUnaligned32 ((UINT32
*) WriteCmd
.Lba
, SwapBytes32 (Lba
));
768 WriteUnaligned16 ((UINT16
*) WriteCmd
.TransferLen
, SwapBytes16 (Count
));
770 Status
= UsbBootExecCmdWithRetry (
773 sizeof (USB_BOOT_WRITE10_CMD
),
779 if (EFI_ERROR (Status
)) {
784 Buffer
+= Count
* BlockSize
;
792 Use the USB clear feature control transfer to clear the endpoint stall condition.
794 @param UsbIo The USB I/O Protocol instance
795 @param EndpointAddr The endpoint to clear stall for
797 @retval EFI_SUCCESS The endpoint stall condition is cleared.
798 @retval Others Failed to clear the endpoint stall condition.
802 UsbClearEndpointStall (
803 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
804 IN UINT8 EndpointAddr
807 EFI_USB_DEVICE_REQUEST Request
;
812 Request
.RequestType
= 0x02;
813 Request
.Request
= USB_REQ_CLEAR_FEATURE
;
814 Request
.Value
= USB_FEATURE_ENDPOINT_HALT
;
815 Request
.Index
= EndpointAddr
;
817 Timeout
= USB_BOOT_GENERAL_CMD_TIMEOUT
/ USB_MASS_1_MILLISECOND
;
819 Status
= UsbIo
->UsbControlTransfer (