From f2123eb7376f59aa027a92de6006b1fa9fdeb373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dav=C3=AD=C3=B0=20Steinn=20Geirsson?= Date: Thu, 12 Mar 2026 20:01:25 +0000 Subject: [PATCH] fix(aten-mount): distinguish handled vs ignored SCSI commands in log Add LUN field and handled/ignored status to SCSI debug log lines so unknown opcodes (silently accepted per firmware behavior) are clearly distinguishable from handled commands that return no data. Co-Authored-By: Claude Opus 4.6 --- crates/aten-mount/src/scsi.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/crates/aten-mount/src/scsi.rs b/crates/aten-mount/src/scsi.rs index f52c5ac..e8ba691 100644 --- a/crates/aten-mount/src/scsi.rs +++ b/crates/aten-mount/src/scsi.rs @@ -88,20 +88,22 @@ impl<'a> ScsiDevice<'a> { tag.copy_from_slice(&cbw[4..8]); let data_transfer_len = u32::from_le_bytes([cbw[8], cbw[9], cbw[10], cbw[11]]); let flags = cbw[12]; + let lun = cbw[13]; let cb_length = cbw[14] as usize; let cdb = &cbw[15..15 + cb_length]; let dir_in = flags & 0x80 != 0; let t0 = Instant::now(); - let (data, status) = self.execute_scsi(cdb, data_transfer_len); + let (data, status, handled) = self.execute_scsi(cdb, data_transfer_len); let elapsed = t0.elapsed(); let actual_len = data.len() as u32; let opcode = if cdb.is_empty() { 0xFF } else { cdb[0] }; let status_str = if status == CSW_STATUS_PASSED { "OK" } else { "FAIL" }; + let handled_str = if handled { "handled" } else { "ignored" }; debug!( - "SCSI ep=0x{ep:02x} {name} (0x{opcode:02x}) tag={tag:02x?} xfer_len={data_transfer_len} \ - resp_len={actual_len} status={status_str} elapsed={elapsed:?}", + "SCSI ep=0x{ep:02x} lun={lun} {name} (0x{opcode:02x}) tag={tag:02x?} xfer_len={data_transfer_len} \ + resp_len={actual_len} status={status_str} {handled_str} elapsed={elapsed:?}", name = scsi_opcode_name(opcode), ); @@ -114,12 +116,14 @@ impl<'a> ScsiDevice<'a> { resp } - fn execute_scsi(&mut self, cdb: &[u8], _transfer_len: u32) -> (Vec, u8) { + /// Returns (data, status, handled). `handled` is false for unknown opcodes + /// that we silently accept per firmware behavior. + fn execute_scsi(&mut self, cdb: &[u8], _transfer_len: u32) -> (Vec, u8, bool) { if cdb.is_empty() { self.set_sense(SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - return (vec![], CSW_STATUS_FAILED); + return (vec![], CSW_STATUS_FAILED, true); } - match cdb[0] { + let result = match cdb[0] { SCSI_TEST_UNIT_READY => self.cmd_test_unit_ready(), SCSI_REQUEST_SENSE => self.cmd_request_sense(cdb), SCSI_INQUIRY => self.cmd_inquiry(cdb), @@ -136,10 +140,10 @@ impl<'a> ScsiDevice<'a> { SCSI_READ_TRACK_INFORMATION => self.cmd_read_track_information(cdb), SCSI_MODE_SENSE_10 => self.cmd_mode_sense_10(cdb), _ => { - warn!("unsupported SCSI opcode 0x{:02x}", cdb[0]); - (vec![], CSW_STATUS_PASSED) + return (vec![], CSW_STATUS_PASSED, false); } - } + }; + (result.0, result.1, true) } fn cmd_test_unit_ready(&mut self) -> (Vec, u8) { @@ -582,10 +586,10 @@ mod tests { #[test] fn test_unknown_opcode() { let mut dev = new_test_device(); - let (data, status) = dev.execute_scsi(&[0xFF], 0); - // Firmware behavior: unknown opcodes return no data, status PASS, no error sense + let (data, status, handled) = dev.execute_scsi(&[0xFF], 0); assert_eq!(status, CSW_STATUS_PASSED); assert!(data.is_empty()); + assert!(!handled); } #[test]