1 /* 2 * Copyright (c) 2023 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <zephyr/sys/util.h> 8 9 #ifndef ZEPHYR_INCLUDE_USBD_MSC_SCSI_H_ 10 #define ZEPHYR_INCLUDE_USBD_MSC_SCSI_H_ 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /* SAM-6 5.3.1 Status codes 17 * Table 44 – Status codes 18 */ 19 enum scsi_status_code { 20 GOOD = 0x00, 21 CHECK_CONDITION = 0x02, 22 CONDITION_MET = 0x04, 23 BUSY = 0x08, 24 RESERVATION_CONFLICT = 0x18, 25 TASK_SET_FULL = 0x28, 26 ACA_ACTIVE = 0x30, 27 TASK_ABORTED = 0x40, 28 }; 29 30 /* SPC-5 4.4.8 Sense key and additional sense code definitions 31 * Table 49 — Sense key descriptions 32 */ 33 enum scsi_sense_key { 34 NO_SENSE = 0x0, 35 RECOVERED_ERROR = 0x1, 36 NOT_READY = 0x2, 37 MEDIUM_ERROR = 0x3, 38 HARDWARE_ERROR = 0x4, 39 ILLEGAL_REQUEST = 0x5, 40 UNIT_ATTENTION = 0x6, 41 DATA_PROTECT = 0x7, 42 BLANK_CHECK = 0x8, 43 VENDOR_SPECIFIC = 0x9, 44 COPY_ABORTED = 0xA, 45 ABORTED_COMMAND = 0xB, 46 /* 0xC is Reserved */ 47 VOLUME_OVERFLOW = 0xD, 48 MISCOMPARE = 0xE, 49 COMPLETED = 0xF, 50 }; 51 52 /* SPC-5 Table F.1 — ASC and ASCQ assignments 53 * ASC is upper 8 bits, ASCQ on lower 8 bits 54 */ 55 enum scsi_additional_sense_code { 56 NO_ADDITIONAL_SENSE_INFORMATION = 0x0000, 57 LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE = 0x2100, 58 INVALID_FIELD_IN_CDB = 0x2400, 59 MEDIUM_NOT_PRESENT = 0x3A00, 60 MEDIUM_REMOVAL_PREVENTED = 0x5302, 61 WRITE_ERROR = 0x0C00, 62 }; 63 64 struct scsi_ctx { 65 const char *disk; 66 const char *vendor; 67 const char *product; 68 const char *revision; 69 size_t (*read_cb)(struct scsi_ctx *ctx, 70 uint8_t buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE]); 71 size_t (*write_cb)(struct scsi_ctx *ctx, const uint8_t *buf, size_t length); 72 size_t remaining_data; 73 uint32_t lba; 74 uint32_t sector_count; 75 uint32_t sector_size; 76 enum scsi_status_code status; 77 enum scsi_sense_key sense_key; 78 enum scsi_additional_sense_code asc; 79 bool prevent_removal : 1; 80 bool medium_loaded : 1; 81 bool cmd_is_data_read : 1; 82 bool cmd_is_data_write : 1; 83 }; 84 85 void scsi_init(struct scsi_ctx *ctx, const char *disk, const char *vendor, 86 const char *product, const char *revision); 87 void scsi_reset(struct scsi_ctx *ctx); 88 int scsi_usb_boot_cmd_len(const uint8_t *cb, int len); 89 size_t scsi_cmd(struct scsi_ctx *ctx, const uint8_t *cb, int len, 90 uint8_t data_in_buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE]); 91 92 bool scsi_cmd_is_data_read(struct scsi_ctx *ctx); 93 bool scsi_cmd_is_data_write(struct scsi_ctx *ctx); 94 size_t scsi_cmd_remaining_data_len(struct scsi_ctx *ctx); 95 size_t scsi_read_data(struct scsi_ctx *ctx, 96 uint8_t data_in_buf[static CONFIG_USBD_MSC_SCSI_BUFFER_SIZE]); 97 size_t scsi_write_data(struct scsi_ctx *ctx, const uint8_t *buf, size_t length); 98 99 enum scsi_status_code scsi_cmd_get_status(struct scsi_ctx *ctx); 100 101 #ifdef __cplusplus 102 } 103 #endif 104 105 #endif /* ZEPHYR_INCLUDE_USBD_MSC_SCSI_H_ */ 106