Use redox-scheme in driver-network
This commit is contained in:
Generated
+1
@@ -401,6 +401,7 @@ name = "driver-network"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox-scheme",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
|
||||
@@ -5,4 +5,5 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
libredox = "0.1.3"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
redox_syscall = "0.5"
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::{ErrorKind, Read, Write};
|
||||
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
||||
use std::{cmp, io};
|
||||
|
||||
use libredox::flag;
|
||||
use libredox::Fd;
|
||||
use redox_scheme::{CallRequest, RequestKind, Response, SchemeBlockMut, SignalBehavior, Socket};
|
||||
use syscall::{
|
||||
Error, EventFlags, Packet, Result, SchemeBlockMut, Stat, EACCES, EBADF, EINVAL, EWOULDBLOCK,
|
||||
MODE_FILE, O_NONBLOCK,
|
||||
Error, EventFlags, Result, Stat, EACCES, EAGAIN, EBADF, EINTR, EINVAL, EWOULDBLOCK, MODE_FILE,
|
||||
O_NONBLOCK,
|
||||
};
|
||||
|
||||
pub trait NetworkAdapter {
|
||||
@@ -32,10 +30,10 @@ pub trait NetworkAdapter {
|
||||
pub struct NetworkScheme<T: NetworkAdapter> {
|
||||
adapter: T,
|
||||
scheme_name: String,
|
||||
scheme: File,
|
||||
socket: Socket,
|
||||
next_id: usize,
|
||||
handles: BTreeMap<usize, Handle>,
|
||||
todo_packets: Vec<Packet>,
|
||||
blocked: Vec<CallRequest>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@@ -47,26 +45,20 @@ enum Handle {
|
||||
impl<T: NetworkAdapter> NetworkScheme<T> {
|
||||
pub fn new(adapter: T, scheme_name: String) -> Self {
|
||||
assert!(scheme_name.starts_with("network"));
|
||||
let scheme_fd = libredox::call::open(
|
||||
format!(":{scheme_name}"),
|
||||
flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK,
|
||||
0,
|
||||
)
|
||||
.expect("failed to create network scheme");
|
||||
let scheme = unsafe { File::from_raw_fd(scheme_fd as RawFd) };
|
||||
let socket = Socket::nonblock(&scheme_name).expect("failed to create network scheme");
|
||||
|
||||
NetworkScheme {
|
||||
adapter,
|
||||
scheme_name,
|
||||
scheme,
|
||||
socket,
|
||||
next_id: 0,
|
||||
handles: BTreeMap::new(),
|
||||
todo_packets: vec![],
|
||||
blocked: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event_handle(&self) -> RawFd {
|
||||
self.scheme.as_raw_fd()
|
||||
pub fn event_handle(&self) -> &Fd {
|
||||
self.socket.inner()
|
||||
}
|
||||
|
||||
pub fn adapter(&self) -> &T {
|
||||
@@ -86,41 +78,53 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
|
||||
// to call when an irq is received to indicate that blocked packets can
|
||||
// be processed.
|
||||
pub fn tick(&mut self) -> io::Result<()> {
|
||||
// Handle any blocked packets
|
||||
// Handle any blocked requests
|
||||
let mut i = 0;
|
||||
while i < self.todo_packets.len() {
|
||||
let mut packet = self.todo_packets[i].clone();
|
||||
if let Some(a) = self.handle(&packet) {
|
||||
self.todo_packets.remove(i);
|
||||
packet.a = a;
|
||||
self.scheme.write(&packet)?;
|
||||
while i < self.blocked.len() {
|
||||
if let Some(resp) = self.blocked[i].handle_scheme_block_mut(self) {
|
||||
self.socket
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("vesad: failed to write display scheme");
|
||||
self.blocked.remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle new scheme packets
|
||||
// Handle new scheme requests
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
match self.scheme.read(&mut packet) {
|
||||
Ok(0) => {
|
||||
return Err(io::Error::new(
|
||||
ErrorKind::BrokenPipe,
|
||||
"scheme has been closed by the kernel",
|
||||
));
|
||||
let request = match self.socket.next_request(SignalBehavior::Restart) {
|
||||
Ok(Some(request)) => request,
|
||||
Ok(None) => {
|
||||
// Scheme likely got unmounted
|
||||
std::process::exit(0);
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(err) if err.kind() == ErrorKind::WouldBlock => break,
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
Err(err) if err.errno == EAGAIN => break,
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
|
||||
if let Some(a) = self.handle(&packet) {
|
||||
packet.a = a;
|
||||
self.scheme.write(&packet)?;
|
||||
} else {
|
||||
self.todo_packets.push(packet);
|
||||
match request.kind() {
|
||||
RequestKind::Call(call_request) => {
|
||||
if let Some(resp) = call_request.handle_scheme_block_mut(self) {
|
||||
self.socket.write_response(resp, SignalBehavior::Restart)?;
|
||||
} else {
|
||||
self.blocked.push(call_request);
|
||||
}
|
||||
}
|
||||
RequestKind::Cancellation(cancellation_request) => {
|
||||
if let Some(i) = self
|
||||
.blocked
|
||||
.iter()
|
||||
.position(|req| req.request().request_id() == cancellation_request.id)
|
||||
{
|
||||
let blocked_req = self.blocked.remove(i);
|
||||
let resp = Response::new(&blocked_req, Err(syscall::Error::new(EINTR)));
|
||||
self.socket.write_response(resp, SignalBehavior::Restart)?;
|
||||
}
|
||||
}
|
||||
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,16 +132,8 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
|
||||
let available_for_read = self.adapter.available_for_read();
|
||||
if available_for_read > 0 {
|
||||
for &handle_id in self.handles.keys() {
|
||||
self.scheme.write(&Packet {
|
||||
id: 0,
|
||||
pid: 0,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
a: syscall::number::SYS_FEVENT,
|
||||
b: handle_id,
|
||||
c: syscall::flag::EVENT_READ.bits(),
|
||||
d: available_for_read,
|
||||
})?;
|
||||
self.socket
|
||||
.post_fevent(handle_id, syscall::flag::EVENT_READ.bits())?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@@ -174,7 +170,13 @@ impl<T: NetworkAdapter> SchemeBlockMut for NetworkScheme<T> {
|
||||
Ok(Some(self.next_id))
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
fn read(
|
||||
&mut self,
|
||||
id: usize,
|
||||
buf: &mut [u8],
|
||||
_offset: u64,
|
||||
_fcntl_flags: u32,
|
||||
) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let flags = match *handle {
|
||||
@@ -200,7 +202,13 @@ impl<T: NetworkAdapter> SchemeBlockMut for NetworkScheme<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
fn write(
|
||||
&mut self,
|
||||
id: usize,
|
||||
buf: &[u8],
|
||||
_offset: u64,
|
||||
_fcntl_flags: u32,
|
||||
) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
match handle {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
use std::cell::RefCell;
|
||||
use std::convert::Infallible;
|
||||
use std::io::{Read, Result, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::rc::Rc;
|
||||
|
||||
use driver_network::NetworkScheme;
|
||||
use event::{user_data, EventQueue};
|
||||
use pcid_interface::PciFunctionHandle;
|
||||
use syscall::EventFlags;
|
||||
|
||||
pub mod device;
|
||||
|
||||
@@ -46,7 +42,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
let mut event_queue =
|
||||
let event_queue =
|
||||
EventQueue::<Source>::new().expect("e1000d: failed to create event queue");
|
||||
|
||||
event_queue
|
||||
@@ -58,7 +54,7 @@ fn main() {
|
||||
.expect("e1000d: failed to subscribe to IRQ fd");
|
||||
event_queue
|
||||
.subscribe(
|
||||
scheme.event_handle() as usize,
|
||||
scheme.event_handle().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
use std::cell::RefCell;
|
||||
use std::convert::Infallible;
|
||||
use std::io::{Read, Result, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::rc::Rc;
|
||||
|
||||
use driver_network::NetworkScheme;
|
||||
use event::{user_data, EventQueue};
|
||||
use pcid_interface::PciFunctionHandle;
|
||||
use syscall::EventFlags;
|
||||
|
||||
pub mod device;
|
||||
#[rustfmt::skip]
|
||||
@@ -47,7 +43,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
let mut event_queue =
|
||||
let event_queue =
|
||||
EventQueue::<Source>::new().expect("ixgbed: Could not create event queue.");
|
||||
event_queue
|
||||
.subscribe(
|
||||
@@ -58,7 +54,7 @@ fn main() {
|
||||
.unwrap();
|
||||
event_queue
|
||||
.subscribe(
|
||||
scheme.event_handle() as usize,
|
||||
scheme.event_handle().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#![feature(int_roundings)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::convert::{Infallible, TryInto};
|
||||
use std::convert::TryInto;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Result, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
|
||||
use driver_network::NetworkScheme;
|
||||
use event::{user_data, EventQueue};
|
||||
@@ -18,7 +16,6 @@ use pcid_interface::{
|
||||
MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo,
|
||||
SubdriverArguments,
|
||||
};
|
||||
use syscall::EventFlags;
|
||||
|
||||
pub mod device;
|
||||
|
||||
@@ -221,7 +218,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
let mut event_queue =
|
||||
let event_queue =
|
||||
EventQueue::<Source>::new().expect("rtl8139d: Could not create event queue.");
|
||||
event_queue
|
||||
.subscribe(
|
||||
@@ -232,7 +229,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
.unwrap();
|
||||
event_queue
|
||||
.subscribe(
|
||||
scheme.event_handle() as usize,
|
||||
scheme.event_handle().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use std::cell::RefCell;
|
||||
use std::convert::{Infallible, TryInto};
|
||||
use std::convert::TryInto;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Result, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
|
||||
use driver_network::NetworkScheme;
|
||||
use event::{user_data, EventQueue};
|
||||
@@ -16,7 +14,6 @@ use pcid_interface::{
|
||||
MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo,
|
||||
SubdriverArguments,
|
||||
};
|
||||
use syscall::EventFlags;
|
||||
|
||||
pub mod device;
|
||||
|
||||
@@ -219,8 +216,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
let mut event_queue =
|
||||
EventQueue::<Source>::new().expect("rtl8168d: Could not create event queue.");
|
||||
let event_queue = EventQueue::<Source>::new().expect("rtl8168d: Could not create event queue.");
|
||||
event_queue
|
||||
.subscribe(
|
||||
irq_file.as_raw_fd() as usize,
|
||||
@@ -230,7 +226,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
.unwrap();
|
||||
event_queue
|
||||
.subscribe(
|
||||
scheme.event_handle() as usize,
|
||||
scheme.event_handle().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
|
||||
@@ -97,7 +97,7 @@ fn deamon(daemon: redox_daemon::Daemon) -> Result<(), Box<dyn std::error::Error>
|
||||
|
||||
let mut event_queue = File::open("/scheme/event")?;
|
||||
event_queue.write(&syscall::Event {
|
||||
id: scheme.event_handle() as usize,
|
||||
id: scheme.event_handle().raw(),
|
||||
flags: syscall::EVENT_READ,
|
||||
data: 0,
|
||||
})?;
|
||||
|
||||
Reference in New Issue
Block a user