pub struct MscDevice<'d, A, M = NoopRawMutex>where
A: UsbHostAllocator<'d>,
M: RawMutex,{ /* private fields */ }Expand description
USB Mass Storage Class host device.
Owns the control and bulk pipes for one BBB/SCSI interface and
serializes all command traffic through an internal async mutex.
Open per-LUN handles with MscDevice::lun.
Use MscDevice::new for the common single-task case; the
transport mutex is a NoopRawMutex with no runtime cost. To
share LUNs across tasks, construct with
MscDevice::new_with_raw_mutex and pick a Sync raw mutex.
Implementations§
Source§impl<'d, A> MscDevice<'d, A, NoopRawMutex>where
A: UsbHostAllocator<'d>,
impl<'d, A> MscDevice<'d, A, NoopRawMutex>where
A: UsbHostAllocator<'d>,
Sourcepub async fn new(
alloc: &A,
enum_info: &EnumerationInfo,
config_desc: &[u8],
) -> Result<Self, MscError>
pub async fn new( alloc: &A, enum_info: &EnumerationInfo, config_desc: &[u8], ) -> Result<Self, MscError>
Allocate the control and bulk pipes for the first BBB/SCSI
interface in config_desc, probe GET_MAX_LUN, and wrap the
transport in a NoopRawMutex.
The resulting device is !Sync. Use this constructor when all
LUNs stay in one task. For multi-task sharing, use
MscDevice::new_with_raw_mutex instead.
Source§impl<'d, A, M> MscDevice<'d, A, M>where
A: UsbHostAllocator<'d>,
M: RawMutex,
impl<'d, A, M> MscDevice<'d, A, M>where
A: UsbHostAllocator<'d>,
M: RawMutex,
Sourcepub async fn new_with_raw_mutex(
alloc: &A,
enum_info: &EnumerationInfo,
config_desc: &[u8],
) -> Result<Self, MscError>
pub async fn new_with_raw_mutex( alloc: &A, enum_info: &EnumerationInfo, config_desc: &[u8], ) -> Result<Self, MscError>
Allocate the control and bulk pipes for the first BBB/SCSI
interface in config_desc, probe GET_MAX_LUN, and wrap the
transport in the caller-chosen raw mutex M.
Pick a Sync raw mutex (e.g. CriticalSectionRawMutex) to
drive LUNs from multiple tasks. For single-task use, prefer
MscDevice::new.
Sourcepub fn lun(&self, lun: u8) -> Result<MscLun<'_, 'd, A, M>, MscError>
pub fn lun(&self, lun: u8) -> Result<MscLun<'_, 'd, A, M>, MscError>
Handle to the given LUN.
LUN handles are cheap and do not reserve any transport resource; issuing more than one for the same LUN is permitted but only useful if the caller manages the split state between them.
Sourcepub async fn command(
&self,
lun: u8,
cdb: &[u8],
data: DataDir<'_>,
) -> Result<CommandOutcome, MscError>
pub async fn command( &self, lun: u8, cdb: &[u8], data: DataDir<'_>, ) -> Result<CommandOutcome, MscError>
Run one Bulk-Only command cycle and return the outcome.
cdb must be 1..=16 bytes. The length of data is reported as
dCBWDataTransferLength and drives the data phase.
Recovers from endpoint stalls (via CLEAR_FEATURE(ENDPOINT_HALT)
plus data-toggle reset) and from CSW signature/tag mismatches
(via Bulk-Only Mass Storage Reset). A CSW status of 0x02
(phase error) triggers a reset and returns
MscError::PhaseError.
§Cancellation
Not cancel-safe: dropping the future mid-cycle leaves the device in an undefined state. The transport marks itself dirty and issues a Mass Storage Reset before the next command.