ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ux_device_class_storage_inquiry.c File Reference

SPC-correct SCSI INQUIRY override for the USBX device storage class. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ux_api.h"
#include "ux_device_class_storage.h"
#include "ux_device_stack.h"
Include dependency graph for ux_device_class_storage_inquiry.c:

Go to the source code of this file.

Macros

#define UX_SOURCE_CODE

Enumerations

enum  ra8_ux_inquiry_const_t : uint8_t {
  k_inq_cdb_off_evpd = 1U ,
  k_inq_cdb_evpd_bit = 0x01U ,
  k_inq_off_page_code = 1U ,
  k_inq_off_version = 2U ,
  k_inq_off_data_format = 3U ,
  k_inq_off_addl_len = 4U ,
  k_inq_version_spc2 = 0x04U ,
  k_inq_format_spc = 0x02U ,
  k_inq_format_cdrom = 0x32U ,
  k_inq_addl_len_std = 0x1FU ,
  k_inq_vpd0_count_off = 3U ,
  k_inq_vpd0_first_off = 4U ,
  k_inq_vpd0_second_off = 5U ,
  k_inq_vpd0_pages = 2U ,
  k_inq_vpd0_len = 6U ,
  k_inq_vpd_hdr_len = 4U ,
  k_inq_serial_len = 20U ,
  k_inq_vendor_id_len = 8U ,
  k_inq_product_id_len = 16U ,
  k_inq_product_rev_len = 4U ,
  k_inq_serial_resp_len = 24U ,
  k_inq_dir_in_bit = 0x80U ,
  k_inq_sense_illegal = 0x05U ,
  k_inq_sense_asc_field = 0x26U ,
  k_inq_sense_ascq = 0x01U
}
 SCSI INQUIRY wire-format constants (SPC-4 sec 6.6). More...

Functions

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_vpd_pages (UCHAR *buf)
 Fill the VPD page 0x00 (Supported VPD Pages) response.
static ULONG internal_inquiry_fill_serial (UX_SLAVE_CLASS_STORAGE *storage, UCHAR *buf)
 Fill the VPD page 0x80 (Unit Serial Number) 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.
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.
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).

Detailed Description

SPC-correct SCSI INQUIRY override for the USBX device storage class.

Tag
[Ring 4 / PORT] {World: S}

First-party replacement for the vendored ux_device_class_storage_inquiry.c (excluded from the build in cmake/usbx.cmake). The vendor implementation has two defects that macOS's SCSI layer rejects (observed on a real EK-RA8D2 against a Mac host: three standard INQUIRYs, then Bulk-Only Mass Storage Reset, then the device is abandoned – no block device is created):

  1. It reports RESPONSE DATA FORMAT = 0 (SCSI-1 era) and VERSION = 0 in the standard INQUIRY data. SPC requires format 2; macOS refuses the device, Linux tolerates it.
  2. It ignores the EVPD bit (CDB byte 1 bit 0) and switches on the PAGE CODE byte alone, so a Supported-VPD-Pages request (EVPD=1, page 0x00) is answered with standard INQUIRY bytes.

This override keys on EVPD properly (standard data, VPD page 0x00 supported-pages list, VPD page 0x80 unit serial from the class instance), reports VERSION = SPC-2 / RESPONSE DATA FORMAT = 2, and keeps the vendor's transport behaviour (direction check, residue + IN-stall on short host length, CSW status codes) byte-for-byte.

Author
Brighton Sikarskie
Date
2026-06-12
Since
0.1.0

Definition in file ux_device_class_storage_inquiry.c.

Macro Definition Documentation

◆ UX_SOURCE_CODE

#define UX_SOURCE_CODE

Definition at line 36 of file ux_device_class_storage_inquiry.c.

Enumeration Type Documentation

◆ ra8_ux_inquiry_const_t

enum ra8_ux_inquiry_const_t : uint8_t

SCSI INQUIRY wire-format constants (SPC-4 sec 6.6).

Enumerator
k_inq_cdb_off_evpd 

CDB byte holding the EVPD flag.

k_inq_cdb_evpd_bit 

EVPD: vital-product-data request.

k_inq_off_page_code 

VPD response: PAGE CODE byte.

k_inq_off_version 

Standard response: VERSION byte.

k_inq_off_data_format 

Standard response: RESPONSE FORMAT.

k_inq_off_addl_len 

Standard response: ADDITIONAL LENGTH.

k_inq_version_spc2 

VERSION = SPC-2 (SPC-4 table 142).

k_inq_format_spc 

RESPONSE DATA FORMAT = 2 (SPC).

k_inq_format_cdrom 

Vendor's CD-ROM format byte.

k_inq_addl_len_std 

36-byte response: n - 5 = 31.

k_inq_vpd0_count_off 

VPD page 0: PAGE LENGTH byte.

k_inq_vpd0_first_off 

VPD page 0: first supported page.

k_inq_vpd0_second_off 

VPD page 0: second supported page.

k_inq_vpd0_pages 

Pages listed (0x00 + 0x80).

k_inq_vpd0_len 

VPD page 0 total response length.

k_inq_vpd_hdr_len 

VPD header bytes before payload.

k_inq_serial_len 

Serial payload bytes (vendor size).

k_inq_vendor_id_len 

Vendor-identification field bytes.

k_inq_product_id_len 

Product-identification field bytes.

k_inq_product_rev_len 

Product-revision field bytes.

k_inq_serial_resp_len 

VPD page 0x80 total response length.

k_inq_dir_in_bit 

CBW bmCBWFlags: data IN direction.

k_inq_sense_illegal 

Sense key: ILLEGAL REQUEST.

k_inq_sense_asc_field 

ASC: INVALID FIELD IN PARAMETER.

k_inq_sense_ascq 

ASCQ used by the vendor class.

Definition at line 49 of file ux_device_class_storage_inquiry.c.

Function Documentation

◆ _ux_device_class_storage_inquiry()

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).

Drop-in replacement for the vendored handler; see the file header for the behavioural differences. Dispatches on the EVPD bit and PAGE CODE, fills the response, then runs the vendor's transport tail (clamp to host allocation length, data IN, residue + IN stall when the host asked for more than was returned).

Parameters
[in,out]storageStorage class instance.
[in]lunLogical unit the host addressed.
[in]endpoint_inBulk-IN endpoint.
[in]endpoint_outBulk-OUT endpoint (direction check only).
[in]cbwcbCDB bytes from the CBW.
Returns
Completion status.
Return values
UX_SUCCESSThe response (possibly zero-length) was queued.
UX_ERRORThe command was rejected (sense data latched).
Precondition
Called by the storage class command dispatcher.
cbwcb points at a 6-byte INQUIRY CDB.
Postcondition
On success the data phase is queued and CSW is PASSED.
On rejection the IN endpoint is stalled and CSW is FAILED.
Note
Non-standalone (ThreadX) build path; mirrors vendor 6.3.0.
Since
0.1.0

Definition at line 287 of file ux_device_class_storage_inquiry.c.

References internal_inquiry_fill_serial(), internal_inquiry_fill_standard(), internal_inquiry_fill_vpd_pages(), internal_inquiry_reject(), internal_inquiry_send(), k_inq_cdb_evpd_bit, k_inq_cdb_off_evpd, k_inq_dir_in_bit, and k_inq_serial_resp_len.

◆ internal_inquiry_fill_serial()

ULONG internal_inquiry_fill_serial ( UX_SLAVE_CLASS_STORAGE * storage,
UCHAR * buf )
static

Fill the VPD page 0x80 (Unit Serial Number) response.

Byte-for-byte the vendor serial branch: big-endian page code, 20-byte length, then the class instance's product serial.

Parameters
[in]storageStorage class instance.
[out]bufResponse buffer (>= 24 bytes, pre-zeroed).
Returns
Response length in bytes.
Return values
24Always (4-byte header + 20 serial bytes).
Precondition
buf was zeroed.
The class instance carries a product serial string.
Postcondition
buf holds the unit-serial VPD page.
No class state is modified.
Note
Pure data marshalling; no transport side effects.
Since
0.1.0

Definition at line 169 of file ux_device_class_storage_inquiry.c.

References k_inq_off_version, k_inq_serial_len, k_inq_serial_resp_len, k_inq_vpd_hdr_len, and RA8_INTERNAL.

Referenced by _ux_device_class_storage_inquiry().

◆ internal_inquiry_fill_standard()

void internal_inquiry_fill_standard ( UX_SLAVE_CLASS_STORAGE * storage,
ULONG lun,
UCHAR * buf )
static

Fill the 36-byte standard INQUIRY response.

Mirrors the vendor data (peripheral type, removable flag, vendor/product/revision strings from the class instance) and fixes the two SPC fields macOS checks: VERSION = SPC-2 and RESPONSE DATA FORMAT = 2. The CD-ROM media type keeps the vendor's special format (0x32) and additional-length (0x5B) values.

Parameters
[in]storageStorage class instance.
[in]lunLogical unit the host addressed.
[out]bufResponse buffer (>= 36 bytes, pre-zeroed).
Precondition
buf was zeroed for the full standard response length.
lun indexes a configured LUN slot.
Postcondition
buf holds the full standard INQUIRY data.
No class state is modified.
Note
Pure data marshalling; no transport side effects.
Since
0.1.0

Definition at line 99 of file ux_device_class_storage_inquiry.c.

References k_inq_addl_len_std, k_inq_format_cdrom, k_inq_format_spc, k_inq_off_addl_len, k_inq_off_data_format, k_inq_off_version, k_inq_product_id_len, k_inq_product_rev_len, k_inq_vendor_id_len, and k_inq_version_spc2.

Referenced by _ux_device_class_storage_inquiry().

◆ internal_inquiry_fill_vpd_pages()

ULONG internal_inquiry_fill_vpd_pages ( UCHAR * buf)
static

Fill the VPD page 0x00 (Supported VPD Pages) response.

Lists the two pages this device serves: 0x00 (this list) and 0x80 (unit serial number). SPC-4 sec 7.8.15.

Parameters
[out]bufResponse buffer (>= 6 bytes, pre-zeroed).
Returns
Response length in bytes.
Return values
6Always (header + two page codes).
Precondition
buf was zeroed.
Caller clamps the host allocation length afterwards.
Postcondition
buf holds the supported-pages list.
No class state is modified.
Note
Pure data marshalling; no transport side effects.
Since
0.1.0

Definition at line 142 of file ux_device_class_storage_inquiry.c.

References k_inq_off_page_code, k_inq_vpd0_count_off, k_inq_vpd0_first_off, k_inq_vpd0_len, k_inq_vpd0_pages, k_inq_vpd0_second_off, and RA8_INTERNAL.

Referenced by _ux_device_class_storage_inquiry().

◆ internal_inquiry_reject()

UINT internal_inquiry_reject ( UX_SLAVE_CLASS_STORAGE * storage,
ULONG lun,
UX_SLAVE_ENDPOINT * endpoint_in )
static

Reject an unsupported INQUIRY variant per the vendor contract.

Stalls the IN endpoint, records ILLEGAL REQUEST sense data for the addressed LUN, and fails the CSW – identical to the vendor default branch so REQUEST SENSE keeps reporting the same codes.

Parameters
[in,out]storageStorage class instance.
[in]lunLogical unit the host addressed.
[in]endpoint_inBulk-IN endpoint to stall.
Returns
UX_ERROR always.
Return values
UX_ERRORThe command was rejected.
Precondition
The CBW for this command has been parsed.
lun indexes a configured LUN slot.
Postcondition
The IN endpoint is stalled and sense data is latched.
The CSW status is FAILED.
Note
Mirrors the vendored default-branch behaviour exactly.
Since
0.1.0

Definition at line 200 of file ux_device_class_storage_inquiry.c.

References k_inq_sense_asc_field, k_inq_sense_ascq, and k_inq_sense_illegal.

Referenced by _ux_device_class_storage_inquiry().

◆ internal_inquiry_send()

void internal_inquiry_send ( UX_SLAVE_CLASS_STORAGE * storage,
UX_SLAVE_ENDPOINT * endpoint_in,
UX_SLAVE_TRANSFER * transfer_request,
ULONG inquiry_length )
static

Run the vendor transport tail: data IN + residue / IN stall.

Queues the clamped response on the bulk-IN endpoint and, when the host asked for more bytes than were returned, records the CSW residue and stalls IN – byte-for-byte the vendored behaviour. The standalone build variant instead primes the storage state machine for its polled transfer path.

Parameters
[in,out]storageStorage class instance.
[in]endpoint_inBulk-IN endpoint.
[in,out]transfer_requestIN transfer carrying the response.
[in]inquiry_lengthClamped response length to send.
Precondition
The response bytes are already in the transfer buffer.
The CSW status for this command is already set.
Postcondition
The data phase is queued (or primed, standalone builds).
Residue/stall recorded when the host length was larger.
Note
Mirrors the vendored transport tail exactly.
Since
0.1.0

Definition at line 237 of file ux_device_class_storage_inquiry.c.

References RA8_INTERNAL.

Referenced by _ux_device_class_storage_inquiry().