Fixed unexpected timeout in Usb MassStorage Driver.
Fixed unexpected timeout in Uhci/Ehci driver. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4038 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -73,8 +73,8 @@ enum {
|
||||
USB_MASS_STORE_CBI1 = 0x01, // CBI protocol without command completion interrupt
|
||||
USB_MASS_STORE_BOT = 0x50, // Bulk-Only Transport
|
||||
|
||||
USB_MASS_STALL_1_MS = 1000,
|
||||
USB_MASS_STALL_1_S = 1000 * USB_MASS_STALL_1_MS,
|
||||
USB_MASS_1_MILLISECOND = 1000,
|
||||
USB_MASS_1_SECOND = 1000 * USB_MASS_1_MILLISECOND,
|
||||
|
||||
USB_MASS_CMD_SUCCESS = 0,
|
||||
USB_MASS_CMD_FAIL,
|
||||
|
@@ -935,7 +935,7 @@ UsbClearEndpointStall (
|
||||
Request.Value = USB_FEATURE_ENDPOINT_HALT;
|
||||
Request.Index = EndpointAddr;
|
||||
Request.Length = 0;
|
||||
Timeout = USB_BOOT_GENERAL_CMD_TIMEOUT / USB_MASS_STALL_1_MS;
|
||||
Timeout = USB_BOOT_GENERAL_CMD_TIMEOUT / USB_MASS_1_MILLISECOND;
|
||||
|
||||
Status = UsbIo->UsbControlTransfer (
|
||||
UsbIo,
|
||||
|
@@ -31,14 +31,13 @@ enum {
|
||||
// The opcodes of various usb boot commands:
|
||||
// INQUIRY/REQUEST_SENSE are "No Timeout Commands" as specified
|
||||
// by MMC command set. Others are "Group 1 Timeout Commands". That
|
||||
// is they should be retried if driver is ready.
|
||||
// We can't use the Peripheral Device Type in Inquiry data to
|
||||
// is they should be retried if driver is ready.
|
||||
// We can't use the Peripheral Device Type in Inquiry data to
|
||||
// determine the timeout used. For example, both floppy and flash
|
||||
// are likely set their PDT to 0, or Direct Access Device.
|
||||
//
|
||||
USB_BOOT_INQUIRY_OPCODE = 0x12,
|
||||
USB_BOOT_REQUEST_SENSE_OPCODE = 0x03,
|
||||
|
||||
USB_BOOT_MODE_SENSE10_OPCODE = 0x5A,
|
||||
USB_BOOT_READ_CAPACITY_OPCODE = 0x25,
|
||||
USB_BOOT_TEST_UNIT_READY_OPCODE = 0x00,
|
||||
@@ -70,45 +69,45 @@ enum {
|
||||
USB_BOOT_ASC_MEDIA_CHANGE = 0x28,
|
||||
|
||||
//
|
||||
// Other parameters
|
||||
// Supported PDT codes, or Peripheral Device Type
|
||||
//
|
||||
USB_BOOT_IO_BLOCKS = 64,
|
||||
USB_PDT_DIRECT_ACCESS = 0x00, // Direct access device
|
||||
USB_PDT_CDROM = 0x05, // CDROM
|
||||
USB_PDT_OPTICAL = 0x07, // Non-CD optical disks
|
||||
USB_PDT_SIMPLE_DIRECT = 0x0E, // Simplified direct access device
|
||||
|
||||
//
|
||||
// Other parameters, Max carried size is 512B * 128 = 64KB
|
||||
//
|
||||
USB_BOOT_IO_BLOCKS = 128,
|
||||
|
||||
//
|
||||
// Boot Retry times
|
||||
// Retry mass command times, set by experience
|
||||
//
|
||||
USB_BOOT_COMMAND_RETRY = 5,
|
||||
USB_BOOT_WAIT_RETRY = 5,
|
||||
USB_BOOT_INIT_MEDIA_RETRY = 5,
|
||||
|
||||
//
|
||||
// Boot Stall time
|
||||
// Wait for unit ready command, set by experience
|
||||
//
|
||||
USB_BOOT_UNIT_READY_STALL = 50 * USB_MASS_STALL_1_MS,
|
||||
USB_BOOT_RETRY_UNIT_READY_STALL = 500 * USB_MASS_1_MILLISECOND,
|
||||
|
||||
//
|
||||
// Boot Transfer timeout
|
||||
// Mass command timeout, refers to specification[USB20-9.2.6.1]
|
||||
//
|
||||
// USB2.0 Spec define the up-limit timeout 5s for all command. USB floppy,
|
||||
// USB CD-Rom and iPod devices are much slower than USB key when reponse
|
||||
// most of commands, So we set 5s as timeout here.
|
||||
//
|
||||
//
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT = 5 * USB_MASS_STALL_1_S,
|
||||
|
||||
//
|
||||
// Supported PDT codes, or Peripheral Device Type
|
||||
//
|
||||
USB_PDT_DIRECT_ACCESS = 0x00, // Direct access device
|
||||
USB_PDT_CDROM = 0x05, // CDROM
|
||||
USB_PDT_OPTICAL = 0x07, // Non-CD optical disks
|
||||
USB_PDT_SIMPLE_DIRECT = 0x0E // Simplified direct access device
|
||||
USB_BOOT_GENERAL_CMD_TIMEOUT = 5 * USB_MASS_1_SECOND,
|
||||
};
|
||||
|
||||
//
|
||||
// The required commands are INQUIRY, READ CAPACITY, TEST UNIT READY,
|
||||
// READ10, WRITE10, and REQUEST SENSE. The BLOCK_IO protocol uses LBA
|
||||
// so it isn't necessary to issue MODE SENSE / READ FORMAT CAPACITY
|
||||
// command to retrieve the disk gemotrics.
|
||||
// command to retrieve the disk gemotrics.
|
||||
//
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
@@ -221,7 +220,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
UINT8 ModeDataLen;
|
||||
UINT8 MediumType;
|
||||
UINT8 MediumType;
|
||||
UINT8 DevicePara;
|
||||
UINT8 BlkDesLen;
|
||||
} USB_SCSI_MODE_SENSE6_PARA_HEADER;
|
||||
@@ -245,7 +244,7 @@ typedef struct {
|
||||
//
|
||||
#define USB_BOOT_SWAP32(Data32) \
|
||||
((((Data32) & 0x000000ff) << 24) | (((Data32) & 0xff000000) >> 24) | \
|
||||
(((Data32) & 0x0000ff00) << 8) | (((Data32) & 0x00ff0000) >> 8))
|
||||
(((Data32) & 0x0000ff00) << 8) | (((Data32) & 0x00ff0000) >> 8))
|
||||
|
||||
#define USB_BOOT_SWAP16(Data16) \
|
||||
((((Data16) & 0x00ff) << 8) | (((Data16) & 0xff00) >> 8))
|
||||
|
@@ -191,7 +191,7 @@ UsbBotSendCommand (
|
||||
|
||||
Result = 0;
|
||||
DataLen = sizeof (USB_BOT_CBW);
|
||||
Timeout = USB_BOT_CBW_TIMEOUT / USB_MASS_STALL_1_MS;
|
||||
Timeout = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;
|
||||
|
||||
//
|
||||
// Use the UsbIo to send the command to the device. The default
|
||||
@@ -266,7 +266,7 @@ UsbBotDataTransfer (
|
||||
}
|
||||
|
||||
Result = 0;
|
||||
Timeout = Timeout / USB_MASS_STALL_1_MS;
|
||||
Timeout = Timeout / USB_MASS_1_MILLISECOND;
|
||||
|
||||
Status = UsbBot->UsbIo->UsbBulkTransfer (
|
||||
UsbBot->UsbIo,
|
||||
@@ -323,14 +323,14 @@ UsbBotGetStatus (
|
||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||
UINT32 Index;
|
||||
UINTN Timeout;
|
||||
|
||||
|
||||
*CmdStatus = USB_BOT_COMMAND_ERROR;
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
Endpoint = UsbBot->BulkInEndpoint->EndpointAddress;
|
||||
UsbIo = UsbBot->UsbIo;
|
||||
Timeout = USB_BOT_CSW_TIMEOUT / USB_MASS_STALL_1_MS;
|
||||
Timeout = USB_BOT_RECV_CSW_TIMEOUT / USB_MASS_1_MILLISECOND;
|
||||
|
||||
for (Index = 0; Index < USB_BOT_GET_STATUS_RETRY; Index++) {
|
||||
for (Index = 0; Index < USB_BOT_RECV_CSW_RETRY; Index++) {
|
||||
//
|
||||
// Attemp to the read CSW from bulk in endpoint
|
||||
//
|
||||
@@ -499,7 +499,7 @@ UsbBotResetDevice (
|
||||
Request.Value = 0;
|
||||
Request.Index = UsbBot->Interface.InterfaceNumber;
|
||||
Request.Length = 0;
|
||||
Timeout = USB_BOT_RESET_TIMEOUT / USB_MASS_STALL_1_MS;
|
||||
Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
|
||||
|
||||
Status = UsbBot->UsbIo->UsbControlTransfer (
|
||||
UsbBot->UsbIo,
|
||||
@@ -521,7 +521,7 @@ UsbBotResetDevice (
|
||||
// complete. We can use this to sync the device and host. For
|
||||
// now just stall 100ms to wait the device.
|
||||
//
|
||||
gBS->Stall (USB_BOT_RESET_STALL);
|
||||
gBS->Stall (USB_BOT_RESET_DEVICE_STALL);
|
||||
|
||||
//
|
||||
// Clear the Bulk-In and Bulk-Out stall condition.
|
||||
|
@@ -46,21 +46,21 @@ enum {
|
||||
USB_BOT_COMMAND_ERROR = 0x02, // Phase error, need to reset the device
|
||||
|
||||
//
|
||||
// Usb Bot retry times
|
||||
// Usb Bot retry to get CSW, refers to specification[BOT10-5.3, it says 2 times]
|
||||
//
|
||||
USB_BOT_GET_STATUS_RETRY = 3,
|
||||
USB_BOT_RECV_CSW_RETRY = 3,
|
||||
|
||||
//
|
||||
// Usb Bot stall time
|
||||
// Usb Bot wait device reset complete, set by experience
|
||||
//
|
||||
USB_BOT_RESET_DEVICE_STALL = 100 * USB_MASS_1_MILLISECOND,
|
||||
|
||||
//
|
||||
USB_BOT_RESET_STALL = 100 * USB_MASS_STALL_1_MS,
|
||||
|
||||
// Usb Bot transport timeout, set by experience
|
||||
//
|
||||
// Usb Bot transfer timeout
|
||||
//
|
||||
USB_BOT_CBW_TIMEOUT = 1 * USB_MASS_STALL_1_S,
|
||||
USB_BOT_CSW_TIMEOUT = 1 * USB_MASS_STALL_1_S,
|
||||
USB_BOT_RESET_TIMEOUT = 3 * USB_MASS_STALL_1_S
|
||||
USB_BOT_SEND_CBW_TIMEOUT = 3 * USB_MASS_1_SECOND,
|
||||
USB_BOT_RECV_CSW_TIMEOUT = 3 * USB_MASS_1_SECOND,
|
||||
USB_BOT_RESET_DEVICE_TIMEOUT = 3 * USB_MASS_1_SECOND,
|
||||
};
|
||||
|
||||
//
|
||||
|
@@ -194,7 +194,7 @@ UsbCbiSendCommand (
|
||||
Request.Length = CmdLen;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Timeout = Timeout / USB_MASS_STALL_1_MS;
|
||||
Timeout = Timeout / USB_MASS_1_MILLISECOND;
|
||||
|
||||
for (Retry = 0; Retry < USB_CBI_MAX_RETRY; Retry++) {
|
||||
//
|
||||
@@ -281,7 +281,7 @@ UsbCbiDataTransfer (
|
||||
Remain = *TransLen;
|
||||
Retry = 0;
|
||||
Status = EFI_SUCCESS;
|
||||
Timeout = Timeout / USB_MASS_STALL_1_MS;
|
||||
Timeout = Timeout / USB_MASS_1_MILLISECOND;
|
||||
|
||||
//
|
||||
// Transfer the data, if the device returns NAK, retry it.
|
||||
@@ -376,7 +376,7 @@ UsbCbiGetStatus (
|
||||
|
||||
Endpoint = UsbCbi->InterruptEndpoint->EndpointAddress;
|
||||
Status = EFI_SUCCESS;
|
||||
Timeout = Timeout / USB_MASS_STALL_1_MS;
|
||||
Timeout = Timeout / USB_MASS_1_MILLISECOND;
|
||||
|
||||
//
|
||||
// Attemp to the read the result from interrupt endpoint
|
||||
@@ -555,7 +555,7 @@ UsbCbiResetDevice (
|
||||
|
||||
ResetCmd[0] = 0x1D;
|
||||
ResetCmd[1] = 0x04;
|
||||
Timeout = USB_CBI_RESET_TIMEOUT / USB_MASS_STALL_1_MS;
|
||||
Timeout = USB_CBI_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
|
||||
|
||||
//
|
||||
// Send the command to the device. Don't use UsbCbiExecCommand here.
|
||||
@@ -570,7 +570,7 @@ UsbCbiResetDevice (
|
||||
// 50ms to wait it complete
|
||||
//
|
||||
UsbCbiGetStatus (UsbCbi, Timeout, &Result);
|
||||
gBS->Stall (50 * 1000);
|
||||
gBS->Stall (USB_CBI_RESET_DEVICE_STALL);
|
||||
|
||||
//
|
||||
// Clear the Bulk-In and Bulk-Out stall condition and
|
||||
|
@@ -30,14 +30,19 @@ enum {
|
||||
USB_CBI_RESET_CMD_LEN = 12,
|
||||
|
||||
//
|
||||
// Usb CBI retry times
|
||||
// Usb Cbi retry C/B/I transport times, set by experience
|
||||
//
|
||||
USB_CBI_MAX_RETRY = 3,
|
||||
|
||||
//
|
||||
// Usb Cbi transfer timeout
|
||||
// Usb Cbi wait device reset complete, set by experience
|
||||
//
|
||||
USB_CBI_RESET_DEVICE_STALL = 50 * USB_MASS_1_MILLISECOND,
|
||||
|
||||
//
|
||||
USB_CBI_RESET_TIMEOUT = 1 * USB_MASS_STALL_1_S
|
||||
// Usb Cbi transport timeout, set by experience
|
||||
//
|
||||
USB_CBI_RESET_DEVICE_TIMEOUT = 1 * USB_MASS_1_SECOND,
|
||||
};
|
||||
|
||||
//
|
||||
|
@@ -91,7 +91,7 @@ UsbMassInitMedia (
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
for (Index = 0; Index < USB_BOOT_WAIT_RETRY; Index++) {
|
||||
for (Index = 0; Index < USB_BOOT_INIT_MEDIA_RETRY; Index++) {
|
||||
|
||||
Status = UsbBootGetParams (UsbMass);
|
||||
if ((Status != EFI_MEDIA_CHANGED)
|
||||
@@ -102,7 +102,7 @@ UsbMassInitMedia (
|
||||
|
||||
Status = UsbBootIsUnitReady (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->Stall (USB_BOOT_UNIT_READY_STALL * (Index + 1));
|
||||
gBS->Stall (USB_BOOT_RETRY_UNIT_READY_STALL * (Index + 1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -128,9 +128,17 @@ UsbMassReset (
|
||||
)
|
||||
{
|
||||
USB_MASS_DEVICE *UsbMass;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
|
||||
|
||||
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
|
||||
return UsbMass->Transport->Reset (UsbMass->Context, ExtendedVerification);
|
||||
Status = UsbMass->Transport->Reset (UsbMass->Context, ExtendedVerification);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,8 +173,10 @@ UsbMassReadBlocks (
|
||||
USB_MASS_DEVICE *UsbMass;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
UINTN TotalBlock;
|
||||
|
||||
|
||||
OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
|
||||
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
|
||||
Media = &UsbMass->BlockIoMedia;
|
||||
|
||||
@@ -174,40 +184,47 @@ UsbMassReadBlocks (
|
||||
// First, validate the parameters
|
||||
//
|
||||
if ((Buffer == NULL) || (BufferSize == 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If it is a remoable media, such as CD-Rom or Usb-Floppy,
|
||||
// if, need to detect the media before each rw, while Usb-Flash
|
||||
// needn't. However, it's hard to identify Usb-Floppy between
|
||||
// Usb-Flash by now, so detect media every time.
|
||||
//
|
||||
Status = UsbBootDetectMedia (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootDetectMedia (%r)\n", Status));
|
||||
return Status;
|
||||
// If it is a removable media, such as CD-Rom or Usb-Floppy,
|
||||
// need to detect the media before each rw. While some of
|
||||
// Usb-Flash is marked as removable media.
|
||||
//
|
||||
//
|
||||
if (Media->RemovableMedia == TRUE) {
|
||||
Status = UsbBootDetectMedia (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootDetectMedia (%r)\n", Status));
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Make sure BlockSize and LBA is consistent with BufferSize
|
||||
//
|
||||
if ((BufferSize % Media->BlockSize) != 0) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
TotalBlock = BufferSize / Media->BlockSize;
|
||||
|
||||
if (Lba + TotalBlock - 1 > Media->LastBlock) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootReadBlocks (%r) -> Reset\n", Status));
|
||||
UsbMassReset (This, TRUE);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -243,8 +260,10 @@ UsbMassWriteBlocks (
|
||||
USB_MASS_DEVICE *UsbMass;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
UINTN TotalBlock;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
|
||||
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
|
||||
Media = &UsbMass->BlockIoMedia;
|
||||
|
||||
@@ -252,34 +271,39 @@ UsbMassWriteBlocks (
|
||||
// First, validate the parameters
|
||||
//
|
||||
if ((Buffer == NULL) || (BufferSize == 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If it is a remoable media, such as CD-Rom or Usb-Floppy,
|
||||
// if, need to detect the media before each rw, while Usb-Flash
|
||||
// needn't. However, it's hard to identify Usb-Floppy between
|
||||
// Usb-Flash by now, so detect media every time.
|
||||
//
|
||||
Status = UsbBootDetectMedia (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootDetectMedia (%r)\n", Status));
|
||||
return Status;
|
||||
// If it is a removable media, such as CD-Rom or Usb-Floppy,
|
||||
// need to detect the media before each rw. While some of
|
||||
// Usb-Flash is marked as removable media.
|
||||
//
|
||||
//
|
||||
if (Media->RemovableMedia == TRUE) {
|
||||
Status = UsbBootDetectMedia (UsbMass);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootDetectMedia (%r)\n", Status));
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Make sure BlockSize and LBA is consistent with BufferSize
|
||||
//
|
||||
if ((BufferSize % Media->BlockSize) != 0) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
TotalBlock = BufferSize / Media->BlockSize;
|
||||
|
||||
if (Lba + TotalBlock - 1 > Media->LastBlock) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
Status = EFI_BAD_BUFFER_SIZE;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Try to write the data even the device is marked as ReadOnly,
|
||||
// and clear the status should the write succeed.
|
||||
@@ -289,7 +313,9 @@ UsbMassWriteBlocks (
|
||||
DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootWriteBlocks (%r) -> Reset\n", Status));
|
||||
UsbMassReset (This, TRUE);
|
||||
}
|
||||
|
||||
|
||||
ON_EXIT:
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,13 @@ typedef struct _USB_MASS_DEVICE USB_MASS_DEVICE;
|
||||
#include "UsbMassBoot.h"
|
||||
|
||||
enum {
|
||||
USB_MASS_SIGNATURE= EFI_SIGNATURE_32 ('U', 's', 'b', 'K')
|
||||
//
|
||||
// MassStorage raises TPL to TPL_NOTIFY to serialize all its operations
|
||||
// to protect shared data structures.
|
||||
//
|
||||
USB_MASS_TPL = TPL_NOTIFY,
|
||||
|
||||
USB_MASS_SIGNATURE = EFI_SIGNATURE_32 ('U', 's', 'b', 'M'),
|
||||
};
|
||||
|
||||
struct _USB_MASS_DEVICE {
|
||||
|
Reference in New Issue
Block a user