Merge branch 'bgad_scheme' into 'master'

Move bgad and xhcid to redox-scheme

See merge request redox-os/drivers!251
This commit is contained in:
Jeremy Soller
2025-03-13 16:26:23 +00:00
9 changed files with 142 additions and 160 deletions
Generated
+2
View File
@@ -193,6 +193,7 @@ dependencies = [
"orbclient",
"pcid",
"redox-daemon",
"redox-scheme 0.3.0",
"redox_syscall",
]
@@ -1933,6 +1934,7 @@ dependencies = [
"pcid",
"plain",
"redox-daemon",
"redox-scheme 0.3.0",
"redox_event",
"redox_syscall",
"regex",
+2 -1
View File
@@ -1,11 +1,12 @@
[package]
name = "bgad"
version = "0.1.0"
edition = "2018"
edition = "2021"
[dependencies]
orbclient = "0.3.47"
redox-daemon = "0.1"
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
redox_syscall = "0.5"
common = { path = "../../common" }
+33 -21
View File
@@ -1,14 +1,8 @@
extern crate orbclient;
extern crate syscall;
use std::fs::File;
use std::io::{Read, Write};
use inputd::ProducerHandle;
use pcid_interface::PciFunctionHandle;
use redox_scheme::{RequestKind, Response, SignalBehavior, Socket};
use syscall::call::iopl;
use syscall::data::Packet;
use syscall::scheme::SchemeMut;
use syscall::EOPNOTSUPP;
use crate::bga::Bga;
use crate::scheme::BgaScheme;
@@ -28,7 +22,7 @@ fn main() {
redox_daemon::Daemon::new(move |daemon| {
unsafe { iopl(3).unwrap() };
let mut socket = File::create(":bga").expect("bgad: failed to create bga scheme");
let socket = Socket::create("bga").expect("bgad: failed to create bga scheme");
let mut bga = Bga::new();
println!(" - BGA {}x{}", bga.width(), bga.height());
@@ -45,20 +39,38 @@ fn main() {
daemon.ready().expect("bgad: failed to notify parent");
loop {
let mut packet = Packet::default();
if socket
.read(&mut packet)
.expect("bgad: failed to read events from bga scheme")
== 0
{
break;
let Some(request) = socket
.next_request(SignalBehavior::Restart)
.expect("bgad: failed to read scheme")
else {
// Scheme likely got unmounted
std::process::exit(0);
};
match request.kind() {
RequestKind::Call(call_request) => {
let resp = call_request.handle_scheme(&mut scheme);
socket
.write_response(resp, SignalBehavior::Restart)
.expect("bgad: failed to write display scheme");
}
RequestKind::SendFd(sendfd_request) => {
socket
.write_response(
Response::for_sendfd(
&sendfd_request,
Err(syscall::Error::new(EOPNOTSUPP)),
),
SignalBehavior::Restart,
)
.expect("bgad: failed to write response");
}
RequestKind::Cancellation(_cancellation_request) => {}
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
unreachable!()
}
}
scheme.handle(&mut packet);
socket
.write(&packet)
.expect("bgad: failed to write responses to bga scheme");
}
std::process::exit(0);
})
.expect("bgad: failed to daemonize");
}
+11 -4
View File
@@ -1,7 +1,8 @@
use inputd::ProducerHandle;
use redox_scheme::Scheme;
use std::str;
use syscall::data::Stat;
use syscall::{Error, Result, SchemeMut, EACCES, EINVAL, MODE_CHR};
use syscall::{Error, Result, EACCES, EINVAL, MODE_CHR};
use crate::bga::Bga;
@@ -24,7 +25,7 @@ impl BgaScheme {
}
}
impl SchemeMut for BgaScheme {
impl Scheme for BgaScheme {
fn open(&mut self, _path: &str, _flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid == 0 {
Ok(0)
@@ -33,7 +34,13 @@ impl SchemeMut for BgaScheme {
}
}
fn read(&mut self, _file: usize, buf: &mut [u8]) -> Result<usize> {
fn read(
&mut self,
_id: usize,
buf: &mut [u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<usize> {
let mut i = 0;
let data = format!("{},{}\n", self.bga.width(), self.bga.height()).into_bytes();
while i < buf.len() && i < data.len() {
@@ -43,7 +50,7 @@ impl SchemeMut for BgaScheme {
Ok(i)
}
fn write(&mut self, _file: usize, buf: &[u8]) -> Result<usize> {
fn write(&mut self, _id: usize, buf: &[u8], _offset: u64, _fcntl_flags: u32) -> Result<usize> {
let string = str::from_utf8(buf).or(Err(Error::new(EINVAL)))?;
let string = string.trim();
+1 -1
View File
@@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
log = "0.4"
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
redox_syscall = { version = "0.5", features = ["std"] }
redox_syscall = "0.5"
libredox = "0.1.3"
common = { path = "../../common" }
+2 -2
View File
@@ -114,7 +114,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
std::process::exit(0);
}
Err(err) if err.errno == EAGAIN => break,
Err(err) => panic!("vesad: failed to read display scheme: {err}"),
Err(err) => panic!("driver-graphics: failed to read display scheme: {err}"),
};
match request.kind() {
@@ -122,7 +122,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
let resp = call_request.handle_scheme(self);
self.socket
.write_response(resp, SignalBehavior::Restart)
.expect("vesad: failed to write display scheme");
.expect("driver-graphics: failed to write display scheme");
}
RequestKind::SendFd(sendfd_request) => {
self.socket.write_response(
+1
View File
@@ -21,6 +21,7 @@ lazy_static = "1.4"
log = "0.4"
redox-daemon = "0.1"
redox_event = "0.4.1"
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
redox_syscall = "0.5"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
+30 -29
View File
@@ -26,12 +26,9 @@
extern crate bitflags;
use std::fs::File;
use std::io::{Read, Write};
use std::os::unix::io::{FromRawFd, RawFd};
use std::ptr::NonNull;
use std::sync::{Arc, Mutex};
use libredox::flag;
#[cfg(target_arch = "x86_64")]
use pcid_interface::irq_helpers::allocate_single_interrupt_vector_for_msi;
use pcid_interface::irq_helpers::read_bsp_apic_id;
@@ -40,9 +37,8 @@ use pcid_interface::{
MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo,
};
use syscall::data::Packet;
use syscall::error::EWOULDBLOCK;
use syscall::scheme::Scheme;
use redox_scheme::{RequestKind, Response, SignalBehavior, Socket};
use syscall::EOPNOTSUPP;
use crate::xhci::{InterruptMethod, Xhci};
@@ -190,14 +186,11 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
println!(" + XHCI {}", pci_config.func.display());
let scheme_name = format!("usb.{}", name);
let socket_fd =
libredox::call::open(format!(":{}", scheme_name), flag::O_RDWR | flag::O_CREAT, 0)
.expect("xhcid: failed to create usb scheme");
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
let socket = Socket::create(scheme_name.clone()).expect("xhcid: failed to create usb scheme");
daemon.ready().expect("xhcid: failed to notify parent");
let mut hci = Arc::new(
let hci = Arc::new(
Xhci::new(scheme_name, address, interrupt_method, pcid_handle)
.expect("xhcid: failed to allocate device"),
);
@@ -207,26 +200,34 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
hci.poll();
let mut todo = Vec::<Packet>::new();
loop {
let mut packet = Packet::default();
match socket.read(&mut packet) {
Ok(0) => break,
Ok(_) => (),
Err(err) => panic!("xhcid failed to read from socket: {err}"),
}
let Some(request) = socket
.next_request(SignalBehavior::Restart)
.expect("xhcid: failed to read scheme")
else {
// Scheme likely got unmounted
std::process::exit(0);
};
let a = packet.a;
hci.handle(&mut packet);
if packet.a == (-EWOULDBLOCK) as usize {
packet.a = a;
todo.push(packet);
} else {
socket
.write(&packet)
.expect("xhcid failed to write to socket");
match request.kind() {
RequestKind::Call(call_request) => {
let resp = call_request.handle_scheme(&mut &*hci);
socket
.write_response(resp, SignalBehavior::Restart)
.expect("xhcid: failed to write scheme");
}
RequestKind::SendFd(sendfd_request) => {
socket
.write_response(
Response::for_sendfd(&sendfd_request, Err(syscall::Error::new(EOPNOTSUPP))),
SignalBehavior::Restart,
)
.expect("xhcid: failed to write response");
}
RequestKind::Cancellation(_cancellation_request) => {}
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
unreachable!()
}
}
}
std::process::exit(0);
}
+60 -102
View File
@@ -28,7 +28,8 @@ use log::{debug, error, info, trace, warn};
use smallvec::SmallVec;
use common::io::Io;
use syscall::scheme::Scheme;
use redox_scheme::{CallerCtx, OpenResult, Scheme};
use syscall::schemev2::NewFdFlags;
use syscall::{
Error, Result, Stat, EACCES, EBADF, EBADFD, EBADMSG, EINVAL, EIO, EISDIR, ENOENT, ENOSYS,
ENOTDIR, EPROTO, ESPIPE, MODE_CHR, MODE_DIR, MODE_FILE, O_DIRECTORY, O_RDWR, O_STAT, O_WRONLY,
@@ -97,7 +98,7 @@ pub enum EndpointHandleTy {
Ctl,
/// portX/endpoints/Y/
Root(usize, Vec<u8>), // offset, content
Root(Vec<u8>), // content
}
#[derive(Clone, Copy, Debug)]
@@ -122,13 +123,13 @@ pub enum PortReqState {
/// Contains some information about the data requested via the handle.
#[derive(Debug)]
pub enum Handle {
TopLevel(usize, Vec<u8>), // offset, contents (ports)
Port(usize, usize, Vec<u8>), // port, offset, contents
PortDesc(usize, usize, Vec<u8>), // port, offset, contents
PortState(usize, usize), // port, offset
TopLevel(Vec<u8>), // contents (ports)
Port(usize, Vec<u8>), // port, contents
PortDesc(usize, Vec<u8>), // port, contents
PortState(usize), // port
PortReq(usize, PortReqState), // port, state
Endpoints(usize, usize, Vec<u8>), // port, offset, contents
Endpoint(usize, u8, EndpointHandleTy), // port, endpoint, offset, state
Endpoints(usize, Vec<u8>), // port, contents
Endpoint(usize, u8, EndpointHandleTy), // port, endpoint, state
ConfigureEndpoints(usize), // port
}
@@ -181,20 +182,20 @@ impl Handle {
/// - A [String] containing the scheme path that the handle is associated with.
pub(crate) fn to_scheme(&self) -> String {
match self {
Handle::TopLevel(_, _) => String::from(""),
Handle::Port(port_num, _, _) => {
Handle::TopLevel(_) => String::from(""),
Handle::Port(port_num, _) => {
format!("port{}", port_num)
}
Handle::PortDesc(port_num, _, _) => {
Handle::PortDesc(port_num, _) => {
format!("port{}/descriptors", port_num)
}
Handle::PortState(port_num, _) => {
Handle::PortState(port_num) => {
format!("port{}/state", port_num)
}
Handle::PortReq(port_num, _) => {
format!("port{}/request", port_num)
}
Handle::Endpoints(port_num, _, _) => {
Handle::Endpoints(port_num, _) => {
format!("port{}/endpoints", port_num)
}
Handle::Endpoint(port_num, endpoint_num, handle_type) => match handle_type {
@@ -204,7 +205,7 @@ impl Handle {
EndpointHandleTy::Ctl => {
format!("port{}/endpoints/{}/ctl", port_num, endpoint_num)
}
EndpointHandleTy::Root(_, _) => {
EndpointHandleTy::Root(_) => {
format!("port{}/endpoints/{}", port_num, endpoint_num)
}
},
@@ -224,21 +225,21 @@ impl Handle {
/// - [HandleType] - The access mode associated with the handle.
pub(crate) fn get_handle_type(&self) -> HandleType {
match self {
&Handle::TopLevel(_, _) => HandleType::Directory,
&Handle::Port(_, _, _) => HandleType::Directory,
&Handle::Endpoints(_, _, _) => HandleType::Directory,
&Handle::PortDesc(_, _, _) => HandleType::File,
&Handle::TopLevel(_) => HandleType::Directory,
&Handle::Port(_, _) => HandleType::Directory,
&Handle::Endpoints(_, _) => HandleType::Directory,
&Handle::PortDesc(_, _) => HandleType::File,
&Handle::PortReq(_, PortReqState::WaitingForDeviceBytes(_, _)) => HandleType::Character,
&Handle::PortReq(_, PortReqState::WaitingForHostBytes(_, _)) => HandleType::Character,
&Handle::PortReq(_, PortReqState::Tmp) => unreachable!(),
&Handle::PortReq(_, PortReqState::TmpSetup(_)) => unreachable!(),
&Handle::PortState(_, _) => HandleType::Character,
&Handle::PortState(_) => HandleType::Character,
&Handle::PortReq(_, _) => HandleType::Character,
&Handle::ConfigureEndpoints(_) => HandleType::Character,
&Handle::Endpoint(_, _, ref st) => match st {
EndpointHandleTy::Data => HandleType::Character,
EndpointHandleTy::Ctl => HandleType::Character,
EndpointHandleTy::Root(_, _) => HandleType::Directory,
EndpointHandleTy::Root(_) => HandleType::Directory,
},
}
}
@@ -252,21 +253,21 @@ impl Handle {
/// Either the size of the buffer, or [Option::None] if the buffer does not exist.
pub(crate) fn get_buf_len(&self) -> Option<usize> {
match self {
&Handle::TopLevel(_, ref buf) => Some(buf.len()),
&Handle::Port(_, _, ref buf) => Some(buf.len()),
&Handle::Endpoints(_, _, ref buf) => Some(buf.len()),
&Handle::PortDesc(_, _, ref buf) => Some(buf.len()),
&Handle::TopLevel(ref buf) => Some(buf.len()),
&Handle::Port(_, ref buf) => Some(buf.len()),
&Handle::Endpoints(_, ref buf) => Some(buf.len()),
&Handle::PortDesc(_, ref buf) => Some(buf.len()),
&Handle::PortReq(_, PortReqState::WaitingForDeviceBytes(ref buf, _)) => Some(buf.len()),
&Handle::PortReq(_, PortReqState::WaitingForHostBytes(ref buf, _)) => Some(buf.len()),
&Handle::PortReq(_, PortReqState::Tmp) => None,
&Handle::PortReq(_, PortReqState::TmpSetup(_)) => None,
&Handle::PortState(_, _) => None,
&Handle::PortState(_) => None,
&Handle::PortReq(_, _) => None,
&Handle::ConfigureEndpoints(_) => None,
&Handle::Endpoint(_, _, ref st) => match st {
EndpointHandleTy::Data => None,
EndpointHandleTy::Ctl => None,
EndpointHandleTy::Root(_, ref buf) => Some(buf.len()),
EndpointHandleTy::Root(ref buf) => Some(buf.len()),
},
}
}
@@ -1551,13 +1552,11 @@ impl Xhci {
.dev_desc;
serde_json::to_vec(dev_desc).or(Err(Error::new(EIO)))
}
fn write_dyn_string(string: &[u8], buf: &mut [u8], offset: &mut usize) -> usize {
fn write_dyn_string(string: &[u8], buf: &mut [u8], offset: usize) -> usize {
let max_bytes_to_read = cmp::min(string.len(), buf.len());
let bytes_to_read = cmp::max(*offset, max_bytes_to_read) - *offset;
let bytes_to_read = cmp::max(offset, max_bytes_to_read) - offset;
buf[..bytes_to_read].copy_from_slice(&string[..bytes_to_read]);
*offset += bytes_to_read;
bytes_to_read
}
async fn port_req_transfer(
@@ -1735,7 +1734,7 @@ impl Xhci {
write!(contents, "port{}\n", index).unwrap();
}
Ok(Handle::TopLevel(0, contents))
Ok(Handle::TopLevel(contents))
} else {
Err(Error::new(EISDIR))
}
@@ -1758,7 +1757,7 @@ impl Xhci {
}
let contents = self.port_desc_json(port_num)?;
Ok(Handle::PortDesc(port_num, 0, contents))
Ok(Handle::PortDesc(port_num, contents))
}
/// implements open() for /port<n>
@@ -1792,7 +1791,7 @@ impl Xhci {
write!(contents, "configure\n").unwrap();
}
Ok(Handle::Port(port_num, 0, contents))
Ok(Handle::Port(port_num, contents))
} else {
Err(Error::new(EISDIR))
}
@@ -1814,7 +1813,7 @@ impl Xhci {
return Err(Error::new(ENOTDIR));
}
Ok(Handle::PortState(port_num, 0))
Ok(Handle::PortState(port_num))
}
/// implements open() for /port<n>/endpoints
@@ -1843,7 +1842,7 @@ impl Xhci {
write!(contents, "{}\n", ep_num).unwrap();
}
Ok(Handle::Endpoints(port_num, 0, contents))
Ok(Handle::Endpoints(port_num, contents))
}
/// implements open() for /port<n>/endpoints/<n>
@@ -1886,7 +1885,7 @@ impl Xhci {
Ok(Handle::Endpoint(
port_num,
endpoint_num,
EndpointHandleTy::Root(0, contents),
EndpointHandleTy::Root(contents),
))
}
@@ -1983,9 +1982,9 @@ impl Xhci {
}
}
impl Scheme for Xhci {
fn open(&self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
if uid != 0 {
impl Scheme for &Xhci {
fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
if ctx.uid != 0 {
return Err(Error::new(EACCES));
}
@@ -2025,11 +2024,14 @@ impl Scheme for Xhci {
self.handles.insert(fd, handle);
Ok(fd)
Ok(OpenResult::ThisScheme {
number: fd,
flags: NewFdFlags::POSITIONED,
})
}
fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
let mut guard = self.handles.get(&id).ok_or(Error::new(EBADF))?;
fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result<usize> {
let guard = self.handles.get(&id).ok_or(Error::new(EBADF))?;
stat.st_mode = match (&*guard).get_handle_type() {
HandleType::Directory => MODE_DIR,
@@ -2043,14 +2045,14 @@ impl Scheme for Xhci {
};
//If we have a handle to the configure scheme, we need to mark it as write only.
if let &Handle::ConfigureEndpoints(_) = (&*guard) {
if let &Handle::ConfigureEndpoints(_) = &*guard {
stat.st_mode = stat.st_mode | 0o200;
}
Ok(0)
}
fn fpath(&self, fd: usize, buffer: &mut [u8]) -> Result<usize> {
fn fpath(&mut self, fd: usize, buffer: &mut [u8]) -> Result<usize> {
let mut cursor = io::Cursor::new(buffer);
let guard = self.handles.get(&fd).ok_or(Error::new(EBADF))?;
@@ -2068,51 +2070,8 @@ impl Scheme for Xhci {
Ok(src_len)
}
fn seek(&self, fd: usize, pos: isize, whence: usize) -> Result<isize> {
let mut guard = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
trace!(
"SEEK fd={}, handle={:?}, pos {}, whence {}",
fd,
guard,
pos,
whence
);
match &mut *guard {
// Directories, or fixed files
Handle::TopLevel(ref mut offset, ref buf)
| Handle::Port(_, ref mut offset, ref buf)
| Handle::PortDesc(_, ref mut offset, ref buf)
| Handle::Endpoints(_, ref mut offset, ref buf)
| Handle::Endpoint(_, _, EndpointHandleTy::Root(ref mut offset, ref buf)) => {
let max = buf.len() as isize;
*offset = match whence {
SEEK_SET => cmp::max(0, cmp::min(pos, max)),
SEEK_CUR => cmp::max(0, cmp::min(*offset as isize + pos, max)),
SEEK_END => cmp::max(0, cmp::min(max + pos, max)),
_ => return Err(Error::new(EINVAL)),
} as usize;
Ok(*offset as isize)
}
Handle::PortState(_, ref mut offset) => {
match whence {
//TODO: checks for invalid pos
SEEK_SET => *offset = pos as usize,
SEEK_CUR => *offset = pos as usize,
SEEK_END => *offset = pos as usize,
_ => return Err(Error::new(EINVAL)),
};
Ok(*offset as isize)
}
// Write-once configure or transfer
Handle::Endpoint(_, _, _) | Handle::ConfigureEndpoints(_) | Handle::PortReq(_, _) => {
Err(Error::new(ESPIPE))
}
}
}
fn read(&self, fd: usize, buf: &mut [u8]) -> Result<usize> {
fn read(&mut self, fd: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
let offset = offset as usize;
let mut guard = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
trace!(
"READ fd={}, handle={:?}, buf=(addr {:p}, length {})",
@@ -2122,16 +2081,15 @@ impl Scheme for Xhci {
buf.len()
);
match &mut *guard {
Handle::TopLevel(ref mut offset, ref src_buf)
| Handle::Port(_, ref mut offset, ref src_buf)
| Handle::PortDesc(_, ref mut offset, ref src_buf)
| Handle::Endpoints(_, ref mut offset, ref src_buf)
| Handle::Endpoint(_, _, EndpointHandleTy::Root(ref mut offset, ref src_buf)) => {
Handle::TopLevel(ref src_buf)
| Handle::Port(_, ref src_buf)
| Handle::PortDesc(_, ref src_buf)
| Handle::Endpoints(_, ref src_buf)
| Handle::Endpoint(_, _, EndpointHandleTy::Root(ref src_buf)) => {
let max_bytes_to_read = cmp::min(src_buf.len(), buf.len());
let bytes_to_read = cmp::max(max_bytes_to_read, *offset) - *offset;
let bytes_to_read = cmp::max(max_bytes_to_read, offset) - offset;
buf[..bytes_to_read].copy_from_slice(&src_buf[..bytes_to_read]);
*offset += bytes_to_read;
Ok(bytes_to_read)
}
@@ -2140,9 +2098,9 @@ impl Scheme for Xhci {
&mut Handle::Endpoint(port_num, endp_num, ref mut st) => match st {
EndpointHandleTy::Ctl => self.on_read_endp_ctl(port_num, endp_num, buf),
EndpointHandleTy::Data => block_on(self.on_read_endp_data(port_num, endp_num, buf)),
EndpointHandleTy::Root(_, _) => Err(Error::new(EBADF)),
EndpointHandleTy::Root(_) => Err(Error::new(EBADF)),
},
&mut Handle::PortState(port_num, ref mut offset) => {
&mut Handle::PortState(port_num) => {
let ps = self.port_states.get(&port_num).ok_or(Error::new(EBADF))?;
let state = self
.dev_ctx
@@ -2164,7 +2122,7 @@ impl Scheme for Xhci {
.unwrap_or("unknown")
.as_bytes();
Ok(Self::write_dyn_string(string, buf, offset))
Ok(Xhci::write_dyn_string(string, buf, offset))
}
&mut Handle::PortReq(port_num, ref mut st) => {
let state = std::mem::replace(st, PortReqState::Tmp);
@@ -2173,7 +2131,7 @@ impl Scheme for Xhci {
}
}
}
fn write(&self, fd: usize, buf: &[u8]) -> Result<usize> {
fn write(&mut self, fd: usize, buf: &[u8], _offset: u64, _fcntl_flags: u32) -> Result<usize> {
let mut guard = self.handles.get_mut(&fd).ok_or(Error::new(EBADF))?;
trace!(
"WRITE fd={}, handle={:?}, buf=(addr {:p}, length {})",
@@ -2193,7 +2151,7 @@ impl Scheme for Xhci {
EndpointHandleTy::Data => {
block_on(self.on_write_endp_data(port_num, endp_num, buf))
}
EndpointHandleTy::Root(_, _) => return Err(Error::new(EBADF)),
EndpointHandleTy::Root(_) => return Err(Error::new(EBADF)),
},
&mut Handle::PortReq(port_num, ref mut st) => {
let state = std::mem::replace(st, PortReqState::Tmp);
@@ -2205,7 +2163,7 @@ impl Scheme for Xhci {
_ => Err(Error::new(EBADF)),
}
}
fn close(&self, fd: usize) -> Result<usize> {
fn close(&mut self, fd: usize) -> Result<usize> {
if self.handles.remove(&fd).is_none() {
return Err(Error::new(EBADF));
}