1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** USBX Component */ 16 /** */ 17 /** Device Storage Class */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 23 /**************************************************************************/ 24 /* */ 25 /* COMPONENT DEFINITION RELEASE */ 26 /* */ 27 /* ux_device_class_storage.h PORTABLE C */ 28 /* 6.3.0 */ 29 /* AUTHOR */ 30 /* */ 31 /* Chaoqiong Xiao, Microsoft Corporation */ 32 /* */ 33 /* DESCRIPTION */ 34 /* */ 35 /* This file contains all the header and extern functions used by the */ 36 /* USBX device storage class. */ 37 /* */ 38 /* RELEASE HISTORY */ 39 /* */ 40 /* DATE NAME DESCRIPTION */ 41 /* */ 42 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 43 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 44 /* optimized command logic, */ 45 /* resulting in version 6.1 */ 46 /* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ 47 /* fixed USB CV test issues, */ 48 /* resulting in version 6.1.3 */ 49 /* 08-02-2021 Chaoqiong Xiao Modified comment(s), */ 50 /* added extern "C" keyword */ 51 /* for compatibility with C++, */ 52 /* resulting in version 6.1.8 */ 53 /* 10-15-2021 Chaoqiong Xiao Modified comment(s), */ 54 /* improved TAG management, */ 55 /* resulting in version 6.1.9 */ 56 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ 57 /* added standalone support, */ 58 /* resulting in version 6.1.10 */ 59 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */ 60 /* added a new mode to manage */ 61 /* endpoint buffer in classes, */ 62 /* added error checks support, */ 63 /* resulting in version 6.3.0 */ 64 /* */ 65 /**************************************************************************/ 66 67 #ifndef UX_DEVICE_CLASS_STORAGE_H 68 #define UX_DEVICE_CLASS_STORAGE_H 69 70 /* Determine if a C++ compiler is being used. If so, ensure that standard 71 C is used to process the API information. */ 72 73 #ifdef __cplusplus 74 75 /* Yes, C++ compiler is present. Use standard C. */ 76 extern "C" { 77 78 #endif 79 80 81 /* Internal option: enable the basic USBX error checking. This define is typically used 82 while debugging application. */ 83 #if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_DEVICE_CLASS_STORAGE_ENABLE_ERROR_CHECKING) 84 #define UX_DEVICE_CLASS_STORAGE_ENABLE_ERROR_CHECKING 85 #endif 86 87 /* Bulk endpoint buffer size (UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE). */ 88 #define UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE 89 90 /* Define User configurable Storage Class constants. */ 91 92 #ifndef UX_MAX_SLAVE_LUN 93 #define UX_MAX_SLAVE_LUN 2 94 #endif 95 96 97 /* Define Storage Class USB Class constants. */ 98 99 #define UX_SLAVE_CLASS_STORAGE_CLASS 8 100 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_RBC 1 101 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SFF8020 2 102 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_UFI 4 103 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SFF8070 5 104 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SCSI 6 105 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_CBI 0 106 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_CB 1 107 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_BO 0x50 108 109 /* Define Storage Class USB MEDIA types. */ 110 #define UX_SLAVE_CLASS_STORAGE_MEDIA_FAT_DISK 0 111 #define UX_SLAVE_CLASS_STORAGE_MEDIA_CDROM 5 112 #define UX_SLAVE_CLASS_STORAGE_MEDIA_OPTICAL_DISK 7 113 #define UX_SLAVE_CLASS_STORAGE_MEDIA_IOMEGA_CLICK 0x55 114 115 116 117 /* Define Storage Class SCSI command constants. */ 118 119 #define UX_SLAVE_CLASS_STORAGE_SCSI_TEST_READY 0x00 120 #define UX_SLAVE_CLASS_STORAGE_SCSI_REQUEST_SENSE 0x03 121 #define UX_SLAVE_CLASS_STORAGE_SCSI_FORMAT 0x04 122 #define UX_SLAVE_CLASS_STORAGE_SCSI_INQUIRY 0x12 123 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT 0x1a 124 #define UX_SLAVE_CLASS_STORAGE_SCSI_START_STOP 0x1b 125 #define UX_SLAVE_CLASS_STORAGE_SCSI_PREVENT_ALLOW_MEDIA_REMOVAL 0x1e 126 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_FORMAT_CAPACITY 0x23 127 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_CAPACITY 0x25 128 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ16 0x28 129 #define UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16 0x2a 130 #define UX_SLAVE_CLASS_STORAGE_SCSI_VERIFY 0x2f 131 #define UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE 0x35 132 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_TOC 0x43 133 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_CONFIGURATION 0x46 134 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_STATUS_NOTIFICATION 0x4A 135 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_DISK_INFORMATION 0x51 136 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SELECT 0x55 137 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE 0x5a 138 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ32 0xa8 139 #define UX_SLAVE_CLASS_STORAGE_SCSI_REPORT_KEY 0xa4 140 #define UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32 0xaa 141 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_PERFORMANCE 0xac 142 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_DVD_STRUCTURE 0xad 143 144 /* Define Storage Class SCSI command block wrapper constants. */ 145 146 #define UX_SLAVE_CLASS_STORAGE_CBW_SIGNATURE_MASK 0x43425355 147 #define UX_SLAVE_CLASS_STORAGE_CBW_SIGNATURE 0 148 #define UX_SLAVE_CLASS_STORAGE_CBW_TAG 4 149 #define UX_SLAVE_CLASS_STORAGE_CBW_DATA_LENGTH 8 150 #define UX_SLAVE_CLASS_STORAGE_CBW_FLAGS 12 151 #define UX_SLAVE_CLASS_STORAGE_CBW_LUN 13 152 #define UX_SLAVE_CLASS_STORAGE_CBW_CB_LENGTH 14 153 #define UX_SLAVE_CLASS_STORAGE_CBW_CB 15 154 #define UX_SLAVE_CLASS_STORAGE_CBW_LENGTH 31 155 156 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_DIR (1u<<7) 157 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_IN (1u<<7) 158 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_D2H (1u<<7) 159 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_OUT (0u) 160 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_H2D (0u) 161 162 163 /* Define Storage Class SCSI response status wrapper constants. */ 164 165 #define UX_SLAVE_CLASS_STORAGE_CSW_SIGNATURE_MASK 0x53425355 166 #define UX_SLAVE_CLASS_STORAGE_CSW_SIGNATURE 0 167 #define UX_SLAVE_CLASS_STORAGE_CSW_TAG 4 168 #define UX_SLAVE_CLASS_STORAGE_CSW_DATA_RESIDUE 8 169 #define UX_SLAVE_CLASS_STORAGE_CSW_STATUS 12 170 #define UX_SLAVE_CLASS_STORAGE_CSW_LENGTH 13 171 172 173 /* Define Storage Class SCSI inquiry command constants. */ 174 175 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_OPERATION 0 176 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_LUN 1 177 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE 2 178 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_ALLOCATION_LENGTH 4 179 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_UFI 12 180 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC 06 181 182 183 /* Define Storage Class SCSI inquiry response constants. */ 184 185 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PERIPHERAL_TYPE 0 186 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_REMOVABLE_MEDIA 1 187 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_DATA_FORMAT 3 188 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_ADDITIONAL_LENGTH 4 189 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_VENDOR_INFORMATION 8 190 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_ID 16 191 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION 32 192 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH 36 193 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH_CD_ROM 0x5b 194 195 196 /* Define Storage Class SCSI start/stop command constants. */ 197 198 #define UX_SLAVE_CLASS_STORAGE_START_STOP_OPERATION 0 199 #define UX_SLAVE_CLASS_STORAGE_START_STOP_LBUFLAGS 1 200 #define UX_SLAVE_CLASS_STORAGE_START_STOP_START_BIT 4 201 #define UX_SLAVE_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_UFI 12 202 #define UX_SLAVE_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_SBC 6 203 204 205 /* Define Storage Class SCSI mode sense command constants. */ 206 207 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_OPERATION 0 208 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_LUN 1 209 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PC_PAGE_CODE 2 210 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_6 4 211 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_10 7 212 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_ALLOCATION_LENGTH_6 4 213 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_ALLOCATION_LENGTH_10 7 214 215 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_MEDIUM_TYPE_6 1 216 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_MEDIUM_TYPE_10 2 217 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAGS_6 2 218 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAGS_10 3 219 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAG_WP 0x80 220 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_HEADER_LENGTH_6 4 221 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_HEADER_LENGTH_10 8 222 223 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_UFI 12 224 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_SBC 12 225 226 #define UX_SLAVE_CLASS_STORAGE_IEC_MODE_PAGE_PAGE_LENGTH 0x0A 227 228 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_PAGE_LENGTH 0x12 229 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_CODE 0 230 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_LENGTH 1 231 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_FLAGS 2 232 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_FLAG_WCE (1u<<2) 233 234 235 /* Define Storage Class SCSI request sense command constants. */ 236 237 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_OPERATION 0 238 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_LUN 1 239 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_ALLOCATION_LENGTH 4 240 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_UFI 12 241 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC 12 242 243 244 /* Define Storage Class request sense response constants. */ 245 246 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE 0 247 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_SENSE_KEY 2 248 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_INFORMATION 3 249 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ADD_LENGTH 7 250 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE 12 251 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE_QUALIFIER 13 252 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH 18 253 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_HEADER_LENGTH 8 254 255 256 /* Define Storage Class read capacity command constants. */ 257 258 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_OPERATION 0 259 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_LUN 1 260 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_LBA 2 261 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_UFI 12 262 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_SBC 10 263 264 265 /* Define Storage Class read capacity response constants. */ 266 267 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LAST_LBA 0 268 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_BLOCK_SIZE 4 269 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LENGTH 8 270 271 /* Define Storage Class read capacity response constants. */ 272 273 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_SIZE 0 274 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_LAST_LBA 4 275 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_DESC_CODE 8 276 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_BLOCK_SIZE 8 277 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_LENGTH 12 278 279 /* Define Storage Class test unit read command constants. */ 280 281 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_OPERATION 0 282 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_LUN 1 283 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_UFI 12 284 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC 6 285 286 287 /* Define Storage Class SCSI read command constants. */ 288 289 #define UX_SLAVE_CLASS_STORAGE_READ_OPERATION 0 290 #define UX_SLAVE_CLASS_STORAGE_READ_LUN 1 291 #define UX_SLAVE_CLASS_STORAGE_READ_LBA 2 292 #define UX_SLAVE_CLASS_STORAGE_READ_TRANSFER_LENGTH_32 6 293 #define UX_SLAVE_CLASS_STORAGE_READ_TRANSFER_LENGTH_16 7 294 #define UX_SLAVE_CLASS_STORAGE_READ_COMMAND_LENGTH_UFI 12 295 #define UX_SLAVE_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC 10 296 297 298 /* Define Storage Class SCSI write command constants. */ 299 300 #define UX_SLAVE_CLASS_STORAGE_WRITE_OPERATION 0 301 #define UX_SLAVE_CLASS_STORAGE_WRITE_LUN 1 302 #define UX_SLAVE_CLASS_STORAGE_WRITE_LBA 2 303 #define UX_SLAVE_CLASS_STORAGE_WRITE_TRANSFER_LENGTH_32 6 304 #define UX_SLAVE_CLASS_STORAGE_WRITE_TRANSFER_LENGTH_16 7 305 #define UX_SLAVE_CLASS_STORAGE_WRITE_COMMAND_LENGTH_UFI 12 306 #define UX_SLAVE_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC 10 307 308 309 /* Define Storage Class SCSI sense key definition constants. */ 310 311 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE 0x0 312 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_RECOVERED_ERROR 0x1 313 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NOT_READY 0x2 314 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_MEDIUM_ERROR 0x3 315 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_HARDWARE_ERROR 0x4 316 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST 0x5 317 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION 0x6 318 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_DATA_PROTECT 0x7 319 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_BLANK_CHECK 0x8 320 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ABORTED_COMMAND 0x0b 321 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_VOLUME_OVERFLOW 0x0d 322 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_MISCOMPARE 0x0e 323 324 325 /* Define Storage Class SCSI sense key definition constants. */ 326 327 #define UX_SLAVE_CLASS_STORAGE_REQUEST_CODE_MEDIA_PROTECTED 0x27 328 329 /* Define Storage Class SCSI GET CONFIGURATION command constants. */ 330 331 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_OPERATION 0 332 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_RT 1 333 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_STARTING_FEATURE 2 334 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_ALLOCATION_LENGTH 7 335 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_COMMAND_LENGTH_SBC 9 336 337 /* Define Storage Class SCSI ASC return codes. */ 338 #define UX_SLAVE_CLASS_STORAGE_ASC_KEY_INVALID_COMMAND 0x20 339 340 /* Define Storage Class CSW status. */ 341 342 #define UX_SLAVE_CLASS_STORAGE_CSW_PASSED 0 343 #define UX_SLAVE_CLASS_STORAGE_CSW_FAILED 1 344 #define UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR 2 345 346 /* Define generic SCSI values. */ 347 348 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE_VALUE 0x70 349 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_STANDARD 0x00 350 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_SERIAL 0x80 351 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PERIPHERAL_TYPE 0x00 352 #define UX_SLAVE_CLASS_STORAGE_RESET 0xff 353 #define UX_SLAVE_CLASS_STORAGE_GET_MAX_LUN 0xfe 354 #define UX_SLAVE_CLASS_STORAGE_MAX_LUN 0 355 #define UX_SLAVE_CLASS_STORAGE_RESPONSE_LENGTH 64 356 357 /* Define Storage Class SCSI read disk information command constants. */ 358 359 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_OPERATION 0 360 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_STATUS 2 361 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_ALLOCATION_LENGTH 7 362 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_LENGTH 10 363 364 /* Define Storage Class Feature Descriptor generic format. */ 365 366 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_CODE 0 367 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_PARAMETER 2 368 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_ADD_LENGTH 3 369 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_LENGTH 4 370 371 372 /* Define Storage Class SCSI REPORT_KEY command constants. */ 373 374 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_OPERATION 0 375 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ALLOCATION_LENGTH 8 376 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT 10 377 378 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_LENGTH 8 379 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_PAYLOAD 6 380 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_RESET_FIELD 4 381 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_REGION_MASK 5 382 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_RPC_SCHEME 6 383 384 385 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_AGID 0 386 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_CHALLENGE 1 387 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_KEY2 2 388 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_TITLE 4 389 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_RPC 8 390 391 /* Define Storage Class SCSI get event status notification command constants. */ 392 393 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_OPCODE 0 394 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_IMMEDIATE 1 395 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_CLASS_REQUEST 4 396 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_ALLOCATION_LENGTH 7 397 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_LENGTH 10 398 399 /* Define Storage Class SCSI read toc command constants. */ 400 401 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_OPCODE 0 402 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_FORMAT 2 403 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_TRACK_NUMBER 6 404 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_ALLOCATION_LENGTH 7 405 406 /* Define Storage Class SCSI read DVD structure command constants. */ 407 408 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_OPCODE 0 409 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_ADDRESS 2 410 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_FORMAT 7 411 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_ALLOCATION_LENGTH 8 412 413 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_RESP_LENGTH 0 414 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_BOOK_TYPE 4 415 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_DS_MR 5 416 417 418 /* Define Storage Class SCSI get performance command constants. */ 419 420 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE 1 421 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE_14 0x14 422 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE_0 0x00 423 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAYLOAD_LENGTH 4 424 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_RESPONSE_LENGTH 8 425 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAYLOAD 0x20000000 426 427 /* Define buffer length for IN/OUT pipes. This should match the size of the endpoint maximum buffer size. */ 428 429 #define UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE UX_SLAVE_REQUEST_DATA_MAX_LENGTH 430 431 432 /* Define MMC2 CD-ROM / DVD-ROM bit fields */ 433 434 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_EMPTY 0 435 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_INCOMPLETE 1 436 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_COMPLETE 2 437 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_OTHERS 3 438 439 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_EMPTY 0 440 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_INCOMPLETE 1 441 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_COMPLETE 3 442 443 444 /* Define Storage Class SCSI synchronize cache constants. */ 445 446 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS 1 447 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_LBA 2 448 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_NUMBER_OF_BLOCKS 7 449 450 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS_IMMED 0x02 451 452 453 /* Define MODE SENSE Page Codes. */ 454 #define UX_SLAVE_CLASS_STORAGE_MMC2_PAGE_CODE_CDROM 0x2a 455 456 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE 0x08 457 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_IEC 0x1C 458 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_ALL 0x3F 459 460 #if defined(UX_DEVICE_STANDALONE) 461 462 /* Define Device Storage Class states. */ 463 464 #define UX_DEVICE_CLASS_STORAGE_STATE_IDLE (UX_STATE_STEP + 0) 465 #define UX_DEVICE_CLASS_STORAGE_STATE_RESET (UX_STATE_STEP + 1) 466 #define UX_DEVICE_CLASS_STORAGE_STATE_RESET_WAIT (UX_STATE_STEP + 2) 467 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_START (UX_STATE_STEP + 3) 468 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_WAIT (UX_STATE_STEP + 4) 469 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_NEXT (UX_STATE_STEP + 5) 470 #define UX_DEVICE_CLASS_STORAGE_STATE_DISK_WAIT (UX_STATE_STEP + 6) 471 #define UX_DEVICE_CLASS_STORAGE_STATE_DISK_ERROR (UX_STATE_STEP + 7) 472 473 #define UX_DEVICE_CLASS_STORAGE_DISK_IDLE (0) 474 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_START (1) 475 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_WAIT (2) 476 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_NEXT (3) 477 #define UX_DEVICE_CLASS_STORAGE_DISK_USB_WAIT (4) 478 #define UX_DEVICE_CLASS_STORAGE_DISK_USB_ERROR (5) 479 480 #define UX_DEVICE_CLASS_STORAGE_BUFFER_IDLE (0) 481 #define UX_DEVICE_CLASS_STORAGE_BUFFER_EMPTY (1) 482 #define UX_DEVICE_CLASS_STORAGE_BUFFER_FULL (2) 483 484 #define UX_DEVICE_CLASS_STORAGE_CMD_IDLE (0) 485 #define UX_DEVICE_CLASS_STORAGE_CMD_CBW (1) 486 #define UX_DEVICE_CLASS_STORAGE_CMD_ERR (2) 487 #define UX_DEVICE_CLASS_STORAGE_CMD_CSW (3) 488 #define UX_DEVICE_CLASS_STORAGE_CMD_WRITE (4) 489 #define UX_DEVICE_CLASS_STORAGE_CMD_READ (5) 490 #define UX_DEVICE_CLASS_STORAGE_CMD_DISK_OP (6) 491 492 #endif 493 494 /* Define Slave Storage Class LUN structure. */ 495 496 typedef struct UX_SLAVE_CLASS_STORAGE_LUN_STRUCT 497 { 498 ULONG ux_slave_class_storage_media_last_lba; 499 ULONG ux_slave_class_storage_media_block_length; 500 ULONG ux_slave_class_storage_media_type; 501 ULONG ux_slave_class_storage_media_removable_flag; 502 ULONG ux_slave_class_storage_media_read_only_flag; 503 ULONG ux_slave_class_storage_media_id; 504 ULONG ux_slave_class_storage_request_sense_status; 505 ULONG ux_slave_class_storage_disk_status; 506 ULONG ux_slave_class_storage_last_session_state; 507 508 UINT (*ux_slave_class_storage_media_read)(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status); 509 UINT (*ux_slave_class_storage_media_write)(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status); 510 UINT (*ux_slave_class_storage_media_flush)(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status); 511 UINT (*ux_slave_class_storage_media_status)(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status); 512 UINT (*ux_slave_class_storage_media_notification)(VOID *storage, ULONG lun, ULONG media_id, ULONG notification_class, UCHAR **media_notification, ULONG *media_notification_length); 513 } UX_SLAVE_CLASS_STORAGE_LUN; 514 515 /* Sense status value (key at bit0-7, code at bit8-15 and qualifier at bit16-23). */ 516 517 #define UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(key,code,qualifier) (((key) & 0xFF)|(((code) & 0xFF) << 8)|(((qualifier) & 0xFF) << 16)) 518 #define UX_DEVICE_CLASS_STORAGE_SENSE_KEY(status) ((status) & 0xFF) 519 #define UX_DEVICE_CLASS_STORAGE_SENSE_CODE(status) (((status) >> 8) & 0xFF) 520 #define UX_DEVICE_CLASS_STORAGE_SENSE_QUALIFIER(status) (((status) >> 16) & 0xFF) 521 522 523 /* Define Slave Storage Class structure. */ 524 525 typedef struct UX_SLAVE_CLASS_STORAGE_STRUCT 526 { 527 UX_SLAVE_INTERFACE *ux_slave_class_storage_interface; 528 #if UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1 529 UCHAR *ux_device_class_storage_endpoint_buffer; 530 #endif 531 ULONG ux_slave_class_storage_number_lun; 532 UX_SLAVE_CLASS_STORAGE_LUN ux_slave_class_storage_lun[UX_MAX_SLAVE_LUN]; 533 ULONG ux_slave_class_storage_host_length; 534 UCHAR ux_slave_class_storage_cbw_flags; 535 UCHAR ux_slave_class_storage_cbw_lun; 536 UCHAR ux_slave_class_storage_reserved[2]; 537 ULONG ux_slave_class_storage_scsi_tag; 538 ULONG ux_slave_class_storage_csw_residue; 539 ULONG ux_slave_class_storage_csw_status; 540 VOID (*ux_slave_class_storage_instance_activate)(VOID *); 541 VOID (*ux_slave_class_storage_instance_deactivate)(VOID *); 542 UCHAR *ux_slave_class_storage_vendor_id; 543 UCHAR *ux_slave_class_storage_product_id; 544 UCHAR *ux_slave_class_storage_product_rev; 545 UCHAR *ux_slave_class_storage_product_serial; 546 547 #if defined(UX_DEVICE_STANDALONE) 548 UCHAR *ux_device_class_storage_buffer[2]; 549 UCHAR ux_device_class_storage_buffer_state[2]; 550 UCHAR ux_device_class_storage_buffer_usb; 551 UCHAR ux_device_class_storage_buffer_disk; 552 553 UCHAR ux_device_class_storage_cmd; 554 UCHAR ux_device_class_storage_cmd_state; 555 UCHAR ux_device_class_storage_disk_state; 556 UCHAR ux_device_class_storage_state; 557 558 UX_SLAVE_ENDPOINT *ux_device_class_storage_ep_out; 559 UX_SLAVE_ENDPOINT *ux_device_class_storage_ep_in; 560 UX_SLAVE_TRANSFER *ux_device_class_storage_transfer; 561 562 ULONG ux_device_class_storage_device_length; 563 UCHAR *ux_device_class_storage_data_buffer; 564 ULONG ux_device_class_storage_data_length; 565 ULONG ux_device_class_storage_data_count; 566 ULONG ux_device_class_storage_trans_host_length; 567 ULONG ux_device_class_storage_trans_device_length; 568 569 ULONG ux_device_class_storage_cmd_lba; 570 ULONG ux_device_class_storage_cmd_n_lb; 571 ULONG ux_device_class_storage_disk_n_lb; 572 ULONG ux_device_class_storage_media_status; 573 #endif 574 575 } UX_SLAVE_CLASS_STORAGE; 576 577 /* Defined for endpoint buffer settings (when STORAGE owns buffer). */ 578 #define UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE_CALC_OVERFLOW \ 579 (UX_OVERFLOW_CHECK_MULC_ULONG(UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE, 2)) 580 #define UX_DEVICE_CLASS_STORAGE_ENDPOINT_BUFFER_SIZE (UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE * 2) 581 #define UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage) ((storage)->ux_device_class_storage_endpoint_buffer) 582 #define UX_DEVICE_CLASS_STORAGE_BULKIN_BUFFER(storage) (UX_DEVICE_CLASS_STORAGE_BULKOUT_BUFFER(storage) + UX_DEVICE_CLASS_STORAGE_BULK_BUFFER_SIZE) 583 584 #define UX_DEVICE_CLASS_STORAGE_CSW_STATUS(p) (((UCHAR*)(p))[0]) 585 #define UX_DEVICE_CLASS_STORAGE_CSW_SKIP(p) (((UCHAR*)(p))[3]) 586 587 /* Define Slave Storage Class Calling Parameter structure */ 588 589 typedef struct UX_SLAVE_CLASS_STORAGE_PARAMETER_STRUCT 590 { 591 VOID (*ux_slave_class_storage_instance_activate)(VOID *); 592 VOID (*ux_slave_class_storage_instance_deactivate)(VOID *); 593 ULONG ux_slave_class_storage_parameter_number_lun; 594 UX_SLAVE_CLASS_STORAGE_LUN ux_slave_class_storage_parameter_lun[UX_MAX_SLAVE_LUN]; 595 UCHAR *ux_slave_class_storage_parameter_vendor_id; 596 UCHAR *ux_slave_class_storage_parameter_product_id; 597 UCHAR *ux_slave_class_storage_parameter_product_rev; 598 UCHAR *ux_slave_class_storage_parameter_product_serial; 599 600 } UX_SLAVE_CLASS_STORAGE_PARAMETER; 601 602 /* Define Device Storage Class prototypes. */ 603 604 UINT _ux_device_class_storage_initialize(UX_SLAVE_CLASS_COMMAND *command); 605 UINT _ux_device_class_storage_uninitialize(UX_SLAVE_CLASS_COMMAND *command); 606 UINT _ux_device_class_storage_activate(UX_SLAVE_CLASS_COMMAND *command); 607 UINT _ux_device_class_storage_control_request(UX_SLAVE_CLASS_COMMAND *command); 608 UINT _ux_device_class_storage_csw_send(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, UCHAR csw_status); 609 UINT _ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND *command); 610 UINT _ux_device_class_storage_entry(UX_SLAVE_CLASS_COMMAND *command); 611 UINT _ux_device_class_storage_format(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 612 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 613 UINT _ux_device_class_storage_inquiry(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 614 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 615 UINT _ux_device_class_storage_mode_select(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 616 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 617 UINT _ux_device_class_storage_mode_sense(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 618 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 619 UINT _ux_device_class_storage_prevent_allow_media_removal(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, 620 UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb); 621 UINT _ux_device_class_storage_read(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 622 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command); 623 UINT _ux_device_class_storage_read_capacity(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 624 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 625 UINT _ux_device_class_storage_read_format_capacity(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 626 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 627 UINT _ux_device_class_storage_read_toc(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 628 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb); 629 UINT _ux_device_class_storage_request_sense(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 630 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 631 UINT _ux_device_class_storage_start_stop(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 632 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 633 UINT _ux_device_class_storage_test_ready(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 634 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 635 VOID _ux_device_class_storage_thread(ULONG storage_instance); 636 UINT _ux_device_class_storage_verify(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 637 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 638 UINT _ux_device_class_storage_write(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 639 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command); 640 UINT _ux_device_class_storage_synchronize_cache(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, 641 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command); 642 UINT _ux_device_class_storage_read_disk_information(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, 643 UX_SLAVE_ENDPOINT *endpoint_in, 644 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 645 646 UINT _ux_device_class_storage_get_configuration(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, 647 UX_SLAVE_ENDPOINT *endpoint_in, 648 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 649 UINT _ux_device_class_storage_get_status_notification(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, 650 UX_SLAVE_ENDPOINT *endpoint_in, 651 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 652 UINT _ux_device_class_storage_report_key(UX_SLAVE_CLASS_STORAGE *storage, 653 ULONG lun, 654 UX_SLAVE_ENDPOINT *endpoint_in, 655 UX_SLAVE_ENDPOINT *endpoint_out, 656 UCHAR *cbwcb); 657 658 UINT _ux_device_class_storage_get_performance(UX_SLAVE_CLASS_STORAGE *storage, 659 ULONG lun, 660 UX_SLAVE_ENDPOINT *endpoint_in, 661 UX_SLAVE_ENDPOINT *endpoint_out, 662 UCHAR *cbwcb); 663 UINT _ux_device_class_storage_read_dvd_structure(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, 664 UX_SLAVE_ENDPOINT *endpoint_in, 665 UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb); 666 667 UINT _ux_device_class_storage_tasks_run(VOID *instance); 668 669 670 UINT _uxe_device_class_storage_initialize(UX_SLAVE_CLASS_COMMAND *command); 671 672 673 /* Define Device Storage Class API prototypes. */ 674 675 #define ux_device_class_storage_entry _ux_device_class_storage_entry 676 677 /* Determine if a C++ compiler is being used. If so, complete the standard 678 C conditional started above. */ 679 #ifdef __cplusplus 680 } 681 #endif 682 683 #endif 684