Skip to content

Commit 29c2af7

Browse files
authored
Merge pull request #3172 from hathach/msc-inquiry2-cb
add tud_msc_inquiry2_cb() for full inquiry response
2 parents 5ce3e3b + e9a78c5 commit 29c2af7

File tree

8 files changed

+100
-58
lines changed

8 files changed

+100
-58
lines changed

examples/device/cdc_msc/src/msc_disk.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,20 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = {
116116
README_CONTENTS
117117
};
118118

119-
// Invoked when received SCSI_CMD_INQUIRY
120-
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
121-
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
119+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
120+
// Some inquiry_resp's fields are already filled with default values, application can update them
121+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
122+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
122123
(void) lun;
123-
124124
const char vid[] = "TinyUSB";
125125
const char pid[] = "Mass Storage";
126126
const char rev[] = "1.0";
127127

128-
memcpy(vendor_id, vid, strlen(vid));
129-
memcpy(product_id, pid, strlen(pid));
130-
memcpy(product_rev, rev, strlen(rev));
128+
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
129+
memcpy(inquiry_resp->product_id, pid, strlen(pid));
130+
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
131+
132+
return sizeof(scsi_inquiry_resp_t); // 36 bytes
131133
}
132134

133135
// Invoked when received Test Unit Ready command.

examples/device/cdc_msc_freertos/src/msc_disk.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,20 @@ static void io_task(void *params) {
188188
void msc_disk_init() {}
189189
#endif
190190

191-
// Invoked when received SCSI_CMD_INQUIRY
192-
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
193-
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
191+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
192+
// Some inquiry_resp's fields are already filled with default values, application can update them
193+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
194+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
194195
(void) lun;
195196
const char vid[] = "TinyUSB";
196197
const char pid[] = "Mass Storage";
197198
const char rev[] = "1.0";
198-
memcpy(vendor_id , vid, strlen(vid));
199-
memcpy(product_id , pid, strlen(pid));
200-
memcpy(product_rev, rev, strlen(rev));
199+
200+
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
201+
memcpy(inquiry_resp->product_id, pid, strlen(pid));
202+
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
203+
204+
return sizeof(scsi_inquiry_resp_t); // 36 bytes
201205
}
202206

203207
// Invoked when received Test Unit Ready command.

examples/device/dynamic_configuration/src/msc_disk.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,20 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
116116
README_CONTENTS
117117
};
118118

119-
// Invoked when received SCSI_CMD_INQUIRY
120-
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
121-
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
122-
{
119+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
120+
// Some inquiry_resp's fields are already filled with default values, application can update them
121+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
122+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
123123
(void) lun;
124-
125124
const char vid[] = "TinyUSB";
126125
const char pid[] = "Mass Storage";
127126
const char rev[] = "1.0";
128127

129-
memcpy(vendor_id , vid, strlen(vid));
130-
memcpy(product_id , pid, strlen(pid));
131-
memcpy(product_rev, rev, strlen(rev));
128+
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
129+
memcpy(inquiry_resp->product_id, pid, strlen(pid));
130+
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
131+
132+
return sizeof(scsi_inquiry_resp_t); // 36 bytes
132133
}
133134

134135
// Invoked when received Test Unit Ready command.

examples/device/msc_dual_lun/src/msc_disk_dual.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,20 @@ uint8_t tud_msc_get_maxlun_cb(void) {
207207
return 2; // dual LUN
208208
}
209209

210-
// Invoked when received SCSI_CMD_INQUIRY
211-
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
212-
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
213-
(void) lun; // use same ID for both LUNs
214-
210+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
211+
// Some inquiry_resp's fields are already filled with default values, application can update them
212+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
213+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
214+
(void) lun;
215215
const char vid[] = "TinyUSB";
216216
const char pid[] = "Mass Storage";
217217
const char rev[] = "1.0";
218218

219-
memcpy(vendor_id , vid, strlen(vid));
220-
memcpy(product_id , pid, strlen(pid));
221-
memcpy(product_rev, rev, strlen(rev));
219+
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
220+
memcpy(inquiry_resp->product_id, pid, strlen(pid));
221+
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
222+
223+
return sizeof(scsi_inquiry_resp_t); // 36 bytes
222224
}
223225

224226
// Invoked when received Test Unit Ready command.

src/class/msc/msc.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct");
108108
//--------------------------------------------------------------------+
109109

110110
/// SCSI Command Operation Code
111-
typedef enum
112-
{
111+
typedef enum {
113112
SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation.
114113
SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device.
115114
SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters.
@@ -124,8 +123,7 @@ typedef enum
124123
}scsi_cmd_type_t;
125124

126125
/// SCSI Sense Key
127-
typedef enum
128-
{
126+
typedef enum {
129127
SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
130128
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< Indicates the last command completed successfully with some recovery action performed by the disc drive.
131129
SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
@@ -141,6 +139,27 @@ typedef enum
141139
SCSI_SENSE_MISCOMPARE = 0x0e ///< Indicates that the source data did not match the data read from the medium.
142140
}scsi_sense_key_type_t;
143141

142+
143+
typedef enum {
144+
SCSI_PDT_DIRECT_ACCESS = 0x0,
145+
SCSI_PDT_SEQUENTIAL_ACCESS = 0x1,
146+
SCSI_PDT_PRINTER = 0x2,
147+
SCSI_PDT_PROCESSOR = 0x3,
148+
SCSI_PDT_WRITE_ONCE = 0x4,
149+
SCSI_PDT_CD_DVD = 0x5,
150+
SCSI_PDT_SCANNER = 0x6,
151+
SCSI_PDT_OPTICAL_DEVICE = 0x7,
152+
SCSI_PDT_MEDIUM_CHANGER = 0x8,
153+
SCSI_PDT_COMMUNICATIONS = 0x9, // obsolete
154+
SCSI_PDT_RAID = 0x0c,
155+
SCSI_PDT_ENCLOSURE_SERVICES = 0x0d,
156+
SCSI_PDT_SIMPLIFIED_DIRECT_ACCESS = 0x0e,
157+
SCSI_PDT_OPTICAL_CARD_READER = 0x0f,
158+
SCSI_PDT_BRIDGE = 0x10, ///< Bridge device, e.g. USB to SCSI bridge
159+
SCSI_PDT_OBJECT_BASED_STORAGE = 0x11, ///< Object-based storage device
160+
SCSI_PDT_AUTOMATION_DRIVE_INTERFACE = 0x12, ///< Automation/Drive Interface (ADI) device
161+
} scsi_peripheral_device_type_t;
162+
144163
//--------------------------------------------------------------------+
145164
// SCSI Primary Command (SPC-4)
146165
//--------------------------------------------------------------------+

src/class/msc/msc_device.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141

4242
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MSC_LOG_LEVEL, __VA_ARGS__)
4343

44+
//--------------------------------------------------------------------+
45+
// Weak stubs: invoked if no strong implementation is available
46+
//--------------------------------------------------------------------+
47+
TU_ATTR_WEAK void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
48+
(void) lun; (void) vendor_id; (void) product_id; (void) product_rev;
49+
}
50+
TU_ATTR_WEAK uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
51+
(void) lun; (void) inquiry_resp;
52+
return 0;
53+
}
54+
4455
//--------------------------------------------------------------------+
4556
// MACRO CONSTANT TYPEDEF
4657
//--------------------------------------------------------------------+
@@ -731,22 +742,19 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
731742
break;
732743

733744
case SCSI_CMD_INQUIRY: {
734-
scsi_inquiry_resp_t inquiry_rsp = {
735-
.is_removable = 1,
736-
.version = 2,
737-
.response_data_format = 2,
738-
.additional_length = sizeof(scsi_inquiry_resp_t) - 5,
739-
};
740-
741-
// vendor_id, product_id, product_rev is space padded string
742-
memset(inquiry_rsp.vendor_id , ' ', sizeof(inquiry_rsp.vendor_id));
743-
memset(inquiry_rsp.product_id , ' ', sizeof(inquiry_rsp.product_id));
744-
memset(inquiry_rsp.product_rev, ' ', sizeof(inquiry_rsp.product_rev));
745-
746-
tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev);
747-
748-
resplen = sizeof(inquiry_rsp);
749-
TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &inquiry_rsp, (size_t) resplen));
745+
scsi_inquiry_resp_t *inquiry_rsp = (scsi_inquiry_resp_t *) buffer;
746+
tu_memclr(inquiry_rsp, sizeof(scsi_inquiry_resp_t));
747+
inquiry_rsp->is_removable = 1;
748+
inquiry_rsp->version = 2;
749+
inquiry_rsp->response_data_format = 2;
750+
inquiry_rsp->additional_length = sizeof(scsi_inquiry_resp_t) - 5;
751+
752+
resplen = (int32_t) tud_msc_inquiry2_cb(lun, inquiry_rsp);
753+
if (resplen == 0) {
754+
// stub callback with no response, use v1 callback
755+
tud_msc_inquiry_cb(lun, inquiry_rsp->vendor_id, inquiry_rsp->product_id, inquiry_rsp->product_rev);
756+
resplen = sizeof(scsi_inquiry_resp_t);
757+
}
750758
}
751759
break;
752760

src/class/msc/msc_device.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,15 @@ bool tud_msc_async_io_done(int32_t bytes_io, bool in_isr);
9090
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
9191
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
9292

93-
// Invoked when received SCSI_CMD_INQUIRY
93+
// Invoked when received SCSI_CMD_INQUIRY, v1, application should use v2 if possible
9494
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
9595
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
9696

97+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
98+
// Some inquiry_resp's fields are already filled with default values, application can update them
99+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
100+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp);
101+
97102
// Invoked when received Test Unit Ready command.
98103
// return true allowing host to read/write this LUN e.g SD card inserted
99104
bool tud_msc_test_unit_ready_cb(uint8_t lun);

test/unit-test/test/device/msc/test_msc_device.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,20 @@ enum
9494

9595
uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE];
9696

97-
// Invoked when received SCSI_CMD_INQUIRY
98-
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
99-
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
100-
{
97+
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
98+
// Some inquiry_resp's fields are already filled with default values, application can update them
99+
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
100+
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
101101
(void) lun;
102-
103102
const char vid[] = "TinyUSB";
104103
const char pid[] = "Mass Storage";
105104
const char rev[] = "1.0";
106105

107-
memcpy(vendor_id , vid, strlen(vid));
108-
memcpy(product_id , pid, strlen(pid));
109-
memcpy(product_rev, rev, strlen(rev));
106+
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
107+
memcpy(inquiry_resp->product_id, pid, strlen(pid));
108+
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
109+
110+
return sizeof(scsi_inquiry_resp_t); // 36 bytes
110111
}
111112

112113
// Invoked when received Test Unit Ready command.

0 commit comments

Comments
 (0)