Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Committer:
hudakz
Date:
Sun Jul 12 20:39:26 2020 +0000
Revision:
0:84353c479782
Child:
1:2263e77400e9
MAX3421E-based USB Host Shield Library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:84353c479782 1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
hudakz 0:84353c479782 2
hudakz 0:84353c479782 3 This program is free software; you can redistribute it and/or modify
hudakz 0:84353c479782 4 it under the terms of the GNU General Public License as published by
hudakz 0:84353c479782 5 the Free Software Foundation; either version 2 of the License, or
hudakz 0:84353c479782 6 (at your option) any later version.
hudakz 0:84353c479782 7
hudakz 0:84353c479782 8 This program is distributed in the hope that it will be useful,
hudakz 0:84353c479782 9 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:84353c479782 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:84353c479782 11 GNU General Public License for more details.
hudakz 0:84353c479782 12
hudakz 0:84353c479782 13 You should have received a copy of the GNU General Public License
hudakz 0:84353c479782 14 along with this program; if not, write to the Free Software
hudakz 0:84353c479782 15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
hudakz 0:84353c479782 16
hudakz 0:84353c479782 17 Contact information
hudakz 0:84353c479782 18 -------------------
hudakz 0:84353c479782 19
hudakz 0:84353c479782 20 Circuits At Home, LTD
hudakz 0:84353c479782 21 Web : http://www.circuitsathome.com
hudakz 0:84353c479782 22 e-mail : support@circuitsathome.com
hudakz 0:84353c479782 23 */
hudakz 0:84353c479782 24
hudakz 0:84353c479782 25 #if !defined(__MASSTORAGE_H__)
hudakz 0:84353c479782 26 #define __MASSTORAGE_H__
hudakz 0:84353c479782 27
hudakz 0:84353c479782 28 // Cruft removal, makes driver smaller, faster.
hudakz 0:84353c479782 29 #ifndef MS_WANT_PARSER
hudakz 0:84353c479782 30 #define MS_WANT_PARSER 0
hudakz 0:84353c479782 31 #endif
hudakz 0:84353c479782 32
hudakz 0:84353c479782 33 #include "Usb.h"
hudakz 0:84353c479782 34
hudakz 0:84353c479782 35 #define bmREQ_MASSOUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
hudakz 0:84353c479782 36 #define bmREQ_MASSIN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
hudakz 0:84353c479782 37
hudakz 0:84353c479782 38 // Mass Storage Subclass Constants
hudakz 0:84353c479782 39 #define MASS_SUBCLASS_SCSI_NOT_REPORTED 0x00 // De facto use
hudakz 0:84353c479782 40 #define MASS_SUBCLASS_RBC 0x01
hudakz 0:84353c479782 41 #define MASS_SUBCLASS_ATAPI 0x02 // MMC-5 (ATAPI)
hudakz 0:84353c479782 42 #define MASS_SUBCLASS_OBSOLETE1 0x03 // Was QIC-157
hudakz 0:84353c479782 43 #define MASS_SUBCLASS_UFI 0x04 // Specifies how to interface Floppy Disk Drives to USB
hudakz 0:84353c479782 44 #define MASS_SUBCLASS_OBSOLETE2 0x05 // Was SFF-8070i
hudakz 0:84353c479782 45 #define MASS_SUBCLASS_SCSI 0x06 // SCSI Transparent Command Set
hudakz 0:84353c479782 46 #define MASS_SUBCLASS_LSDFS 0x07 // Specifies how host has to negotiate access before trying SCSI
hudakz 0:84353c479782 47 #define MASS_SUBCLASS_IEEE1667 0x08
hudakz 0:84353c479782 48
hudakz 0:84353c479782 49 // Mass Storage Class Protocols
hudakz 0:84353c479782 50 #define MASS_PROTO_CBI 0x00 // CBI (with command completion interrupt)
hudakz 0:84353c479782 51 #define MASS_PROTO_CBI_NO_INT 0x01 // CBI (without command completion interrupt)
hudakz 0:84353c479782 52 #define MASS_PROTO_OBSOLETE 0x02
hudakz 0:84353c479782 53 #define MASS_PROTO_BBB 0x50 // Bulk Only Transport
hudakz 0:84353c479782 54 #define MASS_PROTO_UAS 0x62
hudakz 0:84353c479782 55
hudakz 0:84353c479782 56 // Request Codes
hudakz 0:84353c479782 57 #define MASS_REQ_ADSC 0x00
hudakz 0:84353c479782 58 #define MASS_REQ_GET 0xFC
hudakz 0:84353c479782 59 #define MASS_REQ_PUT 0xFD
hudakz 0:84353c479782 60 #define MASS_REQ_GET_MAX_LUN 0xFE
hudakz 0:84353c479782 61 #define MASS_REQ_BOMSR 0xFF // Bulk-Only Mass Storage Reset
hudakz 0:84353c479782 62
hudakz 0:84353c479782 63 #define MASS_CBW_SIGNATURE 0x43425355
hudakz 0:84353c479782 64 #define MASS_CSW_SIGNATURE 0x53425355
hudakz 0:84353c479782 65
hudakz 0:84353c479782 66 #define MASS_CMD_DIR_OUT 0 // (0 << 7)
hudakz 0:84353c479782 67 #define MASS_CMD_DIR_IN 0x80 //(1 << 7)
hudakz 0:84353c479782 68
hudakz 0:84353c479782 69 /*
hudakz 0:84353c479782 70 * Reference documents from T10 (http://www.t10.org)
hudakz 0:84353c479782 71 * SCSI Primary Commands - 3 (SPC-3)
hudakz 0:84353c479782 72 * SCSI Block Commands - 2 (SBC-2)
hudakz 0:84353c479782 73 * Multi-Media Commands - 5 (MMC-5)
hudakz 0:84353c479782 74 */
hudakz 0:84353c479782 75
hudakz 0:84353c479782 76 /* Group 1 commands (CDB's here are should all be 6-bytes) */
hudakz 0:84353c479782 77 #define SCSI_CMD_TEST_UNIT_READY 0x00
hudakz 0:84353c479782 78 #define SCSI_CMD_REQUEST_SENSE 0x03
hudakz 0:84353c479782 79 #define SCSI_CMD_FORMAT_UNIT 0x04
hudakz 0:84353c479782 80 #define SCSI_CMD_READ_6 0x08
hudakz 0:84353c479782 81 #define SCSI_CMD_WRITE_6 0x0A
hudakz 0:84353c479782 82 #define SCSI_CMD_INQUIRY 0x12
hudakz 0:84353c479782 83 #define SCSI_CMD_MODE_SELECT_6 0x15
hudakz 0:84353c479782 84 #define SCSI_CMD_MODE_SENSE_6 0x1A
hudakz 0:84353c479782 85 #define SCSI_CMD_START_STOP_UNIT 0x1B
hudakz 0:84353c479782 86 #define SCSI_CMD_PREVENT_REMOVAL 0x1E
hudakz 0:84353c479782 87 /* Group 2 Commands (CDB's here are 10-bytes) */
hudakz 0:84353c479782 88 #define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23
hudakz 0:84353c479782 89 #define SCSI_CMD_READ_CAPACITY_10 0x25
hudakz 0:84353c479782 90 #define SCSI_CMD_READ_10 0x28
hudakz 0:84353c479782 91 #define SCSI_CMD_WRITE_10 0x2A
hudakz 0:84353c479782 92 #define SCSI_CMD_SEEK_10 0x2B
hudakz 0:84353c479782 93 #define SCSI_CMD_ERASE_10 0x2C
hudakz 0:84353c479782 94 #define SCSI_CMD_WRITE_AND_VERIFY_10 0x2E
hudakz 0:84353c479782 95 #define SCSI_CMD_VERIFY_10 0x2F
hudakz 0:84353c479782 96 #define SCSI_CMD_SYNCHRONIZE_CACHE 0x35
hudakz 0:84353c479782 97 #define SCSI_CMD_WRITE_BUFFER 0x3B
hudakz 0:84353c479782 98 #define SCSI_CMD_READ_BUFFER 0x3C
hudakz 0:84353c479782 99 #define SCSI_CMD_READ_SUBCHANNEL 0x42
hudakz 0:84353c479782 100 #define SCSI_CMD_READ_TOC 0x43
hudakz 0:84353c479782 101 #define SCSI_CMD_READ_HEADER 0x44
hudakz 0:84353c479782 102 #define SCSI_CMD_PLAY_AUDIO_10 0x45
hudakz 0:84353c479782 103 #define SCSI_CMD_GET_CONFIGURATION 0x46
hudakz 0:84353c479782 104 #define SCSI_CMD_PLAY_AUDIO_MSF 0x47
hudakz 0:84353c479782 105 #define SCSI_CMD_PLAY_AUDIO_TI 0x48
hudakz 0:84353c479782 106 #define SCSI_CMD_PLAY_TRACK_REL_10 0x49
hudakz 0:84353c479782 107 #define SCSI_CMD_GET_EVENT_STATUS 0x4A
hudakz 0:84353c479782 108 #define SCSI_CMD_PAUSE_RESUME 0x4B
hudakz 0:84353c479782 109 #define SCSI_CMD_READ_DISC_INFORMATION 0x51
hudakz 0:84353c479782 110 #define SCSI_CMD_READ_TRACK_INFORMATION 0x52
hudakz 0:84353c479782 111 #define SCSI_CMD_RESERVE_TRACK 0x53
hudakz 0:84353c479782 112 #define SCSI_CMD_SEND_OPC_INFORMATION 0x54
hudakz 0:84353c479782 113 #define SCSI_CMD_MODE_SELECT_10 0x55
hudakz 0:84353c479782 114 #define SCSI_CMD_REPAIR_TRACK 0x58
hudakz 0:84353c479782 115 #define SCSI_CMD_MODE_SENSE_10 0x5A
hudakz 0:84353c479782 116 #define SCSI_CMD_CLOSE_TRACK_SESSION 0x5B
hudakz 0:84353c479782 117 #define SCSI_CMD_READ_BUFFER_CAPACITY 0x5C
hudakz 0:84353c479782 118 #define SCSI_CMD_SEND_CUE_SHEET 0x5D
hudakz 0:84353c479782 119 /* Group 5 Commands (CDB's here are 12-bytes) */
hudakz 0:84353c479782 120 #define SCSI_CMD_REPORT_LUNS 0xA0
hudakz 0:84353c479782 121 #define SCSI_CMD_BLANK 0xA1
hudakz 0:84353c479782 122 #define SCSI_CMD_SECURITY_PROTOCOL_IN 0xA2
hudakz 0:84353c479782 123 #define SCSI_CMD_SEND_KEY 0xA3
hudakz 0:84353c479782 124 #define SCSI_CMD_REPORT_KEY 0xA4
hudakz 0:84353c479782 125 #define SCSI_CMD_PLAY_AUDIO_12 0xA5
hudakz 0:84353c479782 126 #define SCSI_CMD_LOAD_UNLOAD 0xA6
hudakz 0:84353c479782 127 #define SCSI_CMD_SET_READ_AHEAD 0xA7
hudakz 0:84353c479782 128 #define SCSI_CMD_READ_12 0xA8
hudakz 0:84353c479782 129 #define SCSI_CMD_PLAY_TRACK_REL_12 0xA9
hudakz 0:84353c479782 130 #define SCSI_CMD_WRITE_12 0xAA
hudakz 0:84353c479782 131 #define SCSI_CMD_READ_MEDIA_SERIAL_12 0xAB
hudakz 0:84353c479782 132 #define SCSI_CMD_GET_PERFORMANCE 0xAC
hudakz 0:84353c479782 133 #define SCSI_CMD_READ_DVD_STRUCTURE 0xAD
hudakz 0:84353c479782 134 #define SCSI_CMD_SECURITY_PROTOCOL_OUT 0xB5
hudakz 0:84353c479782 135 #define SCSI_CMD_SET_STREAMING 0xB6
hudakz 0:84353c479782 136 #define SCSI_CMD_READ_MSF 0xB9
hudakz 0:84353c479782 137 #define SCSI_CMD_SET_SPEED 0xBB
hudakz 0:84353c479782 138 #define SCSI_CMD_MECHANISM_STATUS 0xBD
hudakz 0:84353c479782 139 #define SCSI_CMD_READ_CD 0xBE
hudakz 0:84353c479782 140 #define SCSI_CMD_SEND_DISC_STRUCTURE 0xBF
hudakz 0:84353c479782 141 /* Vendor-unique Commands, included for completeness */
hudakz 0:84353c479782 142 #define SCSI_CMD_CD_PLAYBACK_STATUS 0xC4 /* SONY unique */
hudakz 0:84353c479782 143 #define SCSI_CMD_PLAYBACK_CONTROL 0xC9 /* SONY unique */
hudakz 0:84353c479782 144 #define SCSI_CMD_READ_CDDA 0xD8 /* Vendor unique */
hudakz 0:84353c479782 145 #define SCSI_CMD_READ_CDXA 0xDB /* Vendor unique */
hudakz 0:84353c479782 146 #define SCSI_CMD_READ_ALL_SUBCODES 0xDF /* Vendor unique */
hudakz 0:84353c479782 147
hudakz 0:84353c479782 148 /* SCSI error codes */
hudakz 0:84353c479782 149 #define SCSI_S_NOT_READY 0x02
hudakz 0:84353c479782 150 #define SCSI_S_MEDIUM_ERROR 0x03
hudakz 0:84353c479782 151 #define SCSI_S_ILLEGAL_REQUEST 0x05
hudakz 0:84353c479782 152 #define SCSI_S_UNIT_ATTENTION 0x06
hudakz 0:84353c479782 153 #define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
hudakz 0:84353c479782 154 #define SCSI_ASC_MEDIA_CHANGED 0x28
hudakz 0:84353c479782 155 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
hudakz 0:84353c479782 156
hudakz 0:84353c479782 157 /* USB error codes */
hudakz 0:84353c479782 158 #define MASS_ERR_SUCCESS 0x00
hudakz 0:84353c479782 159 #define MASS_ERR_PHASE_ERROR 0x02
hudakz 0:84353c479782 160 #define MASS_ERR_UNIT_NOT_READY 0x03
hudakz 0:84353c479782 161 #define MASS_ERR_UNIT_BUSY 0x04
hudakz 0:84353c479782 162 #define MASS_ERR_STALL 0x05
hudakz 0:84353c479782 163 #define MASS_ERR_CMD_NOT_SUPPORTED 0x06
hudakz 0:84353c479782 164 #define MASS_ERR_INVALID_CSW 0x07
hudakz 0:84353c479782 165 #define MASS_ERR_NO_MEDIA 0x08
hudakz 0:84353c479782 166 #define MASS_ERR_BAD_LBA 0x09
hudakz 0:84353c479782 167 #define MASS_ERR_MEDIA_CHANGED 0x0A
hudakz 0:84353c479782 168 #define MASS_ERR_DEVICE_DISCONNECTED 0x11
hudakz 0:84353c479782 169 #define MASS_ERR_UNABLE_TO_RECOVER 0x12 // Reset recovery error
hudakz 0:84353c479782 170 #define MASS_ERR_INVALID_LUN 0x13
hudakz 0:84353c479782 171 #define MASS_ERR_WRITE_STALL 0x14
hudakz 0:84353c479782 172 #define MASS_ERR_READ_NAKS 0x15
hudakz 0:84353c479782 173 #define MASS_ERR_WRITE_NAKS 0x16
hudakz 0:84353c479782 174 #define MASS_ERR_WRITE_PROTECTED 0x17
hudakz 0:84353c479782 175 #define MASS_ERR_NOT_IMPLEMENTED 0xFD
hudakz 0:84353c479782 176 #define MASS_ERR_GENERAL_SCSI_ERROR 0xFE
hudakz 0:84353c479782 177 #define MASS_ERR_GENERAL_USB_ERROR 0xFF
hudakz 0:84353c479782 178 #define MASS_ERR_USER 0xA0 // For subclasses to define their own error codes
hudakz 0:84353c479782 179
hudakz 0:84353c479782 180 #define MASS_TRANS_FLG_CALLBACK 0x01 // Callback is involved
hudakz 0:84353c479782 181 #define MASS_TRANS_FLG_NO_STALL_CHECK 0x02 // STALL condition is not checked
hudakz 0:84353c479782 182 #define MASS_TRANS_FLG_NO_PHASE_CHECK 0x04 // PHASE_ERROR is not checked
hudakz 0:84353c479782 183
hudakz 0:84353c479782 184 #define MASS_MAX_ENDPOINTS 3
hudakz 0:84353c479782 185
hudakz 0:84353c479782 186 struct Capacity {
hudakz 0:84353c479782 187 uint8_t data[8];
hudakz 0:84353c479782 188 //uint32_t dwBlockAddress;
hudakz 0:84353c479782 189 //uint32_t dwBlockLength;
hudakz 0:84353c479782 190 } __attribute__((packed));
hudakz 0:84353c479782 191
hudakz 0:84353c479782 192 struct BASICCDB {
hudakz 0:84353c479782 193 uint8_t Opcode;
hudakz 0:84353c479782 194
hudakz 0:84353c479782 195 unsigned unused : 5;
hudakz 0:84353c479782 196 unsigned LUN : 3;
hudakz 0:84353c479782 197
hudakz 0:84353c479782 198 uint8_t info[12];
hudakz 0:84353c479782 199 } __attribute__((packed));
hudakz 0:84353c479782 200
hudakz 0:84353c479782 201 typedef BASICCDB BASICCDB_t;
hudakz 0:84353c479782 202
hudakz 0:84353c479782 203 struct CDB6 {
hudakz 0:84353c479782 204 uint8_t Opcode;
hudakz 0:84353c479782 205
hudakz 0:84353c479782 206 unsigned LBAMSB : 5;
hudakz 0:84353c479782 207 unsigned LUN : 3;
hudakz 0:84353c479782 208
hudakz 0:84353c479782 209 uint8_t LBAHB;
hudakz 0:84353c479782 210 uint8_t LBALB;
hudakz 0:84353c479782 211 uint8_t AllocationLength;
hudakz 0:84353c479782 212 uint8_t Control;
hudakz 0:84353c479782 213
hudakz 0:84353c479782 214 public:
hudakz 0:84353c479782 215
hudakz 0:84353c479782 216 CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
hudakz 0:84353c479782 217 Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
hudakz 0:84353c479782 218 AllocationLength(_AllocationLength), Control(_Control) {
hudakz 0:84353c479782 219 }
hudakz 0:84353c479782 220
hudakz 0:84353c479782 221 CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
hudakz 0:84353c479782 222 Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0),
hudakz 0:84353c479782 223 AllocationLength(_AllocationLength), Control(_Control) {
hudakz 0:84353c479782 224 }
hudakz 0:84353c479782 225 } __attribute__((packed));
hudakz 0:84353c479782 226
hudakz 0:84353c479782 227 typedef CDB6 CDB6_t;
hudakz 0:84353c479782 228
hudakz 0:84353c479782 229 struct CDB10 {
hudakz 0:84353c479782 230 uint8_t Opcode;
hudakz 0:84353c479782 231
hudakz 0:84353c479782 232 unsigned Service_Action : 5;
hudakz 0:84353c479782 233 unsigned LUN : 3;
hudakz 0:84353c479782 234
hudakz 0:84353c479782 235 uint8_t LBA_L_M_MB;
hudakz 0:84353c479782 236 uint8_t LBA_L_M_LB;
hudakz 0:84353c479782 237 uint8_t LBA_L_L_MB;
hudakz 0:84353c479782 238 uint8_t LBA_L_L_LB;
hudakz 0:84353c479782 239
hudakz 0:84353c479782 240 uint8_t Misc2;
hudakz 0:84353c479782 241
hudakz 0:84353c479782 242 uint8_t ALC_MB;
hudakz 0:84353c479782 243 uint8_t ALC_LB;
hudakz 0:84353c479782 244
hudakz 0:84353c479782 245 uint8_t Control;
hudakz 0:84353c479782 246 public:
hudakz 0:84353c479782 247
hudakz 0:84353c479782 248 CDB10(uint8_t _Opcode, uint8_t _LUN) :
hudakz 0:84353c479782 249 Opcode(_Opcode), Service_Action(0), LUN(_LUN),
hudakz 0:84353c479782 250 LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
hudakz 0:84353c479782 251 Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
hudakz 0:84353c479782 252 }
hudakz 0:84353c479782 253
hudakz 0:84353c479782 254 CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
hudakz 0:84353c479782 255 Opcode(_Opcode), Service_Action(0), LUN(_LUN),
hudakz 0:84353c479782 256 LBA_L_M_MB(BGRAB3(_LBA)), LBA_L_M_LB(BGRAB2(_LBA)), LBA_L_L_MB(BGRAB1(_LBA)), LBA_L_L_LB(BGRAB0(_LBA)),
hudakz 0:84353c479782 257 Misc2(0), ALC_MB(BGRAB1(xflen)), ALC_LB(BGRAB0(xflen)), Control(0) {
hudakz 0:84353c479782 258 }
hudakz 0:84353c479782 259 } __attribute__((packed));
hudakz 0:84353c479782 260
hudakz 0:84353c479782 261 typedef CDB10 CDB10_t;
hudakz 0:84353c479782 262
hudakz 0:84353c479782 263 struct CDB12 {
hudakz 0:84353c479782 264 uint8_t Opcode;
hudakz 0:84353c479782 265
hudakz 0:84353c479782 266 unsigned Service_Action : 5;
hudakz 0:84353c479782 267 unsigned Misc : 3;
hudakz 0:84353c479782 268
hudakz 0:84353c479782 269 uint8_t LBA_L_M_LB;
hudakz 0:84353c479782 270 uint8_t LBA_L_L_MB;
hudakz 0:84353c479782 271 uint8_t LBA_L_L_LB;
hudakz 0:84353c479782 272
hudakz 0:84353c479782 273 uint8_t ALC_M_LB;
hudakz 0:84353c479782 274 uint8_t ALC_L_MB;
hudakz 0:84353c479782 275 uint8_t ALC_L_LB;
hudakz 0:84353c479782 276 uint8_t Control;
hudakz 0:84353c479782 277 } __attribute__((packed));
hudakz 0:84353c479782 278
hudakz 0:84353c479782 279 typedef CDB12 CDB12_t;
hudakz 0:84353c479782 280
hudakz 0:84353c479782 281 struct CDB_LBA32_16 {
hudakz 0:84353c479782 282 uint8_t Opcode;
hudakz 0:84353c479782 283
hudakz 0:84353c479782 284 unsigned Service_Action : 5;
hudakz 0:84353c479782 285 unsigned Misc : 3;
hudakz 0:84353c479782 286
hudakz 0:84353c479782 287 uint8_t LBA_L_M_MB;
hudakz 0:84353c479782 288 uint8_t LBA_L_M_LB;
hudakz 0:84353c479782 289 uint8_t LBA_L_L_MB;
hudakz 0:84353c479782 290 uint8_t LBA_L_L_LB;
hudakz 0:84353c479782 291
hudakz 0:84353c479782 292 uint8_t A_M_M_MB;
hudakz 0:84353c479782 293 uint8_t A_M_M_LB;
hudakz 0:84353c479782 294 uint8_t A_M_L_MB;
hudakz 0:84353c479782 295 uint8_t A_M_L_LB;
hudakz 0:84353c479782 296
hudakz 0:84353c479782 297 uint8_t ALC_M_MB;
hudakz 0:84353c479782 298 uint8_t ALC_M_LB;
hudakz 0:84353c479782 299 uint8_t ALC_L_MB;
hudakz 0:84353c479782 300 uint8_t ALC_L_LB;
hudakz 0:84353c479782 301
hudakz 0:84353c479782 302 uint8_t Misc2;
hudakz 0:84353c479782 303 uint8_t Control;
hudakz 0:84353c479782 304 } __attribute__((packed));
hudakz 0:84353c479782 305
hudakz 0:84353c479782 306 struct CDB_LBA64_16 {
hudakz 0:84353c479782 307 uint8_t Opcode;
hudakz 0:84353c479782 308 uint8_t Misc;
hudakz 0:84353c479782 309
hudakz 0:84353c479782 310 uint8_t LBA_M_M_MB;
hudakz 0:84353c479782 311 uint8_t LBA_M_M_LB;
hudakz 0:84353c479782 312 uint8_t LBA_M_L_MB;
hudakz 0:84353c479782 313 uint8_t LBA_M_L_LB;
hudakz 0:84353c479782 314
hudakz 0:84353c479782 315 uint8_t LBA_L_M_MB;
hudakz 0:84353c479782 316 uint8_t LBA_L_M_LB;
hudakz 0:84353c479782 317 uint8_t LBA_L_L_MB;
hudakz 0:84353c479782 318 uint8_t LBA_L_L_LB;
hudakz 0:84353c479782 319
hudakz 0:84353c479782 320 uint8_t ALC_M_MB;
hudakz 0:84353c479782 321 uint8_t ALC_M_LB;
hudakz 0:84353c479782 322 uint8_t ALC_L_MB;
hudakz 0:84353c479782 323 uint8_t ALC_L_LB;
hudakz 0:84353c479782 324
hudakz 0:84353c479782 325 uint8_t Misc2;
hudakz 0:84353c479782 326 uint8_t Control;
hudakz 0:84353c479782 327 } __attribute__((packed));
hudakz 0:84353c479782 328
hudakz 0:84353c479782 329 struct InquiryResponse {
hudakz 0:84353c479782 330 uint8_t DeviceType : 5;
hudakz 0:84353c479782 331 uint8_t PeripheralQualifier : 3;
hudakz 0:84353c479782 332
hudakz 0:84353c479782 333 unsigned Reserved : 7;
hudakz 0:84353c479782 334 unsigned Removable : 1;
hudakz 0:84353c479782 335
hudakz 0:84353c479782 336 uint8_t Version;
hudakz 0:84353c479782 337
hudakz 0:84353c479782 338 unsigned ResponseDataFormat : 4;
hudakz 0:84353c479782 339 unsigned HISUP : 1;
hudakz 0:84353c479782 340 unsigned NormACA : 1;
hudakz 0:84353c479782 341 unsigned TrmTsk : 1;
hudakz 0:84353c479782 342 unsigned AERC : 1;
hudakz 0:84353c479782 343
hudakz 0:84353c479782 344 uint8_t AdditionalLength;
hudakz 0:84353c479782 345 //uint8_t Reserved3[2];
hudakz 0:84353c479782 346
hudakz 0:84353c479782 347 unsigned PROTECT : 1;
hudakz 0:84353c479782 348 unsigned Res : 2;
hudakz 0:84353c479782 349 unsigned ThreePC : 1;
hudakz 0:84353c479782 350 unsigned TPGS : 2;
hudakz 0:84353c479782 351 unsigned ACC : 1;
hudakz 0:84353c479782 352 unsigned SCCS : 1;
hudakz 0:84353c479782 353
hudakz 0:84353c479782 354 unsigned ADDR16 : 1;
hudakz 0:84353c479782 355 unsigned R1 : 1;
hudakz 0:84353c479782 356 unsigned R2 : 1;
hudakz 0:84353c479782 357 unsigned MCHNGR : 1;
hudakz 0:84353c479782 358 unsigned MULTIP : 1;
hudakz 0:84353c479782 359 unsigned VS : 1;
hudakz 0:84353c479782 360 unsigned ENCSERV : 1;
hudakz 0:84353c479782 361 unsigned BQUE : 1;
hudakz 0:84353c479782 362
hudakz 0:84353c479782 363 unsigned SoftReset : 1;
hudakz 0:84353c479782 364 unsigned CmdQue : 1;
hudakz 0:84353c479782 365 unsigned Reserved4 : 1;
hudakz 0:84353c479782 366 unsigned Linked : 1;
hudakz 0:84353c479782 367 unsigned Sync : 1;
hudakz 0:84353c479782 368 unsigned WideBus16Bit : 1;
hudakz 0:84353c479782 369 unsigned WideBus32Bit : 1;
hudakz 0:84353c479782 370 unsigned RelAddr : 1;
hudakz 0:84353c479782 371
hudakz 0:84353c479782 372 uint8_t VendorID[8];
hudakz 0:84353c479782 373 uint8_t ProductID[16];
hudakz 0:84353c479782 374 uint8_t RevisionID[4];
hudakz 0:84353c479782 375 } __attribute__((packed));
hudakz 0:84353c479782 376
hudakz 0:84353c479782 377 struct CommandBlockWrapperBase {
hudakz 0:84353c479782 378 uint32_t dCBWSignature;
hudakz 0:84353c479782 379 uint32_t dCBWTag;
hudakz 0:84353c479782 380 uint32_t dCBWDataTransferLength;
hudakz 0:84353c479782 381 uint8_t bmCBWFlags;
hudakz 0:84353c479782 382 public:
hudakz 0:84353c479782 383
hudakz 0:84353c479782 384 CommandBlockWrapperBase() {
hudakz 0:84353c479782 385 }
hudakz 0:84353c479782 386
hudakz 0:84353c479782 387 CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
hudakz 0:84353c479782 388 dCBWSignature(MASS_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
hudakz 0:84353c479782 389 }
hudakz 0:84353c479782 390 } __attribute__((packed));
hudakz 0:84353c479782 391
hudakz 0:84353c479782 392 struct CommandBlockWrapper : public CommandBlockWrapperBase {
hudakz 0:84353c479782 393
hudakz 0:84353c479782 394 struct {
hudakz 0:84353c479782 395 uint8_t bmCBWLUN : 4;
hudakz 0:84353c479782 396 uint8_t bmReserved1 : 4;
hudakz 0:84353c479782 397 };
hudakz 0:84353c479782 398
hudakz 0:84353c479782 399 struct {
hudakz 0:84353c479782 400 uint8_t bmCBWCBLength : 4;
hudakz 0:84353c479782 401 uint8_t bmReserved2 : 4;
hudakz 0:84353c479782 402 };
hudakz 0:84353c479782 403
hudakz 0:84353c479782 404 uint8_t CBWCB[16];
hudakz 0:84353c479782 405
hudakz 0:84353c479782 406 public:
hudakz 0:84353c479782 407 // All zeroed.
hudakz 0:84353c479782 408
hudakz 0:84353c479782 409 CommandBlockWrapper() :
hudakz 0:84353c479782 410 CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
hudakz 0:84353c479782 411 for(int i = 0; i < 16; i++) CBWCB[i] = 0;
hudakz 0:84353c479782 412 }
hudakz 0:84353c479782 413
hudakz 0:84353c479782 414 // Generic Wrap, CDB zeroed.
hudakz 0:84353c479782 415
hudakz 0:84353c479782 416 CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
hudakz 0:84353c479782 417 CommandBlockWrapperBase(tag, xflen, flgs),
hudakz 0:84353c479782 418 bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
hudakz 0:84353c479782 419 for(int i = 0; i < 16; i++) CBWCB[i] = 0;
hudakz 0:84353c479782 420 // Type punning can cause optimization problems and bugs.
hudakz 0:84353c479782 421 // Using reinterpret_cast to a dreinterpretifferent object is the proper way to do this.
hudakz 0:84353c479782 422 //(((BASICCDB_t *) CBWCB)->LUN) = cmd;
hudakz 0:84353c479782 423 BASICCDB_t *x = reinterpret_cast<BASICCDB_t *>(CBWCB);
hudakz 0:84353c479782 424 x->LUN = cmd;
hudakz 0:84353c479782 425 }
hudakz 0:84353c479782 426
hudakz 0:84353c479782 427 // Wrap for CDB of 6
hudakz 0:84353c479782 428
hudakz 0:84353c479782 429 CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
hudakz 0:84353c479782 430 CommandBlockWrapperBase(tag, xflen, dir),
hudakz 0:84353c479782 431 bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
hudakz 0:84353c479782 432 memcpy(&CBWCB, cdb, 6);
hudakz 0:84353c479782 433 }
hudakz 0:84353c479782 434 // Wrap for CDB of 10
hudakz 0:84353c479782 435
hudakz 0:84353c479782 436 CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
hudakz 0:84353c479782 437 CommandBlockWrapperBase(tag, xflen, dir),
hudakz 0:84353c479782 438 bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
hudakz 0:84353c479782 439 memcpy(&CBWCB, cdb, 10);
hudakz 0:84353c479782 440 }
hudakz 0:84353c479782 441 } __attribute__((packed));
hudakz 0:84353c479782 442
hudakz 0:84353c479782 443 struct CommandStatusWrapper {
hudakz 0:84353c479782 444 uint32_t dCSWSignature;
hudakz 0:84353c479782 445 uint32_t dCSWTag;
hudakz 0:84353c479782 446 uint32_t dCSWDataResidue;
hudakz 0:84353c479782 447 uint8_t bCSWStatus;
hudakz 0:84353c479782 448 } __attribute__((packed));
hudakz 0:84353c479782 449
hudakz 0:84353c479782 450 struct RequestSenseResponce {
hudakz 0:84353c479782 451 uint8_t bResponseCode;
hudakz 0:84353c479782 452 uint8_t bSegmentNumber;
hudakz 0:84353c479782 453
hudakz 0:84353c479782 454 uint8_t bmSenseKey : 4;
hudakz 0:84353c479782 455 uint8_t bmReserved : 1;
hudakz 0:84353c479782 456 uint8_t bmILI : 1;
hudakz 0:84353c479782 457 uint8_t bmEOM : 1;
hudakz 0:84353c479782 458 uint8_t bmFileMark : 1;
hudakz 0:84353c479782 459
hudakz 0:84353c479782 460 uint8_t Information[4];
hudakz 0:84353c479782 461 uint8_t bAdditionalLength;
hudakz 0:84353c479782 462 uint8_t CmdSpecificInformation[4];
hudakz 0:84353c479782 463 uint8_t bAdditionalSenseCode;
hudakz 0:84353c479782 464 uint8_t bAdditionalSenseQualifier;
hudakz 0:84353c479782 465 uint8_t bFieldReplaceableUnitCode;
hudakz 0:84353c479782 466 uint8_t SenseKeySpecific[3];
hudakz 0:84353c479782 467 } __attribute__((packed));
hudakz 0:84353c479782 468
hudakz 0:84353c479782 469 class BulkOnly : public USBDeviceConfig, public UsbConfigXtracter {
hudakz 0:84353c479782 470 protected:
hudakz 0:84353c479782 471 static const uint8_t epDataInIndex; // DataIn endpoint index
hudakz 0:84353c479782 472 static const uint8_t epDataOutIndex; // DataOUT endpoint index
hudakz 0:84353c479782 473 static const uint8_t epInterruptInIndex; // InterruptIN endpoint index
hudakz 0:84353c479782 474
hudakz 0:84353c479782 475 USB *pUsb;
hudakz 0:84353c479782 476 uint8_t bAddress;
hudakz 0:84353c479782 477 uint8_t bConfNum; // configuration number
hudakz 0:84353c479782 478 uint8_t bIface; // interface value
hudakz 0:84353c479782 479 uint8_t bNumEP; // total number of EP in the configuration
hudakz 0:84353c479782 480 uint32_t qNextPollTime; // next poll time
hudakz 0:84353c479782 481 bool bPollEnable; // poll enable flag
hudakz 0:84353c479782 482
hudakz 0:84353c479782 483 EpInfo epInfo[MASS_MAX_ENDPOINTS];
hudakz 0:84353c479782 484
hudakz 0:84353c479782 485 uint32_t dCBWTag; // Tag
hudakz 0:84353c479782 486 //uint32_t dCBWDataTransferLength; // Data Transfer Length
hudakz 0:84353c479782 487 uint8_t bLastUsbError; // Last USB error
hudakz 0:84353c479782 488 uint8_t bMaxLUN; // Max LUN
hudakz 0:84353c479782 489 uint8_t bTheLUN; // Active LUN
hudakz 0:84353c479782 490 uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
hudakz 0:84353c479782 491 uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
hudakz 0:84353c479782 492 bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
hudakz 0:84353c479782 493 bool WriteOk[MASS_MAX_SUPPORTED_LUN];
hudakz 0:84353c479782 494 void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
hudakz 0:84353c479782 495
hudakz 0:84353c479782 496
hudakz 0:84353c479782 497 // Additional Initialization Method for Subclasses
hudakz 0:84353c479782 498
hudakz 0:84353c479782 499 virtual uint8_t OnInit() {
hudakz 0:84353c479782 500 return 0;
hudakz 0:84353c479782 501 };
hudakz 0:84353c479782 502 public:
hudakz 0:84353c479782 503 BulkOnly(USB *p);
hudakz 0:84353c479782 504
hudakz 0:84353c479782 505 uint8_t GetLastUsbError() {
hudakz 0:84353c479782 506 return bLastUsbError;
hudakz 0:84353c479782 507 };
hudakz 0:84353c479782 508
hudakz 0:84353c479782 509 uint8_t GetbMaxLUN() {
hudakz 0:84353c479782 510 return bMaxLUN; // Max LUN
hudakz 0:84353c479782 511 }
hudakz 0:84353c479782 512
hudakz 0:84353c479782 513 uint8_t GetbTheLUN() {
hudakz 0:84353c479782 514 return bTheLUN; // Active LUN
hudakz 0:84353c479782 515 }
hudakz 0:84353c479782 516
hudakz 0:84353c479782 517 bool WriteProtected(uint8_t lun);
hudakz 0:84353c479782 518 uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
hudakz 0:84353c479782 519 uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
hudakz 0:84353c479782 520 uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, USBReadParser *prs);
hudakz 0:84353c479782 521 uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
hudakz 0:84353c479782 522 uint8_t LockMedia(uint8_t lun, uint8_t lock);
hudakz 0:84353c479782 523
hudakz 0:84353c479782 524 bool LUNIsGood(uint8_t lun);
hudakz 0:84353c479782 525 uint32_t GetCapacity(uint8_t lun);
hudakz 0:84353c479782 526 uint16_t GetSectorSize(uint8_t lun);
hudakz 0:84353c479782 527
hudakz 0:84353c479782 528 // USBDeviceConfig implementation
hudakz 0:84353c479782 529 uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
hudakz 0:84353c479782 530 uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
hudakz 0:84353c479782 531
hudakz 0:84353c479782 532 uint8_t Release();
hudakz 0:84353c479782 533 uint8_t Poll();
hudakz 0:84353c479782 534
hudakz 0:84353c479782 535 virtual uint8_t GetAddress() {
hudakz 0:84353c479782 536 return bAddress;
hudakz 0:84353c479782 537 };
hudakz 0:84353c479782 538
hudakz 0:84353c479782 539 // UsbConfigXtracter implementation
hudakz 0:84353c479782 540 void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
hudakz 0:84353c479782 541
hudakz 0:84353c479782 542 virtual bool DEVCLASSOK(uint8_t klass) {
hudakz 0:84353c479782 543 return (klass == USB_CLASS_MASS_STORAGE);
hudakz 0:84353c479782 544 }
hudakz 0:84353c479782 545
hudakz 0:84353c479782 546 uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
hudakz 0:84353c479782 547 uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
hudakz 0:84353c479782 548
hudakz 0:84353c479782 549 private:
hudakz 0:84353c479782 550 uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
hudakz 0:84353c479782 551 uint8_t TestUnitReady(uint8_t lun);
hudakz 0:84353c479782 552 uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
hudakz 0:84353c479782 553 uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
hudakz 0:84353c479782 554 uint8_t GetMaxLUN(uint8_t *max_lun);
hudakz 0:84353c479782 555 uint8_t SetCurLUN(uint8_t lun);
hudakz 0:84353c479782 556 void Reset();
hudakz 0:84353c479782 557 uint8_t ResetRecovery();
hudakz 0:84353c479782 558 uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
hudakz 0:84353c479782 559 void ClearAllEP();
hudakz 0:84353c479782 560 void CheckMedia();
hudakz 0:84353c479782 561 bool CheckLUN(uint8_t lun);
hudakz 0:84353c479782 562 uint8_t Page3F(uint8_t lun);
hudakz 0:84353c479782 563 bool IsValidCBW(uint8_t size, uint8_t *pcbw);
hudakz 0:84353c479782 564 bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
hudakz 0:84353c479782 565
hudakz 0:84353c479782 566 bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
hudakz 0:84353c479782 567
hudakz 0:84353c479782 568 uint8_t ClearEpHalt(uint8_t index);
hudakz 0:84353c479782 569 #if MS_WANT_PARSER
hudakz 0:84353c479782 570 uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
hudakz 0:84353c479782 571 #endif
hudakz 0:84353c479782 572 uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
hudakz 0:84353c479782 573 uint8_t HandleUsbError(uint8_t error, uint8_t index);
hudakz 0:84353c479782 574 uint8_t HandleSCSIError(uint8_t status);
hudakz 0:84353c479782 575
hudakz 0:84353c479782 576 };
hudakz 0:84353c479782 577
hudakz 0:84353c479782 578 #endif // __MASSTORAGE_H__