在實現 USB 大容量存儲設備(BOT 協議)主機驅動時,需向設備下發 SCSI 透明命令集(UFI/SCSI Primary Commands)。本文定義四大核心命令的數據結構,作為後續 CBW(Command Block Wrapper)構建的基礎。所有結構採用 #pragma pack(1) 字節對齊,字段順序嚴格遵循 SCSI 標準。
typedef struct _INQUIRY_SPC {
UINT8 OperationCode; // 0x12
UINT8 Lun; // Logical Unit Number, 通常為 0
UINT8 PageCode; // 頁碼, 標準查詢為 0
UINT8 Reserved1; // 保留
UINT8 AllocationLen; // 分配長度, 常設 0x24 (36 bytes)
UINT8 Reserved[7]; // 保留
} INQUIRY_SPC, *PINQUIRY_SPC;
回數據包含:Peripheral Qualifier、Peripheral Device Type、Removable Bit、版本信息、Vendor/Product/Revision 字符串等。
typedef struct _READ_CAPACITY {
UINT8 OperationCode; // 0x25
UINT8 Reserved[15]; // 保留
} READ_CAPACITY;
返回 8 字節數據:LBA_3~0 (最大邏輯塊地址)、BlockLen_3~0 (塊大小,通常 512 bytes)。總容量 = (LBA+1) × BlockSize。
typedef struct _READ_10 {
UINT8 OperationCode; // 0x28
UINT8 Reserved1; // 保留 (DPO/FUA 等標誌位可擴展)
UINT8 LBA_3; // 邏輯塊地址 Byte 3 (MSB)
UINT8 LBA_2; // Byte 2
UINT8 LBA_1; // Byte 1
UINT8 LBA_0; // Byte 0 (LSB)
UINT8 Reserved2; // 保留
UINT8 XferLen_1; // 傳輸長度高字節 (塊數)
UINT8 XferLen_0; // 傳輸長度低字節
UINT8 Reserved3[4]; // 保留
} READ_10;
LBA 為大端序 32 位無符號整數;傳輸長度為大端序 16 位塊計數(0 表示 65536 塊)。
typedef struct _WRITE_10 {
UINT8 OperationCode; // 0x2A
UINT8 Reserved1; // 保留
UINT8 LBA_3; // 邏輯塊地址 Byte 3
UINT8 LBA_2; // Byte 2
UINT8 LBA_1; // Byte 1
UINT8 LBA_0; // Byte 0
UINT8 Reserved2; // 保留
UINT8 XferLen_1; // 傳輸長度高字節
UINT8 XferLen_0; // 傳輸長度低字節
UINT8 Reserved3[4]; // 保留
} WRITE_10;
結構佈局與 READ_10 完全一致,僅 OperationCode 不同。數據階段為主機 → 設備方向。
htonl/htons 轉換。Reserved 字段必須清零,設備端嚴格校驗。