// -------------------------------------------------------------------- // Copyright (c) 2007 by Terasic Technologies Inc. // -------------------------------------------------------------------- // // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------- // // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: support@terasic.com // // -------------------------------------------------------------------- // Author: Richard Chang #ifndef USB_DISK_TRANSPORT_H_ #define USB_DISK_TRANSPORT_H_ // refer: usbmass-ufi10.pdf #include "isp1761_transport.h" #define BOT_packed __attribute__ ((packed,aligned(1))) #define BOT_CBW_SIGNATURE 0x43425355 #define BOT_CSW_SIGNATURE 0x53425355 // Status typedef enum{ BOT_COMMAND_PASS=0x00, BOT_COMMAND_FAILED=0x01, BOT_PHASE_ERROR=0x02, }BOT_RETURN_CODE; // Bulk-only Wrapper typedef struct{ alt_u32 dCBWSignature; alt_u32 dCBWTag; alt_u32 dCBWDataTransferLength; alt_u8 bmCBWFlags; alt_u8 bCBWLUN:4; alt_u8 Reserved0:4; alt_u8 bCBWCBLength:5; alt_u8 Reserved1:3; alt_u8 CBWCB[16]; }BOT_packed BOT_CBW; typedef struct{ alt_u32 dCSWSignature; alt_u32 dCSWTag; alt_u32 dCSWDataResidue; alt_u8 bCSWStatus; }BOT_packed BOT_CSW; #define MAX_LUN_NUM 16 // mass-storage Bulk-Only Device typedef struct{ // bulk-in alt_u8 BulkInEp; alt_u8 BulkInDataToggle; //alt_u16 BulkInMaxPacketSize; // bulk-out alt_u8 BulkOutEp; alt_u8 BulkOutDataToggle; //alt_u16 BulkOutMaxPacketSize; // Capability alt_u8 LUN; struct{ alt_u32 NumOfBlock; alt_u32 BlockSize; }szLunCap[MAX_LUN_NUM]; // USB_DEVICE UsbDevice; }USBDISK_DRIVER; ///////////////////////////////////////////// // SCSI ///////////////////////////////////// ///////////////////////////////////////////// #define SCSI_INQUERY 0x12 #define SCSI_READ_FORMAT_CAP 0x23 #define SCSI_REQUEST_SENSE 0x03 #define SCSI_READ_CAP 0x25 #define SCSI_MODE_SENSE 0x1A #define SCSI_READ10 0x28 #define SCSI_READ12 0xA8 //========== 0x12 (inquery) ============================= typedef struct{ alt_u8 OP; alt_u8 EVPD:1; alt_u8 Reserved0:4; alt_u8 LogicalUnitNumber:3; alt_u8 PageCode; alt_u8 Reserved1; alt_u8 AllocationLendth; alt_u8 Reserved2[9]; }BOT_packed SCSI_INQUERY_CDB; //CDB: Command Description Block typedef struct{ // byte 1 alt_u8 PeripheralDeviceType:5; alt_u8 Reserved0:3; // byte 2 alt_u8 Reserved1:7; alt_u8 RMB:1; // byte 3 alt_u8 ANSIApprovedVersion:3; //00 alt_u8 ECMAVersion:3; alt_u8 ISOVersion:2; // byte 4 alt_u8 ResponseDataFormat:4; alt_u8 Reserved2:4; // byte 5 alt_u8 AdditionalLength; // byte 6 alt_u8 Reserved3[3]; // byte 9 alt_u8 VerdorInformation[8]; alt_u8 ProductInformation[16]; alt_u8 ProductRevisionLevel[4]; }BOT_packed SCSI_INQUERY_RESULT; typedef enum{ SCSI_DIRECT_ACCESS_DEVICE = 0, SCSI_SEQUENTAIL_ACCESS_DEVICE, SCSI_PRINTER_DEVICE, SCSI_PROCESSOR_DEVICE, SCSI_WRITE_ONCE_DEVICE, SCSI_CDROM_DEVICE, SCSI_SCANNER, SCSI_OPTICAL_MEMORY_DEVICE, SCSI_MEDIUM_CHANGER, SCSI_COMMMUNICATIONS_DEVICE /* more... */ }SCSI_PHERIPHERAL_DEVICE_TYPE; //========= 0x23 (Read Format Capacities) ============================== typedef struct{ alt_u8 OP; alt_u8 Reserved0:5; alt_u8 LogicalUnitNumber:3; alt_u8 Reserved1[5]; alt_u8 AllocationLendth_MSB; alt_u8 AllocationLendth_LSB; // alt_u8 Reserved2[3]; alt_u8 Reserved2[1]; }BOT_packed SCSI_READ_FORMAT_CAP_CDB; typedef struct{ alt_u8 Reserved[3]; alt_u8 CapListLength; }BOT_packed SCSI_CAP_LIST_HEADER; typedef struct{ alt_u8 NumberOfBlocks[4]; // first byte is MSB alt_u8 DescriptorCode:2; // see CAP_DESCRIPTOR_CODE alt_u8 Reserved:6; alt_u8 BlockLength[3]; // first bytes is MSB }BOT_packed SCSI_CUR_MAX_CAP_DESCRIPTOR; typedef enum{ CAP_UNFORMATTED_MEDIA = 0x01, CAP_FORMATTED_MEDIA = 0x02, CAP_NO_CARTRIGE = 0x03, }CAP_DESCRIPTOR_CODE; typedef struct{ alt_u8 NumberOfBlocks[4]; // first byte is MSB alt_u8 Reserved; alt_u8 BlockLength[3]; // first bytes is MSB }BOT_packed SCSI_FORMATTABLE_CAP_DESCRIPTOR; typedef struct{ SCSI_CAP_LIST_HEADER CapListHeader; SCSI_CUR_MAX_CAP_DESCRIPTOR CurMaxCapHeader; SCSI_FORMATTABLE_CAP_DESCRIPTOR FormattableCapDescriptr[0]; }BOT_packed SCSI_CAP_LIST; //========= 0x03 (Request Sense) ============================== typedef struct{ alt_u8 OP; alt_u8 Reserved0:5; alt_u8 LogicalUnitNumber:3; alt_u8 Reserved1[2]; alt_u8 AllocationLength; alt_u8 Reserved2[7]; }BOT_packed SCSI_REQUEST_SENSE_CDB; typedef struct{ // byte 1 alt_u8 ErrorCode:7; alt_u8 Valid:1; // byte 2 alt_u8 Reserved0; // byte 3 alt_u8 SenseKey:5; // refer to SCSI_SNESE_KEY alt_u8 Reserve1:3; // byte 4 alt_u8 Information[4]; // first byte is MSB alt_u8 AdditionalSenseLength; // n-7 alt_u8 Reserve2[4]; alt_u8 AdditionalSenseCode; alt_u8 AdditionalSenseCodeQualifer; alt_u8 Reserved3; alt_u8 Reserved4[3]; }BOT_packed SCSI_REQUEST_SENSE_DATA; typedef enum{ KEY_NO_SENSE=0x00, KEY_RECOVERRED_ERROR=0x01, KEY_NOT_READY=0x02, KEY_HARDWARE_ERROR=0x04, KEY_ILLEAL_REQUEST=0x05, KEY_UNIT_ATTENTION=0x06, KEY_ABORT_COMMAND=0x0B, KEY_RESERVED=0x0C, KEY_VOLUME_OVERLOW=0x0D, KEY_MISCOMPARE=0x0E, KEY_RESERVED1=0x0F, }SCSI_SNESE_KEY; //========= 0x25 (READ CAPACITY) ============================== typedef struct{ alt_u8 OP; alt_u8 RelAdr:1; // fixed to 0 alt_u8 Reserved0:4; alt_u8 LogicUnitNumber:3; alt_u8 LogicalBlockAddress[4]; // first byte is MSB, fixed to 0 alt_u8 Reserved1[2]; alt_u8 PMI:1; // fixed to 0 alt_u8 Reserved2:7; alt_u8 Reserved3[1]; //??? alt_u8 Reserved3[3]; }BOT_packed SCSI_READ_CAP_CDB; typedef struct{ alt_u8 LastLogicalBlockAddress[4]; alt_u8 BlockLengthInBytes[4]; }BOT_packed SCSI_READ_CAP_RESULT; //========= 0x28 (READ_10), ============================== typedef struct{ alt_u8 OP; alt_u8 RelAdr:1; // zero alt_u8 Reserved0:2; alt_u8 FUA:1; // zero alt_u8 DPO:1; // zero alt_u8 LogicalUnitNumber:3; alt_u8 LogicalBlockAddress[4]; // first byte is MSB alt_u8 Reserved1; alt_u8 TransferLength_MSB; alt_u8 TransferLength_LSB; alt_u8 Reserved2[1]; //?? alt_u8 Reserved2[3]; }BOT_packed SCSI_READ10_CDB; //========= 0xA8 (READ_12), ============================== typedef struct{ alt_u8 OP; alt_u8 RelAdr:1; alt_u8 Reserved0:2; alt_u8 FUA:1; alt_u8 DPO:1; alt_u8 LogicalUnitNumber:3; alt_u8 LogicalBlockAddress[4]; // first byte is MSB alt_u8 TransferLength[4]; // first byte is MSB alt_u8 Reserved1[2]; }BOT_packed SCSI_READ12_CDB; //============ 0x1A (Mode Sense) =========================== typedef struct{ // byte 1 alt_u8 OP; // byte 2 alt_u8 Reserved0:4; alt_u8 DBD:1; alt_u8 Reserved1:3; // refer to enum type SCSI_MODE_SENSE_TYPE // byte 3 alt_u8 PageControl:2; alt_u8 PageCode:2; // byte 4 alt_u8 Reserved2; // byte 5 alt_u8 AllocationLendth; alt_u8 control; }BOT_packed SCSI_MODE_SENSE_CDB; typedef enum{ MODE_CURRENT_VALUE = 0x00, MODE_CHANGEABLE_VALUE = 0x01, MODE_DEFAULT_VALUE = 0x02, MODE_SAVED_VALUE = 0x03, }SCSI_MODE_SENSE_TYPE; /* typedef enum{ PAGECODE_ELEMENT_ADDRESS_ASSIGNMENT = 24, }SCSI_PAGECODE; */ //======================================= // Export API bool BOT_Inquery(USBDISK_DRIVER *pUsbDisk, SCSI_INQUERY_RESULT *pInqueryResult); bool BOT_ReadFormatCap(USBDISK_DRIVER *pUsbDisk, SCSI_CAP_LIST *pCapList, alt_u16 ReadLen); bool BOT_RequestSense(USBDISK_DRIVER *pUsbDisk, SCSI_REQUEST_SENSE_DATA *pRequestSenseData); bool BOT_ReadCap(USBDISK_DRIVER *pUsbDisk, SCSI_READ_CAP_RESULT *pResult); bool BOT_Read10(USBDISK_DRIVER *pUsbDisk, alt_u8 LogicalUnitNumber, alt_u32 LogicalBlockAddr, alt_u16 TransferLength, alt_u8 *pBuf, alt_u16 BufLen); // Export API for debug alt_u32 Array2Value(alt_u8 *pData, alt_u8 DataLen); void BOT_ExplainInqueryResult(SCSI_INQUERY_RESULT *pResult, alt_u16 Len); void BOT_ExplainFormatCapResult(SCSI_CAP_LIST *pResult, alt_u16 Len); void BOT_ExplainRequestSense(SCSI_REQUEST_SENSE_DATA *pRequestSenseData); void BOT_ExplainCapResult(SCSI_READ_CAP_RESULT *pResult); void BOT_Raw(alt_u8 *pData, alt_u16 DataLen); #endif /*USB_DISK_TRANSPORT_H_*/