sgutils2: support RequestSense Descriptor format
This commit is contained in:
parent
e1740f3f01
commit
a223458753
@ -3,6 +3,8 @@
|
|||||||
//! Incomplete, but we currently do not need more.
|
//! Incomplete, but we currently do not need more.
|
||||||
//!
|
//!
|
||||||
//! See: `/usr/include/scsi/sg_pt.h`
|
//! See: `/usr/include/scsi/sg_pt.h`
|
||||||
|
//!
|
||||||
|
//! The SCSI Commands Reference Manual also contains some usefull information.
|
||||||
|
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
@ -268,7 +270,7 @@ struct InquiryPage {
|
|||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
#[derive(Endian, Debug)]
|
#[derive(Endian, Debug)]
|
||||||
struct RequestSensePage {
|
struct RequestSenseFixed {
|
||||||
response_code: u8,
|
response_code: u8,
|
||||||
obsolete: u8,
|
obsolete: u8,
|
||||||
flags2: u8,
|
flags2: u8,
|
||||||
@ -281,6 +283,17 @@ struct RequestSensePage {
|
|||||||
sense_key_specific: [u8; 3],
|
sense_key_specific: [u8; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C, packed)]
|
||||||
|
#[derive(Endian, Debug)]
|
||||||
|
struct RequestSenseDescriptor{
|
||||||
|
response_code: u8,
|
||||||
|
sense_key: u8,
|
||||||
|
additional_sense_code: u8,
|
||||||
|
additional_sense_code_qualifier: u8,
|
||||||
|
reserved: [u8;4],
|
||||||
|
additional_sense_len: u8,
|
||||||
|
}
|
||||||
|
|
||||||
/// Inquiry result
|
/// Inquiry result
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct InquiryInfo {
|
pub struct InquiryInfo {
|
||||||
@ -477,22 +490,34 @@ impl <'a, F: AsRawFd> SgRaw<'a, F> {
|
|||||||
if sense_len == 0 {
|
if sense_len == 0 {
|
||||||
return Err(format_err!("scsi command failed: no Sense").into());
|
return Err(format_err!("scsi command failed: no Sense").into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let code = self.sense_buffer[0] & 0x7f;
|
||||||
|
|
||||||
let mut reader = &self.sense_buffer[..(sense_len as usize)];
|
let mut reader = &self.sense_buffer[..(sense_len as usize)];
|
||||||
|
|
||||||
let sense: RequestSensePage = unsafe { reader.read_be_value()? };
|
let sense = match code {
|
||||||
|
0x70 => {
|
||||||
let code = sense.response_code & 0x7f;
|
let sense: RequestSenseFixed = unsafe { reader.read_be_value()? };
|
||||||
if code == 0x71 {
|
SenseInfo {
|
||||||
return Err(format_err!("scsi command failed: received deferred Sense").into());
|
|
||||||
}
|
|
||||||
if code != 0x70 {
|
|
||||||
return Err(format_err!("scsi command failed: invalid Sense response code {:x}", code).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let sense = SenseInfo {
|
|
||||||
sense_key: sense.flags2 & 0xf,
|
sense_key: sense.flags2 & 0xf,
|
||||||
asc: sense.additional_sense_code,
|
asc: sense.additional_sense_code,
|
||||||
ascq: sense.additional_sense_code_qualifier,
|
ascq: sense.additional_sense_code_qualifier,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0x72 => {
|
||||||
|
let sense: RequestSenseDescriptor = unsafe { reader.read_be_value()? };
|
||||||
|
SenseInfo {
|
||||||
|
sense_key: sense.sense_key & 0xf,
|
||||||
|
asc: sense.additional_sense_code,
|
||||||
|
ascq: sense.additional_sense_code_qualifier,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0x71 | 0x73 => {
|
||||||
|
return Err(format_err!("scsi command failed: received deferred Sense").into());
|
||||||
|
}
|
||||||
|
unknown => {
|
||||||
|
return Err(format_err!("scsi command failed: invalid Sense response code {:x}", unknown).into());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Err(ScsiError {
|
return Err(ScsiError {
|
||||||
|
Loading…
Reference in New Issue
Block a user