diff --git a/src/tools/sgutils2.rs b/src/tools/sgutils2.rs index 52352b15..37bc2dff 100644 --- a/src/tools/sgutils2.rs +++ b/src/tools/sgutils2.rs @@ -506,7 +506,7 @@ impl <'a, F: AsRawFd> SgRaw<'a, F> { } if self.buffer.len() < 16 { - return Err(format_err!("output buffer too small").into()); + return Err(format_err!("input buffer too small").into()); } let mut ptvp = self.create_scsi_pt_obj()?; @@ -530,6 +530,45 @@ impl <'a, F: AsRawFd> SgRaw<'a, F> { Ok(&self.buffer[..data_len]) } + /// Run the specified RAW SCSI command, use data as input buffer + pub fn do_in_command<'b>(&mut self, cmd: &[u8], data: &'b mut [u8]) -> Result<&'b [u8], ScsiError> { + + if !unsafe { sg_is_scsi_cdb(cmd.as_ptr(), cmd.len() as c_int) } { + return Err(format_err!("no valid SCSI command").into()); + } + + if data.len() == 0 { + return Err(format_err!("got zero-sized input buffer").into()); + } + + let mut ptvp = self.create_scsi_pt_obj()?; + + unsafe { + set_scsi_pt_data_in( + ptvp.as_mut_ptr(), + data.as_mut_ptr(), + data.len() as c_int, + ); + + set_scsi_pt_cdb( + ptvp.as_mut_ptr(), + cmd.as_ptr(), + cmd.len() as c_int, + ); + }; + + self.do_scsi_pt_checked(&mut ptvp)?; + + let resid = unsafe { get_scsi_pt_resid(ptvp.as_ptr()) } as usize; + + if resid > data.len() { + return Err(format_err!("do_scsi_pt failed - got strange resid (value too big)").into()); + } + let data_len = data.len() - resid; + + Ok(&data[..data_len]) + } + /// Run dataout command /// /// Note: use alloc_page_aligned_buffer to alloc data transfer buffer