const VENDOR: u8 = 0x80;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Inquiry {
page: Option<u8>,
allocation_length: u8,
}
impl Inquiry {
pub fn standard() -> Self {
Self {
page: None,
allocation_length: 36,
}
}
pub fn vpd(page: u8) -> Self {
Self {
page: Some(page),
allocation_length: u8::MAX,
}
}
pub fn allocation_length(&self) -> usize {
self.allocation_length as usize
}
pub fn cdb(&self) -> [u8; 6] {
[
0x12,
self.page.is_some() as u8,
self.page.unwrap_or(0),
0,
self.allocation_length,
match self.page {
Some(_) => VENDOR,
None => 0,
},
]
}
}
#[derive(Debug)]
pub struct TestUnitReady;
impl TestUnitReady {
pub fn cdb(&self) -> [u8; 6] {
[0; 6]
}
}
#[derive(Debug)]
pub struct ReserveUnit;
impl ReserveUnit {
pub fn cdb(&self) -> [u8; 6] {
[0x16, 0, 0, 0, 0, 0]
}
}
#[derive(Debug)]
pub struct ReleaseUnit;
impl ReleaseUnit {
pub fn cdb(&self) -> [u8; 6] {
[0x17, 0, 0, 0, 0, 0]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PageControl {
Current = 0,
Variable = 1,
Default = 2,
}
#[derive(Debug)]
pub struct ModeSense {
page: u8,
control: PageControl,
}
impl ModeSense {
pub fn new(page: u8, control: PageControl) -> Self {
Self { page, control }
}
pub fn allocation_length(&self) -> usize {
20
}
pub fn cdb(&self) -> [u8; 6] {
[
0x1A,
0x10,
(self.control as u8) << 6 | self.page,
0,
self.allocation_length() as u8,
0,
]
}
}
#[derive(Debug)]
pub struct ModeSelect {
parameter_list_length: u8,
}
impl ModeSelect {
pub fn new(parameter_list_length: u8) -> Self {
Self {
parameter_list_length,
}
}
pub fn cdb(&self) -> [u8; 6] {
[0x15, 0x10, 0, 0, self.parameter_list_length, 0]
}
}
#[derive(Debug)]
pub struct GetWindow {
window: Option<u8>,
transfer_length: u32,
}
impl GetWindow {
pub fn all(transfer_length: u32) -> Self {
Self {
window: None,
transfer_length,
}
}
pub fn single(window: u8, transfer_length: u32) -> Self {
Self {
window: Some(window),
transfer_length,
}
}
pub fn allocation_length(&self) -> usize {
self.transfer_length as usize
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(
self.transfer_length <= 0xFF_FFFF,
"GET WINDOW length is 24 bits"
);
let [_, hi, mid, lo] = self.transfer_length.to_be_bytes();
[
0x25,
self.window.is_some() as u8,
0,
0,
0,
self.window.unwrap_or(0),
hi,
mid,
lo,
VENDOR,
]
}
}
#[derive(Debug)]
pub struct Scan {
windows: u8,
}
impl Scan {
pub fn new(windows: u8) -> Self {
Self { windows }
}
pub fn cdb(&self) -> [u8; 6] {
[0x1B, 0, 0, 0, self.windows, 0]
}
}
#[derive(Debug)]
pub struct Read {
dtc: u8,
dtq: u16,
transfer_length: u32,
}
impl Read {
pub fn new(dtc: u8, color: u8, width_code: u8, transfer_length: u32) -> Self {
Self {
dtc,
dtq: u16::from(color) << 8 | u16::from(width_code),
transfer_length,
}
}
pub fn allocation_length(&self) -> usize {
self.transfer_length as usize
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(self.transfer_length <= 0xFF_FFFF, "READ length is 24 bits");
let [_, hi, mid, lo] = self.transfer_length.to_be_bytes();
let [dtq_hi, dtq_lo] = self.dtq.to_be_bytes();
[0x28, 0, self.dtc, 0, dtq_hi, dtq_lo, hi, mid, lo, VENDOR]
}
}
#[derive(Debug)]
pub struct Send {
dtc: u8,
dtq: u16,
transfer_length: u32,
}
impl Send {
pub fn new(dtc: u8, color: u8, width_code: u8, transfer_length: u32) -> Self {
Self {
dtc,
dtq: u16::from(color) << 8 | u16::from(width_code),
transfer_length,
}
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(self.transfer_length <= 0xFF_FFFF, "SEND length is 24 bits");
let [_, hi, mid, lo] = self.transfer_length.to_be_bytes();
let [dtq_hi, dtq_lo] = self.dtq.to_be_bytes();
[0x2A, 0, self.dtc, 0, dtq_hi, dtq_lo, hi, mid, lo, 0]
}
}
#[derive(Debug)]
pub struct SendDiagnostic;
impl SendDiagnostic {
pub fn cdb(&self) -> [u8; 6] {
[0x1D, 0x04, 0, 0, 0, 0]
}
}
#[derive(Debug)]
pub struct Abort;
impl Abort {
pub fn cdb(&self) -> [u8; 6] {
[0xC0, 0, 0, 0, 0, 0]
}
}
#[derive(Debug)]
pub struct SetParameter {
operation: u8,
parameter_length: u32,
}
impl SetParameter {
pub fn new(operation: u8, parameter_length: u32) -> Self {
Self {
operation,
parameter_length,
}
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(
self.parameter_length <= 0xFF_FFFF,
"SET PARAMETER length is 24 bits"
);
let [_, hi, mid, lo] = self.parameter_length.to_be_bytes();
[0xE0, 0, self.operation, 0, 0, 0, hi, mid, lo, 0]
}
}
#[derive(Debug)]
pub struct GetParameter {
operation: u8,
parameter_length: u32,
}
impl GetParameter {
pub fn new(operation: u8, parameter_length: u32) -> Self {
Self {
operation,
parameter_length,
}
}
pub fn allocation_length(&self) -> usize {
self.parameter_length as usize
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(
self.parameter_length <= 0xFF_FFFF,
"GET PARAMETER length is 24 bits"
);
let [_, hi, mid, lo] = self.parameter_length.to_be_bytes();
[0xE1, 0, self.operation, 0, 0, 0, hi, mid, lo, 0]
}
}
#[derive(Debug)]
pub struct Execute;
impl Execute {
pub fn cdb(&self) -> [u8; 6] {
[0xC1, 0, 0, 0, 0, 0]
}
}
#[derive(Debug)]
pub struct SetWindow {
transfer_length: u32,
}
impl SetWindow {
pub fn new(transfer_length: u32) -> Self {
Self { transfer_length }
}
pub fn cdb(&self) -> [u8; 10] {
debug_assert!(
self.transfer_length <= 0xFF_FFFF,
"SET WINDOW length is 24 bits"
);
let [_, hi, mid, lo] = self.transfer_length.to_be_bytes();
[0x24, 0, 0, 0, 0, 0, hi, mid, lo, VENDOR]
}
}