stateless scsi

This commit is contained in:
2025-07-30 14:59:53 -06:00
parent 1d03640d5b
commit f8fb1b81c2
3 changed files with 9 additions and 34 deletions

View File

@@ -12,18 +12,10 @@ use crate::storage::SdCard;
const BULK_ENDPOINT_PACKET_SIZE: usize = 64; const BULK_ENDPOINT_PACKET_SIZE: usize = 64;
#[derive(PartialEq, Eq)]
enum State {
Ready,
Ejected,
}
pub struct MassStorageClass<'d, D: Driver<'d>> { pub struct MassStorageClass<'d, D: Driver<'d>> {
sdcard: SdCard, sdcard: SdCard,
state: State,
bulk_out: D::EndpointOut, bulk_out: D::EndpointOut,
bulk_in: D::EndpointIn, bulk_in: D::EndpointIn,
last_sense: Option<ScsiError>,
} }
impl<'d, D: Driver<'d>> MassStorageClass<'d, D> { impl<'d, D: Driver<'d>> MassStorageClass<'d, D> {
@@ -39,8 +31,6 @@ impl<'d, D: Driver<'d>> MassStorageClass<'d, D> {
bulk_out, bulk_out,
bulk_in, bulk_in,
sdcard, sdcard,
state: State::Ready,
last_sense: None,
} }
} }
@@ -50,12 +40,6 @@ impl<'d, D: Driver<'d>> MassStorageClass<'d, D> {
if let Ok(n) = self.bulk_out.read(&mut cbw_buf).await { if let Ok(n) = self.bulk_out.read(&mut cbw_buf).await {
if n == 31 { if n == 31 {
if let Some(cbw) = CommandBlockWrapper::parse(&cbw_buf[..n]) { if let Some(cbw) = CommandBlockWrapper::parse(&cbw_buf[..n]) {
if self.state == State::Ejected {
self.last_sense = Some(ScsiError::NotReady);
self.send_csw_fail(cbw.dCBWTag).await;
continue;
}
// TODO: validate cbw // TODO: validate cbw
if self.handle_command(&cbw.CBWCB).await.is_ok() { if self.handle_command(&cbw.CBWCB).await.is_ok() {
self.send_csw_success(cbw.dCBWTag).await self.send_csw_success(cbw.dCBWTag).await
@@ -268,13 +252,7 @@ impl<'d, D: Driver<'d>> MassStorageClass<'d, D> {
.map_err(|_| ()) .map_err(|_| ())
} }
ScsiCommand::PreventAllowMediumRemoval { prevent: _prevent } => Ok(()), ScsiCommand::PreventAllowMediumRemoval { prevent: _prevent } => Ok(()),
ScsiCommand::StartStopUnit { start, load_eject } => { ScsiCommand::StartStopUnit { start, load_eject } => Ok(()),
if !start && load_eject {
self.state = State::Ejected;
self.last_sense = Some(ScsiError::NotReady);
}
Ok(())
}
} }
} }

View File

@@ -34,8 +34,6 @@ impl SdCard {
pub const BLOCK_SIZE: u16 = 512; pub const BLOCK_SIZE: u16 = 512;
pub fn new(sdcard: SD, det: Input<'static>) -> Self { pub fn new(sdcard: SD, det: Input<'static>) -> Self {
sdcard.get_card_type().unwrap();
defmt::info!("Card size is {} bytes", sdcard.num_bytes().unwrap());
let volume_mgr = VolumeManager::<_, _, MAX_DIRS, MAX_FILES, MAX_VOLUMES>::new_with_limits( let volume_mgr = VolumeManager::<_, _, MAX_DIRS, MAX_FILES, MAX_VOLUMES>::new_with_limits(
sdcard, sdcard,
DummyTimeSource {}, DummyTimeSource {},

View File

@@ -1,12 +1,6 @@
use crate::{scsi::MassStorageClass, storage::SdCard}; use crate::{scsi::MassStorageClass, storage::SdCard};
use embassy_futures::join::{self, join}; use embassy_futures::select::select;
use embassy_rp::{ use embassy_rp::{peripherals::USB, usb::Driver};
gpio::Output,
peripherals::{SPI0, USB},
spi::{Async, Spi},
usb::Driver,
};
use embassy_time::Delay;
use embassy_usb::{Builder, Config}; use embassy_usb::{Builder, Config};
pub async fn usb_handler(driver: Driver<'static, USB>, sdcard: SdCard) { pub async fn usb_handler(driver: Driver<'static, USB>, sdcard: SdCard) {
@@ -33,5 +27,10 @@ pub async fn usb_handler(driver: Driver<'static, USB>, sdcard: SdCard) {
let mut scsi = MassStorageClass::new(&mut builder, sdcard); let mut scsi = MassStorageClass::new(&mut builder, sdcard);
let mut usb = builder.build(); let mut usb = builder.build();
join(usb.run(), scsi.poll()).await; loop {
select(usb.run(), scsi.poll()).await;
defmt::warn!("rebuilding usb");
usb.disable().await;
}
} }