42#include "ux_device_class_storage.h"
43#include "ux_device_stack.h"
49typedef enum : uint8_t {
101 buf[UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PERIPHERAL_TYPE] =
102 (UCHAR)storage->ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_type;
103 buf[UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_REMOVABLE_MEDIA] =
104 (UCHAR)storage->ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_removable_flag;
105 if (storage->ux_slave_class_storage_lun[lun].ux_slave_class_storage_media_type ==
106 UX_SLAVE_CLASS_STORAGE_MEDIA_CDROM) {
114 _ux_utility_memory_copy(buf + UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_VENDOR_INFORMATION,
115 storage->ux_slave_class_storage_vendor_id,
117 _ux_utility_memory_copy(buf + UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_ID,
118 storage->ux_slave_class_storage_product_id,
120 _ux_utility_memory_copy(buf + UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION,
121 storage->ux_slave_class_storage_product_rev,
171 _ux_utility_short_put_big_endian(buf, UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_SERIAL);
174 storage->ux_slave_class_storage_product_serial,
202#ifndef UX_DEVICE_STANDALONE
203 _ux_device_stack_endpoint_stall(endpoint_in);
205 UX_PARAMETER_NOT_USED(endpoint_in);
207 storage->ux_slave_class_storage_lun[lun].ux_slave_class_storage_request_sense_status =
211 storage->ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_FAILED;
238 UX_SLAVE_ENDPOINT* endpoint_in,
239 UX_SLAVE_TRANSFER* transfer_request,
240 ULONG inquiry_length)
242#ifdef UX_DEVICE_STANDALONE
243 UX_PARAMETER_NOT_USED(endpoint_in);
244 storage->ux_device_class_storage_state = UX_DEVICE_CLASS_STORAGE_STATE_TRANS_START;
245 storage->ux_device_class_storage_cmd_state = UX_DEVICE_CLASS_STORAGE_CMD_READ;
246 storage->ux_device_class_storage_transfer = transfer_request;
247 storage->ux_device_class_storage_device_length = inquiry_length;
248 storage->ux_device_class_storage_data_length = inquiry_length;
249 storage->ux_device_class_storage_data_count = 0;
251 if (inquiry_length != 0U) {
252 _ux_device_stack_transfer_request(transfer_request, inquiry_length, inquiry_length);
254 if (storage->ux_slave_class_storage_host_length != inquiry_length) {
255 storage->ux_slave_class_storage_csw_residue =
256 storage->ux_slave_class_storage_host_length - inquiry_length;
257 _ux_device_stack_endpoint_stall(endpoint_in);
289 UX_SLAVE_ENDPOINT* endpoint_in,
290 UX_SLAVE_ENDPOINT* endpoint_out,
293 UX_PARAMETER_NOT_USED(endpoint_out);
295 UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_STORAGE_INQUIRY,
300 UX_TRACE_DEVICE_CLASS_EVENTS,
304#ifndef UX_DEVICE_STANDALONE
306 if (storage->ux_slave_class_storage_host_length != 0U) {
307 if ((storage->ux_slave_class_storage_cbw_flags & (UCHAR)
k_inq_dir_in_bit) == 0U) {
308 _ux_device_stack_endpoint_stall(endpoint_out);
309 storage->ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR;
315 UX_SLAVE_TRANSFER* transfer_request = &endpoint_in->ux_slave_endpoint_transfer_request;
316 UCHAR* buf = transfer_request->ux_slave_transfer_request_data_pointer;
318 const UCHAR page = cbwcb[UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE];
319 ULONG inquiry_length = storage->ux_slave_class_storage_host_length;
321 _ux_utility_memory_set(buf,
323 UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH);
325 storage->ux_slave_class_storage_csw_status = UX_SLAVE_CLASS_STORAGE_CSW_PASSED;
327 ULONG response_length = 0U;
330 if (page != (UCHAR)UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_STANDARD) {
334 response_length = UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH;
335 }
else if (page == (UCHAR)UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_STANDARD) {
337 }
else if (page == (UCHAR)UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_SERIAL) {
343 if (inquiry_length > response_length) {
344 inquiry_length = response_length;
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
unsigned int UINT
ThreadX-compatible unsigned int (host stub).
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
static ULONG internal_inquiry_fill_vpd_pages(UCHAR *buf)
Fill the VPD page 0x00 (Supported VPD Pages) response.
static UINT internal_inquiry_reject(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in)
Reject an unsupported INQUIRY variant per the vendor contract.
UINT _ux_device_class_storage_inquiry(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb)
SCSI INQUIRY command handler (USBX storage class entry).
static void internal_inquiry_send(UX_SLAVE_CLASS_STORAGE *storage, UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_TRANSFER *transfer_request, ULONG inquiry_length)
Run the vendor transport tail: data IN + residue / IN stall.
static void internal_inquiry_fill_standard(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UCHAR *buf)
Fill the 36-byte standard INQUIRY response.
static ULONG internal_inquiry_fill_serial(UX_SLAVE_CLASS_STORAGE *storage, UCHAR *buf)
Fill the VPD page 0x80 (Unit Serial Number) response.
ra8_ux_inquiry_const_t
SCSI INQUIRY wire-format constants (SPC-4 sec 6.6).
@ k_inq_product_id_len
Product-identification field bytes.
@ k_inq_vpd_hdr_len
VPD header bytes before payload.
@ k_inq_vpd0_first_off
VPD page 0: first supported page.
@ k_inq_vpd0_second_off
VPD page 0: second supported page.
@ k_inq_serial_resp_len
VPD page 0x80 total response length.
@ k_inq_serial_len
Serial payload bytes (vendor size).
@ k_inq_format_spc
RESPONSE DATA FORMAT = 2 (SPC).
@ k_inq_vpd0_len
VPD page 0 total response length.
@ k_inq_addl_len_std
36-byte response: n - 5 = 31.
@ k_inq_format_cdrom
Vendor's CD-ROM format byte.
@ k_inq_version_spc2
VERSION = SPC-2 (SPC-4 table 142).
@ k_inq_sense_illegal
Sense key: ILLEGAL REQUEST.
@ k_inq_sense_ascq
ASCQ used by the vendor class.
@ k_inq_off_version
Standard response: VERSION byte.
@ k_inq_off_addl_len
Standard response: ADDITIONAL LENGTH.
@ k_inq_vpd0_count_off
VPD page 0: PAGE LENGTH byte.
@ k_inq_off_data_format
Standard response: RESPONSE FORMAT.
@ k_inq_vpd0_pages
Pages listed (0x00 + 0x80).
@ k_inq_cdb_evpd_bit
EVPD: vital-product-data request.
@ k_inq_cdb_off_evpd
CDB byte holding the EVPD flag.
@ k_inq_dir_in_bit
CBW bmCBWFlags: data IN direction.
@ k_inq_off_page_code
VPD response: PAGE CODE byte.
@ k_inq_sense_asc_field
ASC: INVALID FIELD IN PARAMETER.
@ k_inq_product_rev_len
Product-revision field bytes.
@ k_inq_vendor_id_len
Vendor-identification field bytes.