Opened 3 years ago
Last modified 3 years ago
#1609 new enhancement
JMicron USB bridges may return empty sense data on error
Reported by: | Eaton Zveare | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | undecided |
Component: | all | Version: | 7.3 |
Keywords: | jmicron | Cc: |
Description
I noticed that when an incorrect pass-through command (or command data) is sent over a JMicron USB, usbjmicron_device::ata_pass_through returns true, indicating success.
If I use a different USB, the call is routed to sat_device::ata_pass_through instead. That method correctly returns false with the same incorrect command/data because you parse the sense data extensively and check for various errors.
When debugging and breaking at this spot, I noticed there is indeed an indication the command failed (io_hdr.scsi_status == 2 (CHECK CONDITION)), but you aren't checking it. There's barely any error checking at all compared to sat_device::ata_pass_through.
Is this an oversight with the JMicron support? I noticed with Cypress support, you do a basic check here. This doesn't appear to be the case with Prolific support though, where you also don't check the sense.
Let me know what you think. Maybe consider copying all the error checking code over from sat_device::ata_pass_through.
Change History (6)
comment:1 by , 3 years ago
Component: | smartctl → all |
---|---|
Keywords: | jmicron added |
Milestone: | → undecided |
comment:2 by , 3 years ago
Hi Christian, I'm actually working in the source code and not with a specific command.
My custom code is basically this inside of atacmds.cpp:
ata_cmd_in in; in.in_regs.command = command; in.in_regs.sector_count = 1; in.set_data_out(out_data_buf, 1); return device->ata_pass_through(in);
The last line is what is erroneously returning true.
I have debugged what you asked and both values are 0 when io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION.
comment:3 by , 3 years ago
This suggests that the USB bridge firmware returns empty sense data. It should not do this if an error occurred, so this is possibly a firmware bug. Check the raw sense data block, see scsi_do_sense_disect
.
comment:4 by , 3 years ago
io_buf->sensep is all zeros. So even though there is a CHECK CONDITION, scsi_do_sense_disect doesn't do anything since resp_code is 0.
comment:5 by , 3 years ago
Summary: | JMicron pass-through does not check returned sense data → JMicron USB bridges may return empty sense data on error |
---|---|
Type: | defect → enhancement |
Even with resp_code != 0
, the remaining zeros would mean SENSE KEY = 0 (NO_SENSE), ASC/ASCQ = 0/0 (NO ADDITIONAL SENSE INFORMATION).
Conclusion: If the JMicron USB bridge returns this on error (i.e. unsupported SCSI command), this is a firmware bug.
If this is common behavior of various JMicron bridges, we could possibly add something like:
-
scsiata.cpp
1011 1011 "usbjmicron_device::ata_pass_through: ")) 1012 1012 return set_err(scsidev->get_err()); 1013 1013 1014 if (io_hdr.scsi_status == SCSI_STATUS_CHECK_CONDITION) 1015 // Some JMicron USB bridges return zero filled sense data on error 1016 return set_err(EIO, "Unknown error, invalid sense data [JMicron]"); 1017 1014 1018 if (in.out_needed.is_set()) { 1015 1019 if (is_smart_status) { 1016 1020 if (io_hdr.resid == 1)
But this would require that CHECK_CONDITION is never set on success.
Change summary accordingly and leave ticket open as undecided for now.
comment:6 by , 3 years ago
Yes, it appears that is the only check that can be done in this case.
Do you have any JMicron adapters to check? It would be interesting to know if affects other bridge models.
Please provide the output of
smartctl -r ioctl,2 ...
for a command whereCHECK_CONDITION
is returned and the error is apparently ignored.CHECK_CONDITION
only indicates presence of valid sense data. The sense data does not necessarily indicate an error (e.g. withsmartctl -d sat -H
, ATA output registers are returned in sense data not indicating an error).usbjmicron_device::ata_pass_through
callsscsi_device::scsi_pass_through_and_check
.After the actual
scsi_pass_through
, this function callsscsi_do_sense_disect
(which sets key/asc/ascq if(SCSI_STATUS_CHECK_CONDITION == io_buf->scsi_status)
) and thenscsiSimpleSenseFilter
which returns nonzero if and only if the sense key indicates an error.Please debug into
scsi_device::scsi_pass_through_and_check
and examinesinfo.sense_key
anderr
: