1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 13 /**************************************************************************/ 14 /**************************************************************************/ 15 /** */ 16 /** USBX Component */ 17 /** */ 18 /** Storage Class */ 19 /** */ 20 /**************************************************************************/ 21 /**************************************************************************/ 22 23 24 /**************************************************************************/ 25 /* */ 26 /* COMPONENT DEFINITION RELEASE */ 27 /* */ 28 /* ux_host_class_storage.h PORTABLE C */ 29 /* 6.3.0 */ 30 /* AUTHOR */ 31 /* */ 32 /* Chaoqiong Xiao, Microsoft Corporation */ 33 /* */ 34 /* DESCRIPTION */ 35 /* */ 36 /* This file contains all the header and extern functions used by the */ 37 /* USBX storage class. */ 38 /* */ 39 /* RELEASE HISTORY */ 40 /* */ 41 /* DATE NAME DESCRIPTION */ 42 /* */ 43 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 44 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 45 /* added option to disable FX */ 46 /* media integration, used UX_ */ 47 /* things instead of FX_ */ 48 /* things directly, used host */ 49 /* class extension pointer for */ 50 /* class specific structured */ 51 /* data, used UX prefix to */ 52 /* refer to TX symbols instead */ 53 /* of using them directly, */ 54 /* resulting in version 6.1 */ 55 /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ 56 /* added exFAT type define, */ 57 /* resulting in version 6.1.2 */ 58 /* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ 59 /* resulting in version 6.1.3 */ 60 /* 08-02-2021 Chaoqiong Xiao Modified comment(s), */ 61 /* added extern "C" keyword */ 62 /* for compatibility with C++, */ 63 /* resulting in version 6.1.8 */ 64 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */ 65 /* added standalone support, */ 66 /* resulting in version 6.1.10 */ 67 /* 10-31-2023 Chaoqiong Xiao Modified comment(s), */ 68 /* added error checks support, */ 69 /* resulting in version 6.3.0 */ 70 /* */ 71 /**************************************************************************/ 72 73 #ifndef UX_HOST_CLASS_STORAGE_H 74 #define UX_HOST_CLASS_STORAGE_H 75 76 /* Determine if a C++ compiler is being used. If so, ensure that standard 77 C is used to process the API information. */ 78 79 #ifdef __cplusplus 80 81 /* Yes, C++ compiler is present. Use standard C. */ 82 extern "C" { 83 84 #endif 85 86 87 /* Internal option: enable the basic USBX error checking. This define is typically used 88 while debugging application. */ 89 #if defined(UX_ENABLE_ERROR_CHECKING) && !defined(UX_HOST_CLASS_STORAGE_ENABLE_ERROR_CHECKING) 90 #define UX_HOST_CLASS_STORAGE_ENABLE_ERROR_CHECKING 91 #endif 92 93 94 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) && !defined(UX_HOST_STANDALONE) 95 /* Include the FileX API. */ 96 #include "fx_api.h" 97 98 /* Refine media stubs. */ 99 100 #ifndef UX_MEDIA 101 #define UX_MEDIA FX_MEDIA 102 #endif 103 104 #ifndef ux_media_id_get 105 #define ux_media_id_get(m) ((m)->fx_media_id) 106 #endif 107 108 #ifndef ux_media_id_set 109 #define ux_media_id_set(m,id) ((m)->fx_media_id=(id)) 110 #endif 111 112 #ifndef ux_media_driver_info_get 113 #define ux_media_driver_info_get(m) ((m)->fx_media_driver_info) 114 #endif 115 116 #ifndef ux_media_driver_info_set 117 #define ux_media_driver_info_set(m,i) ((m)->fx_media_driver_info=(VOID*)(i)) 118 #endif 119 120 #ifndef ux_media_reserved_for_user_get 121 #define ux_media_reserved_for_user_get(m) ((m)->fx_media_reserved_for_user) 122 #endif 123 124 #ifndef ux_media_reserved_for_user_set 125 #define ux_media_reserved_for_user_set(m,u) ((m)->fx_media_reserved_for_user=(ALIGN_TYPE)(u)) 126 #endif 127 128 #ifndef ux_media_open 129 #define ux_media_open fx_media_open 130 #endif 131 132 #ifndef ux_media_close 133 #define ux_media_close fx_media_close 134 #endif 135 #endif 136 137 /* Define User configurable Storage Class constants. */ 138 139 #ifndef UX_MAX_HOST_LUN 140 #define UX_MAX_HOST_LUN 1 141 #endif 142 143 #ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA 144 #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 1 145 #endif 146 147 #ifndef UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE 148 #define UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE (1024) 149 #endif 150 151 #ifndef UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE 152 #define UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE (1024) 153 #endif 154 155 #ifndef UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE 156 #define UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE 157 #endif 158 159 #if defined(UX_HOST_STANDALONE) && !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) 160 #define UX_HOST_CLASS_STORAGE_NO_FILEX 161 #endif 162 163 164 /* Define Storage Class constants. */ 165 166 #define UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY (200) 167 #define UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME (2000) 168 #define UX_HOST_CLASS_STORAGE_INSTANCE_SHUTDOWN_TIMER (10) 169 #define UX_HOST_CLASS_STORAGE_THREAD_PRIORITY_CLASS 20 170 #define UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT 10000 171 #define UX_HOST_CLASS_STORAGE_CBI_STATUS_TIMEOUT 3000 172 #define UX_HOST_CLASS_STORAGE_CLASS 8 173 #define UX_HOST_CLASS_STORAGE_SUBCLASS_RBC 1 174 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SFF8020 2 175 #define UX_HOST_CLASS_STORAGE_SUBCLASS_UFI 4 176 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SFF8070 5 177 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SCSI 6 178 179 #define UX_HOST_CLASS_STORAGE_CBW_SIZE 64 180 181 #define UX_HOST_CLASS_STORAGE_PROTOCOL_CBI 0 182 #define UX_HOST_CLASS_STORAGE_PROTOCOL_CB 1 183 #define UX_HOST_CLASS_STORAGE_PROTOCOL_BO 0x50 184 185 #define UX_HOST_CLASS_STORAGE_DATA_OUT 0 186 #define UX_HOST_CLASS_STORAGE_DATA_IN 0x80 187 188 #define UX_HOST_CLASS_STORAGE_CSW_PASSED 0 189 #define UX_HOST_CLASS_STORAGE_CSW_FAILED 1 190 #define UX_HOST_CLASS_STORAGE_CSW_PHASE_ERROR 2 191 192 #define UX_HOST_CLASS_STORAGE_CBW_SIGNATURE_MASK 0x43425355 193 #define UX_HOST_CLASS_STORAGE_CBW_TAG_MASK 0x55534243 194 195 #define UX_HOST_CLASS_STORAGE_MEDIA_NAME "usb disk" 196 197 #define UX_HOST_CLASS_STORAGE_MEDIA_REMOVABLE 0x80 198 #define UX_HOST_CLASS_STORAGE_MEDIA_UNKNOWN 0 199 #define UX_HOST_CLASS_STORAGE_MEDIA_KNOWN 1 200 201 #define UX_HOST_CLASS_STORAGE_MEDIA_FAT_DISK 0 202 #define UX_HOST_CLASS_STORAGE_MEDIA_CDROM 5 203 #define UX_HOST_CLASS_STORAGE_MEDIA_OPTICAL_DISK 7 204 #define UX_HOST_CLASS_STORAGE_MEDIA_IOMEGA_CLICK 0x55 205 206 #define UX_HOST_CLASS_STORAGE_RESET 0xff 207 #define UX_HOST_CLASS_STORAGE_GET_MAX_LUN 0xfe 208 209 #define UX_HOST_CLASS_STORAGE_TRANSPORT_ERROR 1 210 #define UX_HOST_CLASS_STORAGE_COMMAND_ERROR 2 211 #define UX_HOST_CLASS_STORAGE_SENSE_ERROR 3 212 213 #define UX_HOST_CLASS_STORAGE_SECTOR_SIZE_FAT 512 214 #define UX_HOST_CLASS_STORAGE_SECTOR_SIZE_OTHER 2048 215 216 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY 10 217 218 #define UX_HOST_CLASS_STORAGE_START_MEDIA 1 219 #define UX_HOST_CLASS_STORAGE_STOP_MEDIA 0 220 221 222 #define UX_HOST_CLASS_STORAGE_MEDIA_UNMOUNTED 0 223 #define UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED 1 224 225 /* Define Storage Class SCSI command constants. */ 226 227 #define UX_HOST_CLASS_STORAGE_SCSI_TEST_READY 0x00 228 #define UX_HOST_CLASS_STORAGE_SCSI_REQUEST_SENSE 0x03 229 #define UX_HOST_CLASS_STORAGE_SCSI_FORMAT 0x04 230 #define UX_HOST_CLASS_STORAGE_SCSI_INQUIRY 0x12 231 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT 0x1a 232 #define UX_HOST_CLASS_STORAGE_SCSI_START_STOP 0x1b 233 #define UX_HOST_CLASS_STORAGE_SCSI_READ_FORMAT_CAPACITY 0x23 234 #define UX_HOST_CLASS_STORAGE_SCSI_READ_CAPACITY 0x25 235 #define UX_HOST_CLASS_STORAGE_SCSI_READ16 0x28 236 #define UX_HOST_CLASS_STORAGE_SCSI_WRITE16 0x2a 237 #define UX_HOST_CLASS_STORAGE_SCSI_VERIFY 0x2f 238 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SELECT 0x55 239 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SENSE 0x5a 240 #define UX_HOST_CLASS_STORAGE_SCSI_READ32 0xa8 241 #define UX_HOST_CLASS_STORAGE_SCSI_WRITE32 0xaa 242 243 244 /* Define Storage Class SCSI command block wrapper constants. */ 245 246 #define UX_HOST_CLASS_STORAGE_CBW_SIGNATURE 0 247 #define UX_HOST_CLASS_STORAGE_CBW_TAG 4 248 #define UX_HOST_CLASS_STORAGE_CBW_DATA_LENGTH 8 249 #define UX_HOST_CLASS_STORAGE_CBW_FLAGS 12 250 #define UX_HOST_CLASS_STORAGE_CBW_LUN 13 251 #define UX_HOST_CLASS_STORAGE_CBW_CB_LENGTH 14 252 #define UX_HOST_CLASS_STORAGE_CBW_CB 15 253 254 255 /* Define Storage Class SCSI response status wrapper constants. */ 256 257 #define UX_HOST_CLASS_STORAGE_CSW_SIGNATURE 0 258 #define UX_HOST_CLASS_STORAGE_CSW_TAG 4 259 #define UX_HOST_CLASS_STORAGE_CSW_DATA_RESIDUE 8 260 #define UX_HOST_CLASS_STORAGE_CSW_STATUS 12 261 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH 13 262 263 264 /* Define Storage Class SCSI inquiry command constants. */ 265 266 #define UX_HOST_CLASS_STORAGE_INQUIRY_OPERATION 0 267 #define UX_HOST_CLASS_STORAGE_INQUIRY_LUN 1 268 #define UX_HOST_CLASS_STORAGE_INQUIRY_PAGE_CODE 2 269 #define UX_HOST_CLASS_STORAGE_INQUIRY_ALLOCATION_LENGTH 4 270 #define UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_UFI 12 271 #define UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC 06 272 273 274 /* Define Storage Class SCSI inquiry response constants. */ 275 276 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PERIPHERAL_TYPE 0 277 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_REMOVABLE_MEDIA 1 278 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_DATA_FORMAT 3 279 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_ADDITIONAL_LENGTH 4 280 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_VENDOR_INFORMATION 8 281 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_ID 16 282 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION 32 283 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH 36 284 285 286 /* Define Storage Class SCSI start/stop command constants. */ 287 288 #define UX_HOST_CLASS_STORAGE_START_STOP_OPERATION 0 289 #define UX_HOST_CLASS_STORAGE_START_STOP_LBUFLAGS 1 290 #define UX_HOST_CLASS_STORAGE_START_STOP_START_BIT 4 291 #define UX_HOST_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_UFI 12 292 #define UX_HOST_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_SBC 12 293 294 295 /* Define Storage Class SCSI mode sense command constants. */ 296 297 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_OPERATION 0 298 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_LUN 1 299 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_PC_PAGE_CODE 2 300 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH 7 301 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_UFI 12 302 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_SBC 12 303 304 /* Define Storage Class SCSI mode sense command constants. */ 305 306 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_MODE_DATA_LENGTH 0 307 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_MEDIUM_TYPE_CODE 2 308 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES_SHORT 2 309 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES 3 310 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES_WP 0x80 311 312 /* Define Storage Class SCSI request sense command constants. */ 313 314 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_OPERATION 0 315 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_LUN 1 316 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_ALLOCATION_LENGTH 4 317 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_UFI 12 318 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC 12 319 320 321 /* Define Storage Class request sense response constants. */ 322 323 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE 0 324 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_SENSE_KEY 2 325 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_INFORMATION 3 326 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ADD_LENGTH 7 327 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE 12 328 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE_QUALIFIER 13 329 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH 18 330 331 332 /* Define Storage Class read format command constants. */ 333 334 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_OPERATION 0 335 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_LUN 1 336 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_LBA 2 337 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_PARAMETER_LIST_LENGTH 7 338 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_COMMAND_LENGTH_UFI 12 339 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_COMMAND_LENGTH_SBC 10 340 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_RESPONSE_LENGTH 0xFC 341 342 /* Define Storage Class read capacity command constants. */ 343 344 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_OPERATION 0 345 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_LUN 1 346 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_LBA 2 347 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_UFI 12 348 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_SBC 10 349 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LENGTH 8 350 351 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_DATA_LBA 0 352 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_DATA_SECTOR_SIZE 4 353 354 355 /* Define Storage Class test unit read command constants. */ 356 357 #define UX_HOST_CLASS_STORAGE_TEST_READY_OPERATION 0 358 #define UX_HOST_CLASS_STORAGE_TEST_READY_LUN 1 359 #define UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_UFI 12 360 #define UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC 6 361 362 /* Define Storage Class SCSI read command constants. */ 363 364 #define UX_HOST_CLASS_STORAGE_READ_OPERATION 0 365 #define UX_HOST_CLASS_STORAGE_READ_LUN 1 366 #define UX_HOST_CLASS_STORAGE_READ_LBA 2 367 #define UX_HOST_CLASS_STORAGE_READ_TRANSFER_LENGTH 7 368 #define UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_UFI 12 369 #define UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC 10 370 371 372 /* Define Storage Class SCSI write command constants. */ 373 374 #define UX_HOST_CLASS_STORAGE_WRITE_OPERATION 0 375 #define UX_HOST_CLASS_STORAGE_WRITE_LUN 1 376 #define UX_HOST_CLASS_STORAGE_WRITE_LBA 2 377 #define UX_HOST_CLASS_STORAGE_WRITE_TRANSFER_LENGTH 7 378 #define UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_UFI 12 379 #define UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC 10 380 381 382 /* Define Storage Class SCSI sense key definition constants. */ 383 384 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_NO_SENSE 0x0 385 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_RECOVERED_ERROR 0x1 386 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_NOT_READY 0x2 387 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_MEDIUM_ERROR 0x3 388 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_HARDWARE_ERROR 0x4 389 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST 0x5 390 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION 0x6 391 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_DATA_PROTECT 0x7 392 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_BLANK_CHECK 0x8 393 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_ABORTED_COMMAND 0x0b 394 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_VOLUME_OVERFLOW 0x0d 395 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_MISCOMPARE 0x0e 396 397 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_READY 0x04 398 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_WRITE_PROTECTED 0x27 399 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_READY_TO_READY 0x28 400 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_PRESENT 0x3A 401 402 /* Convertion between sense status and sense key, ASC, ASCQ. */ 403 404 #define UX_HOST_CLASS_STORAGE_SENSE_STATUS(key,ascode,ascqualifier) (((key) << 16) | ((ascode) << 8) | (ascqualifier)) 405 #define UX_HOST_CLASS_STORAGE_SENSE_QUALIFIER(status) ((status) & 0xFF) 406 #define UX_HOST_CLASS_STORAGE_SENSE_CODE(status) (((status) >> 8) & 0xFF) 407 #define UX_HOST_CLASS_STORAGE_SENSE_KEY(status) (((status) >> 16) & 0xFF) 408 #define UX_HOST_CLASS_STORAGE_SENSE_ASCQ(status) UX_HOST_CLASS_STORAGE_SENSE_QUALIFIER(status) 409 #define UX_HOST_CLASS_STORAGE_SENSE_ASC(status) UX_HOST_CLASS_STORAGE_SENSE_CODE(status) 410 411 412 /* Define Mode Sense page codes. */ 413 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RWER_PAGE 0x01 414 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_FD_PAGE 0x05 415 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RBAC_PAGE 0x1B 416 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_TP_PAGE 0x1C 417 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_ALL_PAGE 0x3F 418 419 /* Define Mode Sense page codes response length . */ 420 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_HEADER_PAGE_LENGTH 0x08 421 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RWER_PAGE_LENGTH 0x0c 422 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_FD_PAGE_LENGTH 0x20 423 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RBAC_PAGE_LENGTH 0x0c 424 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_TP_PAGE_LENGTH 0x08 425 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_ALL_PAGE_LENGTH 0xC0 426 427 /* Define Storage Class useful error sense key/code constant. */ 428 429 #define UX_HOST_CLASS_STORAGE_ERROR_MEDIA_NOT_READ 0x023A00 430 431 432 /* Define Storage Class MS-DOS partition entry constants. */ 433 434 #define UX_HOST_CLASS_STORAGE_PARTITION_SIGNATURE 0xaa55 435 #define UX_HOST_CLASS_STORAGE_PARTITION_TABLE_START 446 436 437 #define UX_HOST_CLASS_STORAGE_PARTITION_BOOT_FLAG 0 438 #define UX_HOST_CLASS_STORAGE_PARTITION_START_HEAD 1 439 #define UX_HOST_CLASS_STORAGE_PARTITION_START_SECTOR 2 440 #define UX_HOST_CLASS_STORAGE_PARTITION_START_TRACK 3 441 #define UX_HOST_CLASS_STORAGE_PARTITION_TYPE 4 442 #define UX_HOST_CLASS_STORAGE_PARTITION_END_HEAD 5 443 #define UX_HOST_CLASS_STORAGE_PARTITION_END_SECTOR 6 444 #define UX_HOST_CLASS_STORAGE_PARTITION_END_TRACK 7 445 #define UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE 8 446 #define UX_HOST_CLASS_STORAGE_PARTITION_NUMBER_SECTORS 12 447 #define UX_HOST_CLASS_STORAGE_PARTITION_TABLE_SIZE 16 448 449 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_12 1 450 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16 4 451 #define UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED 5 452 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16L 6 453 #define UX_HOST_CLASS_STORAGE_PARTITION_EXFAT 7 454 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_1 0x0b 455 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_2 0x0c 456 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16_LBA_MAPPED 0x0e 457 #define UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED_LBA_MAPPED 0x0f 458 459 /* Define Storage Class instance structure. */ 460 461 #define UX_HOST_CLASS_STORAGE_CBW_LENGTH 31 462 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH 13 463 #define UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED 32 464 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH_ALIGNED 16 465 466 467 typedef struct UX_HOST_CLASS_STORAGE_STRUCT 468 { 469 470 struct UX_HOST_CLASS_STORAGE_STRUCT 471 *ux_host_class_storage_next_instance; 472 UX_HOST_CLASS *ux_host_class_storage_class; 473 UX_DEVICE *ux_host_class_storage_device; 474 UX_INTERFACE *ux_host_class_storage_interface; 475 UX_ENDPOINT *ux_host_class_storage_bulk_out_endpoint; 476 UX_ENDPOINT *ux_host_class_storage_bulk_in_endpoint; 477 UX_ENDPOINT *ux_host_class_storage_interrupt_endpoint; 478 UCHAR ux_host_class_storage_cbw[UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED]; 479 UCHAR ux_host_class_storage_saved_cbw[UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED]; 480 UCHAR ux_host_class_storage_csw[UX_HOST_CLASS_STORAGE_CSW_LENGTH_ALIGNED]; 481 UINT ux_host_class_storage_state; 482 UINT ux_host_class_storage_media_type; 483 UINT ux_host_class_storage_lun_removable_media_flags[UX_MAX_HOST_LUN]; 484 UINT ux_host_class_storage_write_protected_media; 485 UINT ux_host_class_storage_max_lun; 486 UINT ux_host_class_storage_lun; 487 UINT ux_host_class_storage_lun_types[UX_MAX_HOST_LUN]; 488 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX) 489 ULONG ux_host_class_storage_last_sector_number; 490 #endif 491 ULONG ux_host_class_storage_sector_size; 492 ULONG ux_host_class_storage_data_phase_length; 493 ULONG ux_host_class_storage_sense_code; 494 UCHAR *ux_host_class_storage_memory; 495 #if !defined(UX_HOST_STANDALONE) 496 UINT (*ux_host_class_storage_transport) (struct UX_HOST_CLASS_STORAGE_STRUCT *storage, UCHAR * data_pointer); 497 UX_SEMAPHORE ux_host_class_storage_semaphore; 498 #else 499 ULONG ux_host_class_storage_flags; 500 UINT ux_host_class_storage_status; 501 UCHAR *ux_host_class_storage_sense_memory; 502 503 /* State info for transport state machine. */ 504 UX_TRANSFER *ux_host_class_storage_trans; 505 UCHAR *ux_host_class_storage_trans_data; 506 UCHAR *ux_host_class_storage_trans_data_bak; 507 UCHAR ux_host_class_storage_trans_state; 508 UCHAR ux_host_class_storage_trans_stage; 509 UCHAR ux_host_class_storage_trans_retry; 510 UCHAR ux_host_class_storage_trans_status; 511 512 /* State info for media main state machine. */ 513 ULONG ux_host_class_storage_delay_start; 514 ULONG ux_host_class_storage_delay_ms; 515 UCHAR ux_host_class_storage_state_state; 516 UCHAR ux_host_class_storage_state_next; 517 UCHAR ux_host_class_storage_check_lun; 518 UCHAR ux_host_class_storage_op_state; 519 UCHAR ux_host_class_storage_dbg_state; 520 UCHAR ux_host_class_storage_dbg_rw_state; 521 UCHAR ux_host_class_storage_dbg_trans_state; 522 UCHAR ux_host_class_storage_dbg_trans_stage; 523 ULONG ux_host_class_storage_dbg_state_count; 524 ULONG ux_host_class_storage_dbg_rw_state_count; 525 ULONG ux_host_class_storage_dbg_trans_state_count; 526 527 #endif 528 } UX_HOST_CLASS_STORAGE; 529 530 #define UX_HOST_CLASS_STORAGE_FLAG_PROTECT (1ul << 0) 531 #define UX_HOST_CLASS_STORAGE_FLAG_LOCK (1ul << 1) 532 #define UX_HOST_CLASS_STORAGE_FLAG_CHECK_CURRENT (1ul << 2) 533 534 /* Read/write states. */ 535 536 #define UX_HOST_CLASS_STORAGE_RW_STATE_RESET(s) ((s) -> ux_host_class_storage_op_state = UX_STATE_RESET) 537 #define UX_HOST_CLASS_STORAGE_RW_STATE_IS_IDLE(s) ((s) -> ux_host_class_storage_op_state == UX_STATE_IDLE) 538 #define UX_HOST_CLASS_STORAGE_RW_STATE_IS_RESET(s) ((s) -> ux_host_class_storage_op_state == UX_STATE_RESET) 539 #define UX_HOST_CLASS_STORAGE_RW_IS_IDLE(s) (UX_HOST_CLASS_STORAGE_RW_STATE_IS_IDLE(s) || UX_HOST_CLASS_STORAGE_RW_STATE_IS_RESET(s)) 540 541 /* Main states. */ 542 543 #define UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_GET (UX_STATE_CLASS_STEP + 0) 544 #define UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_SAVE (UX_STATE_CLASS_STEP + 1) 545 #define UX_HOST_CLASS_STORAGE_STATE_CHECK_START (UX_STATE_CLASS_STEP + 2) 546 #define UX_HOST_CLASS_STORAGE_STATE_LOCK_WAIT (UX_STATE_CLASS_STEP + 3) 547 #define UX_HOST_CLASS_STORAGE_STATE_TEST_READY (UX_STATE_CLASS_STEP + 4) 548 #define UX_HOST_CLASS_STORAGE_STATE_TEST_CHECK (UX_STATE_CLASS_STEP + 5) 549 #define UX_HOST_CLASS_STORAGE_STATE_INQUIRY (UX_STATE_CLASS_STEP + 6) 550 #define UX_HOST_CLASS_STORAGE_STATE_INQUIRY_SAVE (UX_STATE_CLASS_STEP + 7) 551 #define UX_HOST_CLASS_STORAGE_STATE_FORMAT_CAP_GET (UX_STATE_CLASS_STEP + 8) 552 #define UX_HOST_CLASS_STORAGE_STATE_FORMAT_CAP_SAVE (UX_STATE_CLASS_STEP + 9) 553 #define UX_HOST_CLASS_STORAGE_STATE_CAP_GET (UX_STATE_CLASS_STEP + 10) 554 #define UX_HOST_CLASS_STORAGE_STATE_CAP_SAVE (UX_STATE_CLASS_STEP + 11) 555 #define UX_HOST_CLASS_STORAGE_STATE_NEXT_LUN (UX_STATE_CLASS_STEP + 12) 556 #define UX_HOST_CLASS_STORAGE_STATE_DELAY_WAIT (UX_STATE_CLASS_STEP + 13) 557 #define UX_HOST_CLASS_STORAGE_STATE_TRANSPORT (UX_STATE_CLASS_STEP + 14) 558 #define UX_HOST_CLASS_STORAGE_STATE_TRANSFER (UX_STATE_CLASS_STEP + 15) 559 #define UX_HOST_CLASS_STORAGE_STATE_CHECK_DONE (UX_STATE_CLASS_STEP + 16) 560 561 /* Transport states. */ 562 563 #define UX_HOST_CLASS_STORAGE_TRANS_STATE_RESET(s) do { \ 564 (s) -> ux_host_class_storage_trans_state = UX_STATE_RESET; \ 565 (s) -> ux_host_class_storage_trans_data = UX_NULL; \ 566 } while(0) \ 567 568 #define UX_HOST_CLASS_STORAGE_TRANS_CBW (UX_STATE_CLASS_STEP + 0) 569 #define UX_HOST_CLASS_STORAGE_TRANS_IN_NEXT (UX_STATE_CLASS_STEP + 1) 570 #define UX_HOST_CLASS_STORAGE_TRANS_OUT_NEXT (UX_STATE_CLASS_STEP + 2) 571 #define UX_HOST_CLASS_STORAGE_TRANS_CSW (UX_STATE_CLASS_STEP + 3) 572 #define UX_HOST_CLASS_STORAGE_TRANS_REQ_SENSE (UX_STATE_CLASS_STEP + 4) 573 #define UX_HOST_CLASS_STORAGE_TRANS_WAIT (UX_STATE_CLASS_STEP + 5) 574 #define UX_HOST_CLASS_STORAGE_TRANS_STATUS (UX_STATE_CLASS_STEP + 6) 575 #define UX_HOST_CLASS_STORAGE_TRANS_MS_RESET (UX_STATE_CLASS_STEP + 7) 576 #define UX_HOST_CLASS_STORAGE_TRANS_EP_RESET (UX_STATE_CLASS_STEP + 8) 577 #define UX_HOST_CLASS_STORAGE_TRANS_RESET_NEXT (UX_STATE_CLASS_STEP + 9) 578 579 #define UX_HOST_CLASS_STORAGE_STAGE_CBW (0x00u) 580 #define UX_HOST_CLASS_STORAGE_STAGE_DATA (0x01u) 581 #define UX_HOST_CLASS_STORAGE_STAGE_CSW (0x02u) 582 #define UX_HOST_CLASS_STORAGE_STAGE_MS_RESET (0x04u) 583 #define UX_HOST_CLASS_STORAGE_STAGE_EP_RESET (0x08u) 584 585 typedef struct UX_HOST_CLASS_STORAGE_EXT_STRUCT 586 { 587 #if !defined(UX_HOST_STANDALONE) 588 UX_THREAD ux_host_class_thread; 589 CHAR ux_host_class_thread_stack[UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE]; 590 #else 591 ALIGN_TYPE reserved; 592 #endif 593 } UX_HOST_CLASS_STORAGE_EXT; 594 595 596 /* Define Host Storage Class Media structure. */ 597 598 typedef struct UX_HOST_CLASS_STORAGE_MEDIA_STRUCT 599 { 600 601 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) 602 UX_MEDIA ux_host_class_storage_media; 603 ULONG ux_host_class_storage_media_partition_start; 604 VOID *ux_host_class_storage_media_memory; 605 ULONG ux_host_class_storage_media_status; 606 ULONG ux_host_class_storage_media_lun; 607 ULONG ux_host_class_storage_media_sector_size; 608 #else 609 struct UX_HOST_CLASS_STORAGE_STRUCT 610 *ux_host_class_storage_media_storage; 611 ULONG ux_host_class_storage_media_number_sectors; 612 USHORT ux_host_class_storage_media_sector_size; 613 UCHAR ux_host_class_storage_media_lun; 614 UCHAR ux_host_class_storage_media_status; 615 #endif 616 617 } UX_HOST_CLASS_STORAGE_MEDIA; 618 619 620 /* Define Storage Class function prototypes. */ 621 622 UINT _ux_host_class_storage_activate(UX_HOST_CLASS_COMMAND *command); 623 VOID _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT flags, 624 ULONG data_transfer_length, UINT command_length); 625 UINT _ux_host_class_storage_configure(UX_HOST_CLASS_STORAGE *storage); 626 UINT _ux_host_class_storage_deactivate(UX_HOST_CLASS_COMMAND *command); 627 UINT _ux_host_class_storage_device_initialize(UX_HOST_CLASS_STORAGE *storage); 628 UINT _ux_host_class_storage_device_reset(UX_HOST_CLASS_STORAGE *storage); 629 UINT _ux_host_class_storage_device_support_check(UX_HOST_CLASS_STORAGE *storage); 630 631 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) 632 VOID _ux_host_class_storage_driver_entry(UX_MEDIA *media); 633 #endif 634 635 UINT _ux_host_class_storage_endpoints_get(UX_HOST_CLASS_STORAGE *storage); 636 UINT _ux_host_class_storage_entry(UX_HOST_CLASS_COMMAND *command); 637 UINT _ux_host_class_storage_max_lun_get(UX_HOST_CLASS_STORAGE *storage); 638 UINT _ux_host_class_storage_media_capacity_get(UX_HOST_CLASS_STORAGE *storage); 639 UINT _ux_host_class_storage_media_characteristics_get(UX_HOST_CLASS_STORAGE *storage); 640 UINT _ux_host_class_storage_media_format_capacity_get(UX_HOST_CLASS_STORAGE *storage); 641 UINT _ux_host_class_storage_media_mount(UX_HOST_CLASS_STORAGE *storage, ULONG sector); 642 UINT _ux_host_class_storage_media_open(UX_HOST_CLASS_STORAGE *storage, ULONG hidden_sectors); 643 UINT _ux_host_class_storage_media_protection_check(UX_HOST_CLASS_STORAGE *storage); 644 UINT _ux_host_class_storage_media_read(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start, 645 ULONG sector_count, UCHAR *data_pointer); 646 UINT _ux_host_class_storage_media_recovery_sense_get(UX_HOST_CLASS_STORAGE *storage); 647 UINT _ux_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start, 648 ULONG sector_count, UCHAR *data_pointer); 649 UINT _ux_host_class_storage_partition_read(UX_HOST_CLASS_STORAGE *storage, UCHAR *sector_memory, ULONG sector); 650 UINT _ux_host_class_storage_request_sense(UX_HOST_CLASS_STORAGE *storage); 651 UINT _ux_host_class_storage_sense_code_translate(UX_HOST_CLASS_STORAGE *storage, UINT status); 652 UINT _ux_host_class_storage_start_stop(UX_HOST_CLASS_STORAGE *storage, 653 ULONG start_stop_signal); 654 VOID _ux_host_class_storage_thread_entry(ULONG class_address); 655 UINT _ux_host_class_storage_transport(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer); 656 UINT _ux_host_class_storage_transport_bo(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer); 657 UINT _ux_host_class_storage_transport_cb(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer); 658 UINT _ux_host_class_storage_transport_cbi(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer); 659 UINT _ux_host_class_storage_unit_ready_test(UX_HOST_CLASS_STORAGE *storage); 660 661 UINT _ux_host_class_storage_media_get(UX_HOST_CLASS_STORAGE *storage, ULONG media_lun, UX_HOST_CLASS_STORAGE_MEDIA **storage_media); 662 UINT _ux_host_class_storage_media_lock(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG wait); 663 664 #if defined(UX_HOST_STANDALONE) 665 UINT _ux_host_class_storage_lock(UX_HOST_CLASS_STORAGE *storage, ULONG wait); 666 UINT _uxe_host_class_storage_lock(UX_HOST_CLASS_STORAGE *storage, ULONG wait); 667 #define _ux_host_class_storage_unlock(s) do { (s) -> ux_host_class_storage_flags &= ~UX_HOST_CLASS_STORAGE_FLAG_LOCK; } while(0) 668 #define _uxe_host_class_storage_unlock(s) do { if((s) != UX_NULL) (s) -> ux_host_class_storage_flags &= ~UX_HOST_CLASS_STORAGE_FLAG_LOCK; } while(0) 669 #define _ux_host_class_storage_media_unlock(m) _ux_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage) 670 #define _uxe_host_class_storage_media_unlock(m) do { if((m) != UX_NULL) _uxe_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage); } while(0) 671 #else 672 #define _ux_host_class_storage_lock(s,w) _ux_host_semaphore_get(&(s) -> ux_host_class_storage_semaphore, (w)) 673 #define _uxe_host_class_storage_lock(s,w) (((s) != UX_NULL) ? _ux_host_semaphore_get(&(s) -> ux_host_class_storage_semaphore, (w)) : UX_INVALID_PARAMETER) 674 #define _ux_host_class_storage_unlock(s) _ux_host_semaphore_put(&(s) -> ux_host_class_storage_semaphore) 675 #define _uxe_host_class_storage_unlock(s) (((s) != UX_NULL) ? _ux_host_semaphore_put(&(s) -> ux_host_class_storage_semaphore) : UX_INVALID_PARAMETER) 676 #define _ux_host_class_storage_media_unlock(m) _ux_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage) 677 #define _uxe_host_class_storage_media_unlock(m) (((m) != UX_NULL) ? _uxe_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage) : UX_INVALID_PARAMETER) 678 #endif 679 #define _ux_host_class_storage_max_lun(s) ((s) -> ux_host_class_storage_max_lun) 680 #define _ux_host_class_storage_lun(s) ((s) -> ux_host_class_storage_lun) 681 #define _ux_host_class_storage_lun_select(s,l) do { (s) -> ux_host_class_storage_lun = (l); } while(0) 682 #define _uxe_host_class_storage_lun_select(s,l) do { if ((s) != UX_NULL) (s) -> ux_host_class_storage_lun = (l); } while(0) 683 #define _ux_host_class_storage_sense_status(s) ((s) -> ux_host_class_storage_sense_code) 684 685 UINT _ux_host_class_storage_media_check(UX_HOST_CLASS_STORAGE *storage); 686 687 UINT _ux_host_class_storage_tasks_run(UX_HOST_CLASS *storage_class); 688 UINT _ux_host_class_storage_transport_run(UX_HOST_CLASS_STORAGE *storage); 689 UINT _ux_host_class_storage_check_run(UX_HOST_CLASS_STORAGE *storage); 690 UINT _ux_host_class_storage_read_write_run(UX_HOST_CLASS_STORAGE *storage, 691 ULONG read_write, ULONG sector_start, ULONG sector_count, UCHAR *data_pointer); 692 693 694 UINT _uxe_host_class_storage_media_read(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start, 695 ULONG sector_count, UCHAR *data_pointer); 696 UINT _uxe_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start, 697 ULONG sector_count, UCHAR *data_pointer); 698 699 UINT _uxe_host_class_storage_media_check(UX_HOST_CLASS_STORAGE *storage); 700 701 UINT _uxe_host_class_storage_media_get(UX_HOST_CLASS_STORAGE *storage, ULONG media_lun, UX_HOST_CLASS_STORAGE_MEDIA **storage_media); 702 UINT _uxe_host_class_storage_media_lock(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG wait); 703 704 705 /* Define Storage Class API prototypes. */ 706 707 #define ux_host_class_storage_entry _ux_host_class_storage_entry 708 709 #define ux_host_class_storage_sense_status _ux_host_class_storage_sense_status 710 711 #if defined(UX_HOST_CLASS_STORAGE_ENABLE_ERROR_CHECKING) 712 713 #define ux_host_class_storage_lock _uxe_host_class_storage_lock 714 #define ux_host_class_storage_unlock _uxe_host_class_storage_unlock 715 #define ux_host_class_storage_lun_select _uxe_host_class_storage_lun_select 716 717 #define ux_host_class_storage_media_read _uxe_host_class_storage_media_read 718 #define ux_host_class_storage_media_write _uxe_host_class_storage_media_write 719 720 #define ux_host_class_storage_media_get _uxe_host_class_storage_media_get 721 #define ux_host_class_storage_media_lock _uxe_host_class_storage_media_lock 722 #define ux_host_class_storage_media_unlock _uxe_host_class_storage_media_unlock 723 724 #define ux_host_class_storage_media_check _uxe_host_class_storage_media_check 725 726 727 #else 728 729 #define ux_host_class_storage_lock _ux_host_class_storage_lock 730 #define ux_host_class_storage_unlock _ux_host_class_storage_unlock 731 #define ux_host_class_storage_lun_select _ux_host_class_storage_lun_select 732 733 #define ux_host_class_storage_media_read _ux_host_class_storage_media_read 734 #define ux_host_class_storage_media_write _ux_host_class_storage_media_write 735 736 #define ux_host_class_storage_media_get _ux_host_class_storage_media_get 737 #define ux_host_class_storage_media_lock _ux_host_class_storage_media_lock 738 #define ux_host_class_storage_media_unlock _ux_host_class_storage_media_unlock 739 740 #define ux_host_class_storage_media_check _ux_host_class_storage_media_check 741 742 #endif 743 744 745 /* Determine if a C++ compiler is being used. If so, complete the standard 746 C conditional started above. */ 747 #ifdef __cplusplus 748 } 749 #endif 750 751 #endif 752