USB: canonical scheme pattern — all 4 drivers aligned
ftdi/usbaudiod scheme.rs updated to match acmd/ecmd pattern: Explicit match arms in read/write (not map/map_err chains) Consistent openat with root dir + device file routing Saturating close count AudioScheme retains capture/playback path routing All 4 scheme modules now identical in structure: acmd → /scheme/ttys/usbACM_<N> (Mutex<bulk_in>, Mutex<bulk_out>) ftdi → /scheme/ttys/usbFTDI_<N> (same) ecmd → /scheme/net/usbECM_<N> (same) audio → /scheme/audio/usbAudio_<N> (Mutex<isoch_in>, Mutex<Option<isoch_out>>)
This commit is contained in:
@@ -27,23 +27,33 @@ impl SchemeSync for FtdiScheme {
|
||||
return Ok(OpenResult::ThisScheme { number: 1, flags: O_STAT | MODE_FILE });
|
||||
}
|
||||
let mut count = self.open_count.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let next_id = 2 + *count;
|
||||
*count += 1;
|
||||
let next_id = 2 + *count; *count += 1;
|
||||
Ok(OpenResult::OtherScheme { number: next_id, flags: O_RDWR })
|
||||
}
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
|
||||
if id < 2 || buf.is_empty() { return Err(Error::new(EBADF)); }
|
||||
let mut b = self.bulk_in.lock().unwrap_or_else(|e| e.into_inner());
|
||||
b.transfer_read(buf).map(|s| s.bytes_transferred as usize).map_err(|e| { log::warn!("FTDI scheme: read: {}", e); Error::new(EINVAL) })
|
||||
let mut bulk_in = self.bulk_in.lock().unwrap_or_else(|e| e.into_inner());
|
||||
match bulk_in.transfer_read(buf) {
|
||||
Ok(status) if status.bytes_transferred > 0 => Ok(status.bytes_transferred as usize),
|
||||
Ok(_) => Ok(0),
|
||||
Err(e) => { log::warn!("FTDI scheme: read: {}", e); Err(Error::new(EINVAL)) }
|
||||
}
|
||||
}
|
||||
fn write(&mut self, id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result<usize> {
|
||||
if id < 2 || buf.is_empty() { return Err(Error::new(EBADF)); }
|
||||
let mut b = self.bulk_out.lock().unwrap_or_else(|e| e.into_inner());
|
||||
b.transfer_write(buf).map(|s| s.bytes_transferred as usize).map_err(|e| { log::warn!("FTDI scheme: write: {}", e); Error::new(EINVAL) })
|
||||
let mut bulk_out = self.bulk_out.lock().unwrap_or_else(|e| e.into_inner());
|
||||
match bulk_out.transfer_write(buf) {
|
||||
Ok(status) if status.bytes_transferred > 0 => Ok(status.bytes_transferred as usize),
|
||||
Ok(_) => Ok(0),
|
||||
Err(e) => { log::warn!("FTDI scheme: write: {}", e); Err(Error::new(EINVAL)) }
|
||||
}
|
||||
}
|
||||
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> { Ok(()) }
|
||||
fn close(&self, id: usize, _ctx: &CallerCtx) -> Result<()> {
|
||||
if id >= 2 { *self.open_count.lock().unwrap_or_else(|e| e.into_inner()) = self.open_count.lock().unwrap_or_else(|e| e.into_inner()).saturating_sub(1); }
|
||||
if id >= 2 {
|
||||
let mut count = self.open_count.lock().unwrap_or_else(|e| e.into_inner());
|
||||
*count = count.saturating_sub(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,25 +32,34 @@ impl SchemeSync for AudioScheme {
|
||||
_ => O_RDWR,
|
||||
};
|
||||
let next_id = 2 + *c; *c += 1;
|
||||
Ok(OpenResult::OtherScheme { number: next_id, flags })
|
||||
Ok(OpenResult::OtherScheme { fd: next_id })
|
||||
}
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
|
||||
if id < 2 || buf.is_empty() { return Err(Error::new(EBADF)); }
|
||||
self.isoch_in.lock().unwrap_or_else(|e| e.into_inner())
|
||||
.transfer_read(buf).map(|s| s.bytes_transferred as usize)
|
||||
.map_err(|e| { log::warn!("Audio scheme: read: {}", e); Error::new(EINVAL) })
|
||||
let mut isoch_in = self.isoch_in.lock().unwrap_or_else(|e| e.into_inner());
|
||||
match isoch_in.transfer_read(buf) {
|
||||
Ok(status) if status.bytes_transferred > 0 => Ok(status.bytes_transferred as usize),
|
||||
Ok(_) => Ok(0),
|
||||
Err(e) => { log::warn!("Audio scheme: read: {}", e); Err(Error::new(EINVAL)) }
|
||||
}
|
||||
}
|
||||
fn write(&mut self, id: usize, buf: &[u8], _ctx: &CallerCtx) -> Result<usize> {
|
||||
if id < 2 || buf.is_empty() { return Err(Error::new(EBADF)); }
|
||||
match self.isoch_out.lock().unwrap_or_else(|e| e.into_inner()).as_mut() {
|
||||
Some(out) => out.transfer_write(buf).map(|s| s.bytes_transferred as usize)
|
||||
.map_err(|e| { log::warn!("Audio scheme: write: {}", e); Error::new(EINVAL) }),
|
||||
Some(isoch_out) => match isoch_out.transfer_write(buf) {
|
||||
Ok(status) if status.bytes_transferred > 0 => Ok(status.bytes_transferred as usize),
|
||||
Ok(_) => Ok(0),
|
||||
Err(e) => { log::warn!("Audio scheme: write: {}", e); Err(Error::new(EINVAL)) }
|
||||
},
|
||||
None => Err(Error::new(EINVAL)),
|
||||
}
|
||||
}
|
||||
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> { Ok(()) }
|
||||
fn close(&self, id: usize, _ctx: &CallerCtx) -> Result<()> {
|
||||
if id >= 2 { let mut c = self.open_count.lock().unwrap_or_else(|e| e.into_inner()); *c = c.saturating_sub(1); }
|
||||
if id >= 2 {
|
||||
let mut count = self.open_count.lock().unwrap_or_else(|e| e.into_inner());
|
||||
*count = count.saturating_sub(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user