Set up a basic SCSI scheme, and get disk size.

Some commands are unused though, and probably won't be used, for example
ReportSuppOpcodes. Also, there appears to be lots of different versions
of the SCSI specification.
This commit is contained in:
4lDO2
2020-02-14 00:02:13 +01:00
parent 9d88528188
commit 034e6bce70
8 changed files with 650 additions and 38 deletions
+13 -10
View File
@@ -1,12 +1,9 @@
use std::convert::TryInto;
use std::fs::File;
use std::io::prelude::*;
use std::{io, slice};
use std::num::NonZeroU32;
use std::slice;
use thiserror::Error;
use xhcid_interface::{ConfDesc, DeviceReqData, EndpBinaryDirection, EndpDirection, EndpointStatus, IfDesc, Invalid, PortReqDirection, PortReqTy, PortReqRecipient, PortTransferStatus, XhciClientHandle, XhciClientHandleError, XhciEndpHandle};
use xhcid_interface::{ConfDesc, DeviceReqData, EndpBinaryDirection, EndpDirection, EndpointStatus, IfDesc, Invalid, PortReqTy, PortReqRecipient, PortTransferStatus, XhciClientHandle, XhciClientHandleError, XhciEndpHandle};
use super::{Protocol, ProtocolError};
use super::{Protocol, ProtocolError, SendCommandStatus};
pub const CBW_SIGNATURE: u32 = 0x43425355;
@@ -130,7 +127,7 @@ impl<'a> BulkOnlyTransport<'a> {
}
impl<'a> Protocol for BulkOnlyTransport<'a> {
fn send_command(&mut self, cb: &[u8], data: DeviceReqData) -> Result<(), ProtocolError> {
fn send_command(&mut self, cb: &[u8], data: DeviceReqData) -> Result<SendCommandStatus, ProtocolError> {
self.current_tag += 1;
let tag = self.current_tag;
@@ -138,10 +135,10 @@ impl<'a> Protocol for BulkOnlyTransport<'a> {
println!();
let mut cbw_bytes = [0u8; 31];
println!("{}", base64::encode(&cbw_bytes));
let cbw = plain::from_mut_bytes::<CommandBlockWrapper>(&mut cbw_bytes).unwrap();
*cbw = CommandBlockWrapper::new(tag, data.len() as u32, data.direction().into(), 0, cb)?;
let cbw = *cbw;
println!("{}", base64::encode(&cbw_bytes));
dbg!(self.bulk_in.status()?, self.bulk_out.status()?);
@@ -209,7 +206,13 @@ impl<'a> Protocol for BulkOnlyTransport<'a> {
dbg!(self.bulk_in.status()?, self.bulk_out.status()?);
}
Ok(())
Ok(if csw.status == CswStatus::Passed as u8 {
SendCommandStatus::Success
} else if csw.status == CswStatus::Failed as u8 {
SendCommandStatus::Failed { residue: NonZeroU32::new(csw.data_residue) }
} else {
return Err(ProtocolError::ProtocolError("bulk-only transport phase error, or other"));
})
}
}
+16 -1
View File
@@ -1,4 +1,5 @@
use std::io;
use std::num::NonZeroU32;
use thiserror::Error;
use xhcid_interface::{DeviceReqData, DevDesc, ConfDesc, IfDesc, XhciClientHandle, XhciClientHandleError};
@@ -16,10 +17,24 @@ pub enum ProtocolError {
#[error("attempted recovery failed")]
RecoveryFailed,
#[error("protocol error")]
ProtocolError(&'static str),
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SendCommandStatus {
Success,
Failed { residue: Option<NonZeroU32> },
}
impl Default for SendCommandStatus {
fn default() -> Self {
Self::Success
}
}
pub trait Protocol {
fn send_command(&mut self, command: &[u8], data: DeviceReqData) -> Result<(), ProtocolError>;
fn send_command(&mut self, command: &[u8], data: DeviceReqData) -> Result<SendCommandStatus, ProtocolError>;
}
/// Bulk-only transport