1 /* 2 * Copyright (c) 2022, sakumisu 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef USB_MSC_H 7 #define USB_MSC_H 8 9 /* MSC Subclass Codes */ 10 #define MSC_SUBCLASS_RBC 0x01 /* Reduced block commands (e.g., flash devices) */ 11 #define MSC_SUBCLASS_SFF8020I_MMC2 0x02 /* SFF-8020i/MMC-2 (ATAPI) (e.g., C/DVD) */ 12 #define MSC_SUBCLASS_QIC157 0x03 /* QIC-157 (e.g., tape device) */ 13 #define MSC_SUBCLASS_UFI 0x04 /* e.g. floppy device */ 14 #define MSC_SUBCLASS_SFF8070I 0x05 /* SFF-8070i (e.g. floppy disk) */ 15 #define MSC_SUBCLASS_SCSI 0x06 /* SCSI transparent */ 16 17 /* MSC Protocol Codes */ 18 #define MSC_PROTOCOL_CBI_INT 0x00 /* CBI transport with command completion interrupt */ 19 #define MSC_PROTOCOL_CBI_NOINT 0x01 /* CBI transport without command completion interrupt */ 20 #define MSC_PROTOCOL_BULK_ONLY 0x50 /* Bulk only transport */ 21 22 /* MSC Request Codes */ 23 #define MSC_REQUEST_RESET 0xFF 24 #define MSC_REQUEST_GET_MAX_LUN 0xFE 25 26 /** MSC Command Block Wrapper (CBW) Signature */ 27 #define MSC_CBW_Signature 0x43425355 28 /** Bulk-only Command Status Wrapper (CSW) Signature */ 29 #define MSC_CSW_Signature 0x53425355 30 31 /** MSC Command Block Status Values */ 32 #define CSW_STATUS_CMD_PASSED 0x00 33 #define CSW_STATUS_CMD_FAILED 0x01 34 #define CSW_STATUS_PHASE_ERROR 0x02 35 36 #define MSC_MAX_CDB_LEN (16) /* Max length of SCSI Command Data Block */ 37 38 /** MSC Bulk-Only Command Block Wrapper (CBW) */ 39 struct CBW { 40 uint32_t dSignature; /* 'USBC' = 0x43425355 */ 41 uint32_t dTag; /* Depends on command id */ 42 uint32_t dDataLength; /* Number of bytes that host expects to transfer */ 43 uint8_t bmFlags; /* Bit 7: Direction=IN (other obsolete or reserved) */ 44 uint8_t bLUN; /* LUN (normally 0) */ 45 uint8_t bCBLength; /* len of cdb[] */ 46 uint8_t CB[MSC_MAX_CDB_LEN]; /* Command Data Block */ 47 } __PACKED; 48 49 #define USB_SIZEOF_MSC_CBW 31 50 51 /** MSC Bulk-Only Command Status Wrapper (CSW) */ 52 struct CSW { 53 uint32_t dSignature; /* 'USBS' = 0x53425355 */ 54 uint32_t dTag; /* Same tag as original command */ 55 uint32_t dDataResidue; /* Amount not transferred */ 56 uint8_t bStatus; /* Status of transfer */ 57 } __PACKED; 58 59 #define USB_SIZEOF_MSC_CSW 13 60 61 /*Length of template descriptor: 23 bytes*/ 62 #define MSC_DESCRIPTOR_LEN (9 + 7 + 7) 63 // clang-format off 64 #define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, wMaxPacketSize, str_idx) \ 65 /* Interface */ \ 66 0x09, /* bLength */ \ 67 USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ 68 bFirstInterface, /* bInterfaceNumber */ \ 69 0x00, /* bAlternateSetting */ \ 70 0x02, /* bNumEndpoints */ \ 71 USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \ 72 MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ \ 73 MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ \ 74 str_idx, /* iInterface */ \ 75 0x07, /* bLength */ \ 76 USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ 77 out_ep, /* bEndpointAddress */ \ 78 0x02, /* bmAttributes */ \ 79 WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ 80 0x00, /* bInterval */ \ 81 0x07, /* bLength */ \ 82 USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ 83 in_ep, /* bEndpointAddress */ \ 84 0x02, /* bmAttributes */ \ 85 WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ 86 0x00 /* bInterval */ 87 // clang-format on 88 89 #endif /* USB_MSC_H */ 90