From a5d502625e9d8c6a784fb04f8a3f40d791466f66 Mon Sep 17 00:00:00 2001 From: Ibuki Omatsu Date: Sat, 29 Nov 2025 14:20:44 +0000 Subject: [PATCH] feat: Update some drivers to latest redox-scheme from the legacy scheme. --- Cargo.lock | 14 ++ audio/ac97d/Cargo.toml | 1 + audio/ac97d/src/device.rs | 44 +++-- audio/ac97d/src/main.rs | 100 +++++------ audio/ihdad/Cargo.toml | 1 + audio/ihdad/src/hda/device.rs | 133 +++++++------- audio/ihdad/src/main.rs | 105 +++++------- audio/sb16d/Cargo.toml | 1 + audio/sb16d/src/device.rs | 39 +++-- audio/sb16d/src/main.rs | 100 +++++------ net/alxd/Cargo.toml | 1 + net/alxd/src/device/mod.rs | 315 ++++++++++++++++++---------------- net/alxd/src/main.rs | 99 +++++------ 13 files changed, 469 insertions(+), 484 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c10dbb4064..e1130c6e7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "log", "pcid", "redox-daemon", + "redox-scheme 0.8.2", "redox_event", "redox_syscall", "spin 0.9.8", @@ -87,6 +88,7 @@ dependencies = [ "common", "libredox", "redox-daemon", + "redox-scheme 0.8.2", "redox_event", "redox_syscall", ] @@ -694,6 +696,7 @@ dependencies = [ "log", "pcid", "redox-daemon", + "redox-scheme 0.8.2", "redox_event", "redox_syscall", "spin 0.9.8", @@ -1137,6 +1140,16 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "redox-scheme" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54adf6001069dfc77e8e9f62dc62d4c9c1471fff65ca577ca140f0e9bdf4e10" +dependencies = [ + "libredox", + "redox_syscall", +] + [[package]] name = "redox_event" version = "0.4.1" @@ -1277,6 +1290,7 @@ dependencies = [ "libredox", "log", "redox-daemon", + "redox-scheme 0.8.2", "redox_event", "redox_syscall", "spin 0.9.8", diff --git a/audio/ac97d/Cargo.toml b/audio/ac97d/Cargo.toml index 2e97f0a1aa..3eea94c5bd 100644 --- a/audio/ac97d/Cargo.toml +++ b/audio/ac97d/Cargo.toml @@ -14,3 +14,4 @@ redox_syscall = "0.5" spin = "0.9" pcid = { path = "../../pcid" } +redox-scheme = "0.8.2" diff --git a/audio/ac97d/src/device.rs b/audio/ac97d/src/device.rs index 5785f67c0f..da73fb54be 100644 --- a/audio/ac97d/src/device.rs +++ b/audio/ac97d/src/device.rs @@ -4,8 +4,12 @@ use std::collections::BTreeMap; use std::sync::atomic::{AtomicUsize, Ordering}; use common::io::Pio; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::CallerCtx; +use redox_scheme::OpenResult; use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, ENOENT}; -use syscall::scheme::SchemeBlockMut; +use syscall::schemev2::NewFdFlags; +use syscall::EWOULDBLOCK; use common::{ dma::Dma, @@ -257,18 +261,28 @@ impl Ac97 { } } -impl SchemeBlockMut for Ac97 { - fn open(&mut self, _path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { - if uid == 0 { +impl SchemeSync for Ac97 { + fn open(&mut self, _path: &str, _flags: usize, ctx: &CallerCtx) -> Result { + if ctx.uid == 0 { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.lock().insert(id, Handle::Todo); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } else { Err(Error::new(EACCES)) } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { { let mut handles = self.handles.lock(); let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; @@ -282,7 +296,7 @@ impl SchemeBlockMut for Ac97 { let mut lvi = self.bus.po.lvi.read() as usize; if lvi == (civ + 3) % NUM_SUB_BUFFS { // Block if we already are 3 buffers ahead - Ok(None) + Err(Error::new(EWOULDBLOCK)) } else { // Fill next buffer lvi = (lvi + 1) % NUM_SUB_BUFFS; @@ -291,28 +305,24 @@ impl SchemeBlockMut for Ac97 { } self.bus.po.lvi.write(lvi as u8); - Ok(Some(SUB_BUFF_SIZE)) + Ok(SUB_BUFF_SIZE) } } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { let mut handles = self.handles.lock(); let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; let mut i = 0; - let scheme_path = b"audiohw:"; + let scheme_path = b"/scheme/audiohw"; while i < buf.len() && i < scheme_path.len() { buf[i] = scheme_path[i]; i += 1; } - Ok(Some(i)) + Ok(i) } - fn close(&mut self, id: usize) -> Result> { - let mut handles = self.handles.lock(); - handles - .remove(&id) - .ok_or(Error::new(EBADF)) - .and(Ok(Some(0))) + fn on_close(&mut self, id: usize) { + let _ = self.handles.lock().remove(&id); } } diff --git a/audio/ac97d/src/main.rs b/audio/ac97d/src/main.rs index f37e2b0f5a..0e786d5d64 100644 --- a/audio/ac97d/src/main.rs +++ b/audio/ac97d/src/main.rs @@ -5,15 +5,15 @@ extern crate event; extern crate spin; extern crate syscall; -use std::fs::File; -use std::io::{ErrorKind, Read, Write}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::io::{Read, Write}; +use std::os::unix::io::AsRawFd; use std::usize; use event::{user_data, EventQueue}; -use libredox::flag; use pcid_interface::PciFunctionHandle; -use syscall::{Packet, SchemeBlockMut}; +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::Socket; +use std::cell::RefCell; pub mod device; @@ -49,15 +49,11 @@ fn main() { let mut irq_file = irq.irq_handle("ac97d"); - let mut device = - unsafe { device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") }; - let socket_fd = libredox::call::open( - ":audiohw", - flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, - 0, - ) - .expect("ac97d: failed to create hda scheme"); - let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; + let device = RefCell::new(unsafe { + device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") + }); + let socket = Socket::nonblock("audiohw").expect("ac97d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); user_data! { enum Source { @@ -76,17 +72,19 @@ fn main() { ) .unwrap(); event_queue - .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) .unwrap(); daemon.ready().expect("ac97d: failed to signal readiness"); libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace"); - let mut todo = Vec::::new(); - let all = [Source::Irq, Source::Scheme]; - 'events: for event in all + for event in all .into_iter() .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) { @@ -95,49 +93,35 @@ fn main() { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if device.irq() { - irq_file.write(&mut irq).unwrap(); - - let mut i = 0; - while i < todo.len() { - if let Some(a) = device.handle(&mut todo[i]) { - let mut packet = todo.remove(i); - packet.a = a; - socket.write(&packet).unwrap(); - } else { - i += 1; - } - } - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + if !device.borrow_mut().irq() { + continue; } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ac97d: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } Source::Scheme => { - loop { - let mut packet = Packet::default(); - match socket.read(&mut packet) { - Ok(0) => break 'events, - Ok(_) => (), - Err(err) => { - if err.kind() == ErrorKind::WouldBlock { - break; - } else { - panic!("ac97d: failed to read socket: {err}"); - } - } - } - - if let Some(a) = device.handle(&mut packet) { - packet.a = a; - socket.write(&packet).unwrap(); - } else { - todo.push(packet); - } + if !readiness_based + .read_requests() + .expect("ac97d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("ac97d: failed to write to socket") + { + break; } /* diff --git a/audio/ihdad/Cargo.toml b/audio/ihdad/Cargo.toml index 4bd093ad88..83fc34df63 100644 --- a/audio/ihdad/Cargo.toml +++ b/audio/ihdad/Cargo.toml @@ -14,3 +14,4 @@ spin = "0.9" common = { path = "../../common" } pcid = { path = "../../pcid" } +redox-scheme = "0.8.2" diff --git a/audio/ihdad/src/hda/device.rs b/audio/ihdad/src/hda/device.rs index df50cf13bd..d48ed0def8 100755 --- a/audio/ihdad/src/hda/device.rs +++ b/audio/ihdad/src/hda/device.rs @@ -6,17 +6,20 @@ use std::collections::HashMap; use std::fmt::Write; use std::str; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::task::Poll; use std::thread; use std::time::Duration; use common::dma::Dma; use common::io::{Io, Mmio}; use common::timeout::Timeout; -use syscall::error::{Error, Result, EACCES, EBADF, EIO, EINVAL, ENODEV}; -use syscall::flag::{SEEK_CUR, SEEK_END, SEEK_SET}; -use syscall::scheme::SchemeBlockMut; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::CallerCtx; +use redox_scheme::OpenResult; +use syscall::error::{Error, Result, EACCES, EBADF, EINVAL, EIO, ENODEV, EWOULDBLOCK}; use spin::Mutex; +use syscall::schemev2::NewFdFlags; use super::common::*; use super::BitsPerSample; @@ -65,7 +68,7 @@ enum Handle { Todo, Pcmout(usize, usize, usize), // Card, index, block_ptr Pcmin(usize, usize, usize), // Card, index, block_ptr - StrBuf(Vec, usize), + StrBuf(Vec), } #[repr(C, packed)] @@ -389,7 +392,7 @@ impl IntelHDA { pub fn find_best_output_pin(&mut self) -> Result { let outs = &self.output_pins; if outs.len() == 1 { - return Ok(outs[0]) + return Ok(outs[0]); } else if outs.len() > 1 { //TODO: change output based on "unsolicited response" interrupts // Check for devices in this order: Headphone, Speaker, Line Out @@ -412,7 +415,6 @@ impl IntelHDA { } } } - } Err(Error::new(ENODEV)) } @@ -864,7 +866,7 @@ impl IntelHDA { Ok(()) } - pub fn write_to_output(&mut self, index: u8, buf: &[u8]) -> Result> { + pub fn write_to_output(&mut self, index: u8, buf: &[u8]) -> Poll> { let output = self.get_output_stream_descriptor(index as usize).unwrap(); let os = self.output_streams.get_mut(index as usize).unwrap(); @@ -875,9 +877,9 @@ impl IntelHDA { if os.current_block() == (open_block + 3) % NUM_SUB_BUFFS { // Block if we already are 3 buffers ahead - Ok(None) + Poll::Pending } else { - os.write_block(buf).map(|count| Some(count)) + Poll::Ready(os.write_block(buf)) } } @@ -982,8 +984,8 @@ impl Drop for IntelHDA { } } -impl SchemeBlockMut for IntelHDA { - fn open(&mut self, path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { +impl SchemeSync for IntelHDA { + fn open(&mut self, path: &str, _flags: usize, ctx: &CallerCtx) -> Result { //let path: Vec<&str>; /* match str::from_utf8(_path) { @@ -997,37 +999,54 @@ impl SchemeBlockMut for IntelHDA { }*/ // TODO: - if uid == 0 { - let handle = match path.trim_matches('/') { - //TODO: allow multiple codecs - "codec" => Handle::StrBuf(self.dump_codec(0).into_bytes(), 0), - _ => Handle::Todo, - }; - let id = self.next_id.fetch_add(1, Ordering::SeqCst); - self.handles.lock().insert(id, handle); - Ok(Some(id)) - } else { - Err(Error::new(EACCES)) + if ctx.uid != 0 { + return Err(Error::new(EACCES)); } + let handle = match path.trim_matches('/') { + //TODO: allow multiple codecs + "codec" => Handle::StrBuf(self.dump_codec(0).into_bytes()), + _ => Handle::Todo, + }; + let id = self.next_id.fetch_add(1, Ordering::Relaxed); + self.handles.lock().insert(id, handle); + + // TODO: always positioned? + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::POSITIONED, + }) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::StrBuf(ref strbuf, ref mut size) => { - let mut i = 0; - while i < buf.len() && *size < strbuf.len() { - buf[i] = strbuf[*size]; - i += 1; - *size += 1; - } - Ok(Some(i)) - } - _ => Err(Error::new(EBADF)), - } + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { + let handles = self.handles.lock(); + let Some(Handle::StrBuf(strbuf)) = handles.get(&id) else { + return Err(Error::new(EBADF)); + }; + + let src = usize::try_from(offset) + .ok() + .and_then(|o| strbuf.get(o..)) + .unwrap_or(&[]); + let len = src.len().min(buf.len()); + buf[..len].copy_from_slice(&src[..len]); + Ok(len) } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { let index = { let mut handles = self.handles.lock(); match handles.get_mut(&id).ok_or(Error::new(EBADF))? { @@ -1038,50 +1057,26 @@ impl SchemeBlockMut for IntelHDA { //log::debug!("Int count: {}", self.int_counter); - self.write_to_output(index, buf) - } - - fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result> { - let pos = pos as usize; - let mut handles = self.handles.lock(); - match *handles.get_mut(&id).ok_or(Error::new(EBADF))? { - Handle::StrBuf(ref mut strbuf, ref mut size) => { - let len = strbuf.len() as usize; - *size = match whence { - SEEK_SET => cmp::min(len, pos), - SEEK_CUR => { - cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize - } - SEEK_END => { - cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize - } - _ => return Err(Error::new(EINVAL)), - }; - Ok(Some(*size as isize)) - } - - _ => Err(Error::new(EINVAL)), + match self.write_to_output(index, buf) { + Poll::Ready(r) => r, + Poll::Pending => Err(Error::new(EWOULDBLOCK)), } } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { let mut handles = self.handles.lock(); let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; let mut i = 0; - let scheme_path = b"audiohw:"; + let scheme_path = b"/scheme/audiohw"; while i < buf.len() && i < scheme_path.len() { buf[i] = scheme_path[i]; i += 1; } - Ok(Some(i)) + Ok(i) } - fn close(&mut self, id: usize) -> Result> { - let mut handles = self.handles.lock(); - handles - .remove(&id) - .ok_or(Error::new(EBADF)) - .and(Ok(Some(0))) + fn on_close(&mut self, id: usize) { + let _ = self.handles.lock().remove(&id); } } diff --git a/audio/ihdad/src/main.rs b/audio/ihdad/src/main.rs index 3d9d32ca73..c1f4cd681f 100755 --- a/audio/ihdad/src/main.rs +++ b/audio/ihdad/src/main.rs @@ -3,12 +3,13 @@ extern crate event; extern crate spin; extern crate syscall; -use libredox::flag; +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::Socket; +use std::cell::RefCell; use std::fs::File; -use std::io::{ErrorKind, Read, Write}; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::io::{Read, Write}; +use std::os::unix::io::AsRawFd; use std::usize; -use syscall::{Packet, SchemeBlockMut}; use event::{user_data, EventQueue}; use pcid_interface::irq_helpers::pci_allocate_interrupt_vector; @@ -56,24 +57,22 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let socket_fd = libredox::call::open( - ":audiohw", - flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, - 0, - ) - .expect("ihdad: failed to create hda scheme"); - let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; + let event_queue = + EventQueue::::new().expect("ihdad: Could not create event queue."); + let device = RefCell::new(unsafe { + hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") + }); + let socket = Socket::nonblock("audiohw").expect("ihdad: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); daemon.ready().expect("ihdad: failed to signal readiness"); - let event_queue = - EventQueue::::new().expect("ihdad: Could not create event queue."); - let mut device = unsafe { - hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device") - }; - event_queue - .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) .unwrap(); event_queue .subscribe( @@ -85,11 +84,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { libredox::call::setrens(0, 0).expect("ihdad: failed to enter null namespace"); - let mut todo = Vec::::new(); - let all = [Source::Irq, Source::Scheme]; - 'events: for event in all + for event in all .into_iter() .chain(event_queue.map(|e| e.expect("failed to get next event").user_data)) { @@ -98,49 +95,35 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if device.irq() { - irq_file.write(&mut irq).unwrap(); - - let mut i = 0; - while i < todo.len() { - if let Some(a) = device.handle(&mut todo[i]) { - let mut packet = todo.remove(i); - packet.a = a; - socket.write(&packet).unwrap(); - } else { - i += 1; - } - } - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + if !device.borrow_mut().irq() { + continue; } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ihdad: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ } Source::Scheme => { - loop { - let mut packet = Packet::default(); - match socket.read(&mut packet) { - Ok(0) => break 'events, - Ok(_) => (), - Err(err) => { - if err.kind() == ErrorKind::WouldBlock { - break; - } else { - panic!("ihdad: failed to read from socket: {err}"); - } - } - } - - if let Some(a) = device.handle(&mut packet) { - packet.a = a; - socket.write(&packet).unwrap(); - } else { - todo.push(packet); - } + if !readiness_based + .read_requests() + .expect("ihdad: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("ihdad: failed to write to socket") + { + break; } /* diff --git a/audio/sb16d/Cargo.toml b/audio/sb16d/Cargo.toml index 29ff243ab8..7e6112edaf 100644 --- a/audio/sb16d/Cargo.toml +++ b/audio/sb16d/Cargo.toml @@ -12,3 +12,4 @@ redox-daemon = "0.1" redox_event = "0.4.1" redox_syscall = "0.5" spin = "0.9" +redox-scheme = "0.8.2" diff --git a/audio/sb16d/src/device.rs b/audio/sb16d/src/device.rs index 36a6e94b8c..ae9f4a0f04 100644 --- a/audio/sb16d/src/device.rs +++ b/audio/sb16d/src/device.rs @@ -6,8 +6,11 @@ use std::{thread, time}; use common::io::{Io, Pio, ReadOnly, WriteOnly}; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::CallerCtx; +use redox_scheme::OpenResult; use syscall::error::{Error, Result, EACCES, EBADF, ENODEV}; -use syscall::scheme::SchemeBlockMut; +use syscall::schemev2::NewFdFlags; use spin::Mutex; @@ -181,40 +184,46 @@ impl Sb16 { } } -impl SchemeBlockMut for Sb16 { - fn open(&mut self, _path: &str, _flags: usize, uid: u32, _gid: u32) -> Result> { - if uid == 0 { +impl SchemeSync for Sb16 { + fn open(&mut self, _path: &str, _flags: usize, ctx: &CallerCtx) -> Result { + if ctx.uid == 0 { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.lock().insert(id, Handle::Todo); - Ok(Some(id)) + Ok(OpenResult::ThisScheme { + number: id, + flags: NewFdFlags::empty(), + }) } else { Err(Error::new(EACCES)) } } - fn write(&mut self, _id: usize, _buf: &[u8]) -> Result> { + fn write( + &mut self, + _id: usize, + _buf: &[u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { //TODO Err(Error::new(EBADF)) } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result { let mut handles = self.handles.lock(); let _handle = handles.get_mut(&id).ok_or(Error::new(EBADF))?; let mut i = 0; - let scheme_path = b"audiohw:"; + let scheme_path = b"/scheme/audiohw"; while i < buf.len() && i < scheme_path.len() { buf[i] = scheme_path[i]; i += 1; } - Ok(Some(i)) + Ok(i) } - fn close(&mut self, id: usize) -> Result> { - let mut handles = self.handles.lock(); - handles - .remove(&id) - .ok_or(Error::new(EBADF)) - .and(Ok(Some(0))) + fn on_close(&mut self, id: usize) { + let _ = self.handles.lock().remove(&id); } } diff --git a/audio/sb16d/src/main.rs b/audio/sb16d/src/main.rs index bf5c7227db..4c47f46d1d 100644 --- a/audio/sb16d/src/main.rs +++ b/audio/sb16d/src/main.rs @@ -1,9 +1,10 @@ //#![deny(warnings)] -use libredox::errno::{EAGAIN, EWOULDBLOCK}; use libredox::{flag, Fd}; +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::Socket; +use std::cell::RefCell; use std::{env, usize}; -use syscall::{Packet, SchemeBlockMut}; use event::{user_data, EventQueue}; @@ -29,17 +30,14 @@ fn main() { common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); - let mut device = - unsafe { device::Sb16::new(addr).expect("sb16d: failed to allocate device") }; - let socket = Fd::open( - ":audiohw", - flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, - 0, - ) - .expect("sb16d: failed to create hda scheme"); + let device = RefCell::new(unsafe { + device::Sb16::new(addr).expect("sb16d: failed to allocate device") + }); + let socket = Socket::nonblock("audiohw").expect("sb16d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); //TODO: error on multiple IRQs? - let irq_file = match device.irqs.first() { + let irq_file = match device.borrow().irqs.first() { Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) .expect("sb16d: failed to open IRQ file"), None => panic!("sb16d: no IRQs found"), @@ -57,18 +55,20 @@ fn main() { .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) .unwrap(); event_queue - .subscribe(socket.raw(), Source::Scheme, event::EventFlags::READ) + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) .unwrap(); daemon.ready().expect("sb16d: failed to signal readiness"); libredox::call::setrens(0, 0).expect("sb16d: failed to enter null namespace"); - let mut todo = Vec::::new(); - let all = [Source::Irq, Source::Scheme]; - 'events: for event in all + for event in all .into_iter() .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) { @@ -77,53 +77,37 @@ fn main() { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if device.irq() { - irq_file.write(&mut irq).unwrap(); + if !device.borrow_mut().irq() { + continue; + } + irq_file.write(&mut irq).unwrap(); - let mut i = 0; - while i < todo.len() { - if let Some(a) = device.handle(&mut todo[i]) { - let mut packet = todo.remove(i); - packet.a = a; - socket - .write(&packet) - .expect("sb16d: failed to write to socket"); - } else { - i += 1; - } - } + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("sb16d: failed to poll requests"); - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("sb16d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("sb16d: failed to write to socket") + { + break; } } - Source::Scheme => loop { - let mut packet = Packet::default(); - match socket.read(&mut packet) { - Ok(0) => break 'events, - Ok(_) => (), - Err(err) => { - if err.errno() == EWOULDBLOCK || err.errno() == EAGAIN { - break; - } else { - panic!("sb16d: failed to read from scheme socket"); - } - } - } - - if let Some(a) = device.handle(&mut packet) { - packet.a = a; - socket - .write(&packet) - .expect("sb16d: failed to write to scheme socket"); - } else { - todo.push(packet); - } - }, } } diff --git a/net/alxd/Cargo.toml b/net/alxd/Cargo.toml index af09892e0b..312da94841 100644 --- a/net/alxd/Cargo.toml +++ b/net/alxd/Cargo.toml @@ -11,3 +11,4 @@ redox-daemon = "0.1" common = { path = "../../common" } libredox = "0.1.3" +redox-scheme = "0.8.2" diff --git a/net/alxd/src/device/mod.rs b/net/alxd/src/device/mod.rs index 17746e8f2e..94a09b8a86 100644 --- a/net/alxd/src/device/mod.rs +++ b/net/alxd/src/device/mod.rs @@ -2,9 +2,12 @@ use std::convert::TryInto; use std::{ptr, thread, time}; use common::io::{Io, Mmio}; +use redox_scheme::scheme::SchemeSync; +use redox_scheme::CallerCtx; +use redox_scheme::OpenResult; use syscall::error::{Error, Result, EACCES, EINVAL, EIO, EWOULDBLOCK}; use syscall::flag::{EventFlags, O_NONBLOCK}; -use syscall::scheme; +use syscall::schemev2::NewFdFlags; use common::dma::Dma; @@ -368,7 +371,7 @@ impl Alx { */ self.imask &= !ISR_PHY; let imask = self.imask; - self.write(IMR, imask); + self.reg_write(IMR, imask); self.flag |= FLAG_TASK_CHK_LINK; self.task(); } @@ -379,7 +382,7 @@ impl Alx { unsafe fn intr_1(&mut self, mut intr: u32) -> bool { /* ACK interrupt */ println!("ACK interrupt: {:X}", intr | ISR_DIS); - self.write(ISR, intr | ISR_DIS); + self.reg_write(ISR, intr | ISR_DIS); intr &= self.imask; if (self.handle_intr_misc(intr)) { @@ -392,19 +395,19 @@ impl Alx { /* mask rx/tx interrupt, enable them when napi complete */ self.imask &= !ISR_ALL_QUEUES; let imask = self.imask; - self.write(IMR, imask); + self.reg_write(IMR, imask); } - self.write(ISR, 0); + self.reg_write(ISR, 0); return true; } pub unsafe fn intr_legacy(&mut self) -> bool { /* read interrupt status */ - let intr = self.read(ISR); + let intr = self.reg_read(ISR); if (intr & ISR_DIS > 0 || intr & self.imask == 0) { - let mask = self.read(IMR); + let mask = self.reg_read(IMR); println!( "seems a wild interrupt, intr={:X}, imask={:X}, mask={:X}", intr, self.imask, mask @@ -416,10 +419,10 @@ impl Alx { return self.intr_1(intr); } - pub fn next_read(&self) -> usize { + pub fn next_reg_read(&self) -> usize { /* - let head = unsafe { self.read(RDH) }; - let mut tail = unsafe { self.read(RDT) }; + let head = unsafe { self.reg_read(RDH) }; + let mut tail = unsafe { self.reg_read(RDT) }; tail += 1; if tail >= self.receive_ring.len() as u32 { @@ -438,11 +441,11 @@ impl Alx { 0 } - unsafe fn read(&self, register: u32) -> u32 { + unsafe fn reg_read(&self, register: u32) -> u32 { ptr::read_volatile((self.base + register as usize) as *mut u32) } - unsafe fn write(&self, register: u32, data: u32) -> u32 { + unsafe fn reg_write(&self, register: u32, data: u32) -> u32 { ptr::write_volatile((self.base + register as usize) as *mut u32, data); ptr::read_volatile((self.base + register as usize) as *mut u32) } @@ -452,7 +455,7 @@ impl Alx { let mut i: u32 = 0; while (i < MDIO_MAX_AC_TO) { - val = self.read(MDIO); + val = self.reg_read(MDIO); if (val & MDIO_BUSY == 0) { break; } @@ -467,7 +470,7 @@ impl Alx { return; } - self.write(MDIO, 0); + self.reg_write(MDIO, 0); self.wait_mdio_idle(); } @@ -483,11 +486,11 @@ impl Alx { | FIELDX!(MDIO_REG, 1) | MDIO_START | MDIO_OP_READ; - self.write(MDIO, val); + self.reg_write(MDIO, val); self.wait_mdio_idle(); val |= MDIO_AUTO_POLLING; val &= !MDIO_START; - self.write(MDIO, val); + self.reg_write(MDIO, val); udelay(30); } @@ -509,7 +512,7 @@ impl Alx { if (ext) { val = FIELDX!(MDIO_EXTN_DEVAD, dev) | FIELDX!(MDIO_EXTN_REG, reg); - self.write(MDIO_EXTN, val); + self.reg_write(MDIO_EXTN, val); val = MDIO_SPRES_PRMBL | FIELDX!(MDIO_CLK_SEL, clk_sel) @@ -523,12 +526,12 @@ impl Alx { | MDIO_START | MDIO_OP_READ; } - self.write(MDIO, val); + self.reg_write(MDIO, val); if (!self.wait_mdio_idle()) { err = ERR_MIIBUSY; } else { - val = self.read(MDIO); + val = self.reg_read(MDIO); *phy_data = FIELD_GETX!(val, MDIO_DATA) as u16; err = 0; } @@ -554,7 +557,7 @@ impl Alx { if (ext) { val = FIELDX!(MDIO_EXTN_DEVAD, dev) | FIELDX!(MDIO_EXTN_REG, reg); - self.write(MDIO_EXTN, val); + self.reg_write(MDIO_EXTN, val); val = MDIO_SPRES_PRMBL | FIELDX!(MDIO_CLK_SEL, clk_sel) @@ -568,7 +571,7 @@ impl Alx { | FIELDX!(MDIO_DATA, phy_data) | MDIO_START; } - self.write(MDIO, val); + self.reg_write(MDIO, val); if !self.wait_mdio_idle() { err = ERR_MIIBUSY; @@ -617,7 +620,7 @@ impl Alx { let mut pmctrl: u32; let rev: u8 = self.revid(); - pmctrl = self.read(PMCTRL); + pmctrl = self.reg_read(PMCTRL); FIELD_SET32!(pmctrl, PMCTRL_LCKDET_TIMER, PMCTRL_LCKDET_TIMER_DEF); pmctrl |= PMCTRL_RCVR_WT_1US | PMCTRL_L1_CLKSW_EN | PMCTRL_L1_SRDSRX_PWD; @@ -644,7 +647,7 @@ impl Alx { pmctrl |= (PMCTRL_L1_EN | PMCTRL_ASPM_FCEN); } - self.write(PMCTRL, pmctrl); + self.reg_write(PMCTRL, pmctrl); } unsafe fn reset_pcie(&mut self) { @@ -663,27 +666,27 @@ impl Alx { } /* clear WoL setting/status */ - self.read(WOL0); - self.write(WOL0, 0); + self.reg_read(WOL0); + self.reg_write(WOL0, 0); /* deflt val of PDLL D3PLLOFF */ - val = self.read(PDLL_TRNS1); - self.write(PDLL_TRNS1, val & !PDLL_TRNS1_D3PLLOFF_EN); + val = self.reg_read(PDLL_TRNS1); + self.reg_write(PDLL_TRNS1, val & !PDLL_TRNS1_D3PLLOFF_EN); /* mask some pcie error bits */ - val = self.read(UE_SVRT); + val = self.reg_read(UE_SVRT); val &= !(UE_SVRT_DLPROTERR | UE_SVRT_FCPROTERR); - self.write(UE_SVRT, val); + self.reg_write(UE_SVRT, val); /* wol 25M & pclk */ - val = self.read(MASTER); + val = self.reg_read(MASTER); if ((rev == REV_A0 || rev == REV_A1) && self.with_cr()) { if ((val & MASTER_WAKEN_25M) == 0 || (val & MASTER_PCLKSEL_SRDS) == 0) { - self.write(MASTER, val | MASTER_PCLKSEL_SRDS | MASTER_WAKEN_25M); + self.reg_write(MASTER, val | MASTER_PCLKSEL_SRDS | MASTER_WAKEN_25M); } } else { if ((val & MASTER_WAKEN_25M) == 0 || (val & MASTER_PCLKSEL_SRDS) != 0) { - self.write(MASTER, (val & !MASTER_PCLKSEL_SRDS) | MASTER_WAKEN_25M); + self.reg_write(MASTER, (val & !MASTER_PCLKSEL_SRDS) | MASTER_WAKEN_25M); } } @@ -701,7 +704,7 @@ impl Alx { let mut phy_val: u16 = 0; /* (DSP)reset PHY core */ - val = self.read(PHY_CTRL); + val = self.reg_read(PHY_CTRL); val &= !(PHY_CTRL_DSPRST_OUT | PHY_CTRL_IDDQ | PHY_CTRL_GATE_25M @@ -714,9 +717,9 @@ impl Alx { } else { val &= !(PHY_CTRL_HIB_PULSE | PHY_CTRL_HIB_EN); } - self.write(PHY_CTRL, val); + self.reg_write(PHY_CTRL, val); udelay(10); - self.write(PHY_CTRL, val | PHY_CTRL_DSPRST_OUT); + self.reg_write(PHY_CTRL, val | PHY_CTRL_DSPRST_OUT); /* delay 800us */ i = 0; @@ -748,8 +751,8 @@ impl Alx { /* half amplify */ self.write_phy_dbg(MIIDBG_AZ_ANADECT, AZ_ANADECT_DEF); } else { - val = self.read(LPI_CTRL); - self.write(LPI_CTRL, val & (!LPI_CTRL_EN)); + val = self.reg_read(LPI_CTRL); + self.reg_write(LPI_CTRL, val & (!LPI_CTRL_EN)); self.write_phy_ext(MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0); } @@ -795,19 +798,19 @@ impl Alx { let mut val: u32; let mut i: u32; - rxq = self.read(RXQ0); - self.write(RXQ0, rxq & (!RXQ0_EN)); - txq = self.read(TXQ0); - self.write(TXQ0, txq & (!TXQ0_EN)); + rxq = self.reg_read(RXQ0); + self.reg_write(RXQ0, rxq & (!RXQ0_EN)); + txq = self.reg_read(TXQ0); + self.reg_write(TXQ0, txq & (!TXQ0_EN)); udelay(40); self.rx_ctrl &= !(MAC_CTRL_RX_EN | MAC_CTRL_TX_EN); - self.write(MAC_CTRL, self.rx_ctrl); + self.reg_write(MAC_CTRL, self.rx_ctrl); i = 0; while i < DMA_MAC_RST_TO { - val = self.read(MAC_STS); + val = self.reg_read(MAC_STS); if (val & MAC_STS_IDLE == 0) { break; } @@ -827,10 +830,10 @@ impl Alx { let txq: u32; let rxq: u32; - rxq = self.read(RXQ0); - self.write(RXQ0, rxq | RXQ0_EN); - txq = self.read(TXQ0); - self.write(TXQ0, txq | TXQ0_EN); + rxq = self.reg_read(RXQ0); + self.reg_write(RXQ0, rxq | RXQ0_EN); + txq = self.reg_read(TXQ0); + self.reg_write(TXQ0, txq | TXQ0_EN); mac = self.rx_ctrl; if (self.link_duplex == FULL_DUPLEX) { @@ -849,7 +852,7 @@ impl Alx { ); mac |= MAC_CTRL_TX_EN | MAC_CTRL_RX_EN; self.rx_ctrl = mac; - self.write(MAC_CTRL, mac); + self.reg_write(MAC_CTRL, mac); } unsafe fn reset_osc(&mut self, rev: u8) { @@ -857,13 +860,13 @@ impl Alx { let mut val2: u32; /* clear Internal OSC settings, switching OSC by hw itself */ - val = self.read(MISC3); - self.write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); + val = self.reg_read(MISC3); + self.reg_write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); /* 25M clk from chipset may be unstable 1s after de-assert of * PERST, driver need re-calibrate before enter Sleep for WoL */ - val = self.read(MISC); + val = self.reg_read(MISC); if (rev >= REV_B0) { /* restore over current protection def-val, * this val could be reset by MAC-RST @@ -871,13 +874,13 @@ impl Alx { FIELD_SET32!(val, MISC_PSW_OCP, MISC_PSW_OCP_DEF); /* a 0->1 change will update the internal val of osc */ val &= !MISC_INTNLOSC_OPEN; - self.write(MISC, val); - self.write(MISC, val | MISC_INTNLOSC_OPEN); + self.reg_write(MISC, val); + self.reg_write(MISC, val | MISC_INTNLOSC_OPEN); /* hw will automatically dis OSC after cab. */ - val2 = self.read(MSIC2); + val2 = self.reg_read(MSIC2); val2 &= !MSIC2_CALB_START; - self.write(MSIC2, val2); - self.write(MSIC2, val2 | MSIC2_CALB_START); + self.reg_write(MSIC2, val2); + self.reg_write(MSIC2, val2 | MSIC2_CALB_START); } else { val &= !MISC_INTNLOSC_OPEN; /* disable isoloate for A0 */ @@ -885,8 +888,8 @@ impl Alx { val &= !MISC_ISO_EN; } - self.write(MISC, val | MISC_INTNLOSC_OPEN); - self.write(MISC, val); + self.reg_write(MISC, val | MISC_INTNLOSC_OPEN); + self.reg_write(MISC, val); } udelay(20); @@ -905,9 +908,9 @@ impl Alx { a_cr = (rev == REV_A0 || rev == REV_A1) && self.with_cr(); /* disable all interrupts, RXQ/TXQ */ - self.write(MSIX_MASK, 0xFFFFFFFF); - self.write(IMR, 0); - self.write(ISR, ISR_DIS); + self.reg_write(MSIX_MASK, 0xFFFFFFFF); + self.reg_write(IMR, 0); + self.reg_write(ISR, ISR_DIS); ret = self.stop_mac(); if (ret > 0) { @@ -915,25 +918,25 @@ impl Alx { } /* mac reset workaroud */ - self.write(RFD_PIDX, 1); + self.reg_write(RFD_PIDX, 1); /* dis l0s/l1 before mac reset */ if (a_cr) { - pmctrl = self.read(PMCTRL); + pmctrl = self.reg_read(PMCTRL); if ((pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN)) != 0) { - self.write(PMCTRL, pmctrl & !(PMCTRL_L1_EN | PMCTRL_L0S_EN)); + self.reg_write(PMCTRL, pmctrl & !(PMCTRL_L1_EN | PMCTRL_L0S_EN)); } } /* reset whole mac safely */ - val = self.read(MASTER); - self.write(MASTER, val | MASTER_DMA_MAC_RST | MASTER_OOB_DIS); + val = self.reg_read(MASTER); + self.reg_write(MASTER, val | MASTER_DMA_MAC_RST | MASTER_OOB_DIS); /* make sure it's real idle */ udelay(10); i = 0; while (i < DMA_MAC_RST_TO) { - val = self.read(RFD_PIDX); + val = self.reg_read(RFD_PIDX); if (val == 0) { break; } @@ -941,7 +944,7 @@ impl Alx { i += 1; } while (i < DMA_MAC_RST_TO) { - val = self.read(MASTER); + val = self.reg_read(MASTER); if ((val & MASTER_DMA_MAC_RST) == 0) { break; } @@ -955,10 +958,10 @@ impl Alx { if (a_cr) { /* set MASTER_PCLKSEL_SRDS (affect by soft-rst, PERST) */ - self.write(MASTER, val | MASTER_PCLKSEL_SRDS); + self.reg_write(MASTER, val | MASTER_PCLKSEL_SRDS); /* resoter l0s / l1 */ if (pmctrl & (PMCTRL_L1_EN | PMCTRL_L0S_EN) > 0) { - self.write(PMCTRL, pmctrl); + self.reg_write(PMCTRL, pmctrl); } } @@ -966,22 +969,22 @@ impl Alx { /* clear Internal OSC settings, switching OSC by hw itself, * disable isoloate for A version */ - val = self.read(MISC3); - self.write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); - val = self.read(MISC); + val = self.reg_read(MISC3); + self.reg_write(MISC3, (val & !MISC3_25M_BY_SW) | MISC3_25M_NOTO_INTNL); + val = self.reg_read(MISC); val &= !MISC_INTNLOSC_OPEN; if (rev == REV_A0 || rev == REV_A1) { val &= !MISC_ISO_EN; } - self.write(MISC, val); + self.reg_write(MISC, val); udelay(20); /* driver control speed/duplex, hash-alg */ - self.write(MAC_CTRL, self.rx_ctrl); + self.reg_write(MAC_CTRL, self.rx_ctrl); /* clk sw */ - val = self.read(SERDES); - self.write(SERDES, val | SERDES_MACCLK_SLWDWN | SERDES_PHYCLK_SLWDWN); + val = self.reg_read(SERDES); + self.reg_write(SERDES, val | SERDES_MACCLK_SLWDWN | SERDES_PHYCLK_SLWDWN); /* mac reset cause MDIO ctrl restore non-polling status */ if (self.is_fpga) { @@ -1053,7 +1056,7 @@ impl Alx { /* clear flag */ self.write_phy_reg(MII_DBG_ADDR, 0); - val = self.read(DRV); + val = self.reg_read(DRV); FIELD_SET32!(val, DRV_PHY, 0); if (ethadv & ADVERTISED_Autoneg > 0) { @@ -1101,14 +1104,14 @@ impl Alx { val |= self.ethadv_to_hw_cfg(ethadv); } - self.write(DRV, val); + self.reg_write(DRV, val); return err; } unsafe fn get_perm_macaddr(&mut self) -> [u8; 6] { - let mac_low = self.read(STAD0); - let mac_high = self.read(STAD1); + let mac_low = self.reg_read(STAD0); + let mac_high = self.reg_read(STAD1); [ mac_low as u8, (mac_low >> 8) as u8, @@ -1195,30 +1198,30 @@ impl Alx { //TODO alx_set_macaddr(hw, self.mac_addr); /* clk gating */ - self.write(CLK_GATE, CLK_GATE_ALL_A0); + self.reg_write(CLK_GATE, CLK_GATE_ALL_A0); /* idle timeout to switch clk_125M */ if (chip_rev >= REV_B0) { - self.write(IDLE_DECISN_TIMER, IDLE_DECISN_TIMER_DEF); + self.reg_write(IDLE_DECISN_TIMER, IDLE_DECISN_TIMER_DEF); } /* stats refresh timeout */ - self.write(SMB_TIMER, self.smb_timer * 500); + self.reg_write(SMB_TIMER, self.smb_timer * 500); /* intr moduration */ - val = self.read(MASTER); + val = self.reg_read(MASTER); val = val | MASTER_IRQMOD2_EN | MASTER_IRQMOD1_EN | MASTER_SYSALVTIMER_EN; - self.write(MASTER, val); - self.write(IRQ_MODU_TIMER, FIELDX!(IRQ_MODU_TIMER1, self.imt >> 1)); + self.reg_write(MASTER, val); + self.reg_write(IRQ_MODU_TIMER, FIELDX!(IRQ_MODU_TIMER1, self.imt >> 1)); /* intr re-trig timeout */ - self.write(INT_RETRIG, INT_RETRIG_TO); + self.reg_write(INT_RETRIG, INT_RETRIG_TO); /* tpd threshold to trig int */ - self.write(TINT_TPD_THRSHLD, self.ith_tpd); - self.write(TINT_TIMER, self.imt as u32); + self.reg_write(TINT_TPD_THRSHLD, self.ith_tpd); + self.reg_write(TINT_TIMER, self.imt as u32); /* mtu, 8:fcs+vlan */ raw_mtu = (self.mtu + ETH_HLEN) as u32; - self.write(MTU, raw_mtu + 8); + self.reg_write(MTU, raw_mtu + 8); if (raw_mtu > MTU_JUMBO_TH) { self.rx_ctrl &= !MAC_CTRL_FAST_PAUSE; } @@ -1229,7 +1232,7 @@ impl Alx { } else { val = TXQ1_JUMBO_TSO_TH >> 3; } - self.write(TXQ1, val | TXQ1_ERRLGPKT_DROP_EN); + self.reg_write(TXQ1, val | TXQ1_ERRLGPKT_DROP_EN); /* TODO max_payload = alx_get_readrq(hw) >> 8; @@ -1247,15 +1250,15 @@ impl Alx { | TXQ0_LSO_8023_EN | TXQ0_SUPT_IPOPT | FIELDX!(TXQ0_TXF_BURST_PREF, TXQ_TXF_BURST_PREF_DEF); - self.write(TXQ0, val); + self.reg_write(TXQ0, val); val = FIELDX!(HQTPD_Q1_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | FIELDX!(HQTPD_Q2_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | FIELDX!(HQTPD_Q3_NUMPREF, TXQ_TPD_BURSTPREF_DEF) | HQTPD_BURST_EN; - self.write(HQTPD, val); + self.reg_write(HQTPD, val); /* rxq, flow control */ - val = self.read(SRAM5); + val = self.reg_read(SRAM5); val = FIELD_GETX!(val, SRAM_RXF_LEN) << 3; if (val > SRAM_RXF_LEN_8K) { val16 = (MTU_STD_ALGN >> 3) as u16; @@ -1264,7 +1267,7 @@ impl Alx { val16 = (MTU_STD_ALGN >> 3) as u16; val = (val - MTU_STD_ALGN) >> 3; } - self.write( + self.reg_write( RXQ2, FIELDX!(RXQ2_RXF_XOFF_THRESH, val16) | FIELDX!(RXQ2_RXF_XON_THRESH, val), ); @@ -1277,17 +1280,18 @@ impl Alx { if (self.cap & CAP_GIGA > 0) { FIELD_SET32!(val, RXQ0_ASPM_THRESH, RXQ0_ASPM_THRESH_100M); } - self.write(RXQ0, val); + self.reg_write(RXQ0, val); /* DMA */ - self.read(DMA); + self.reg_read(DMA); + val = FIELDX!(DMA_RORDER_MODE, DMA_RORDER_MODE_OUT) | DMA_RREQ_PRI_DATA | FIELDX!(DMA_RREQ_BLEN, max_payload) | FIELDX!(DMA_WDLY_CNT, DMA_WDLY_CNT_DEF) | FIELDX!(DMA_RDLY_CNT, DMA_RDLY_CNT_DEF) | FIELDX!(DMA_RCHNL_SEL, self.dma_chnl - 1); - self.write(DMA, val); + self.reg_write(DMA, val); /* multi-tx-q weight */ if (self.cap & CAP_MTQ > 0) { @@ -1296,7 +1300,7 @@ impl Alx { | FIELDX!(WRR_PRI1, self.wrr[1]) | FIELDX!(WRR_PRI2, self.wrr[2]) | FIELDX!(WRR_PRI3, self.wrr[3]); - self.write(WRR, val); + self.reg_write(WRR, val); } } @@ -1312,8 +1316,8 @@ impl Alx { alx_add_mc_addr(hw, ha->addr); */ - self.write(HASH_TBL0, self.mc_hash[0]); - self.write(HASH_TBL1, self.mc_hash[1]); + self.reg_write(HASH_TBL0, self.mc_hash[0]); + self.reg_write(HASH_TBL1, self.mc_hash[1]); /* check for Promiscuous and All Multicast modes */ self.rx_ctrl &= !(MAC_CTRL_MULTIALL_EN | MAC_CTRL_PROMISC_EN); @@ -1326,7 +1330,7 @@ impl Alx { } */ - self.write(MAC_CTRL, self.rx_ctrl); + self.reg_write(MAC_CTRL, self.rx_ctrl); } unsafe fn set_vlan_mode(&mut self, vlan_rx: bool) { @@ -1336,13 +1340,13 @@ impl Alx { self.rx_ctrl &= !MAC_CTRL_VLANSTRIP; } - self.write(MAC_CTRL, self.rx_ctrl); + self.reg_write(MAC_CTRL, self.rx_ctrl); } unsafe fn configure_rss(&mut self, en: bool) { let mut ctrl: u32; - ctrl = self.read(RXQ0); + ctrl = self.reg_read(RXQ0); if (en) { unimplemented!(); @@ -1357,7 +1361,7 @@ impl Alx { } for (i = 0; i < ARRAY_SIZE(self.rss_idt); i++) - self.write(RSS_IDT_TBL0 + i * 4, + self.reg_write(RSS_IDT_TBL0 + i * 4, self.rss_idt[i]); FIELD_SET32(ctrl, RXQ0_RSS_HSTYP, self.rss_hash_type); @@ -1369,7 +1373,7 @@ impl Alx { ctrl &= !RXQ0_RSS_HASH_EN; } - self.write(RXQ0, ctrl); + self.reg_write(RXQ0, ctrl); } unsafe fn configure(&mut self) { @@ -1380,14 +1384,14 @@ impl Alx { } unsafe fn irq_enable(&mut self) { - self.write(ISR, 0); + self.reg_write(ISR, 0); let imask = self.imask; - self.write(IMR, imask); + self.reg_write(IMR, imask); } unsafe fn irq_disable(&mut self) { - self.write(ISR, ISR_DIS); - self.write(IMR, 0); + self.reg_write(ISR, ISR_DIS); + self.reg_write(IMR, 0); } unsafe fn clear_phy_intr(&mut self) -> usize { @@ -1502,7 +1506,7 @@ impl Alx { self.flag &= !FLAG_HALT; /* clear old interrupts */ - self.write(ISR, !ISR_DIS); + self.reg_write(ISR, !ISR_DIS); self.irq_enable(); @@ -1521,8 +1525,8 @@ impl Alx { unsafe fn init_ring_ptrs(&mut self) { // Write high addresses - self.write(RX_BASE_ADDR_HI, 0); - self.write(TX_BASE_ADDR_HI, 0); + self.reg_write(RX_BASE_ADDR_HI, 0); + self.reg_write(TX_BASE_ADDR_HI, 0); // RFD ring for i in 0..self.rfd_ring.len() { @@ -1533,23 +1537,23 @@ impl Alx { .addr_high .write(((self.rfd_buffer[i].physical() as u64) >> 32) as u32); } - self.write(RFD_ADDR_LO, self.rfd_ring.physical() as u32); - self.write(RFD_RING_SZ, self.rfd_ring.len() as u32); - self.write(RFD_BUF_SZ, 16384); + self.reg_write(RFD_ADDR_LO, self.rfd_ring.physical() as u32); + self.reg_write(RFD_RING_SZ, self.rfd_ring.len() as u32); + self.reg_write(RFD_BUF_SZ, 16384); // RRD ring - self.write(RRD_ADDR_LO, self.rrd_ring.physical() as u32); - self.write(RRD_RING_SZ, self.rrd_ring.len() as u32); + self.reg_write(RRD_ADDR_LO, self.rrd_ring.physical() as u32); + self.reg_write(RRD_RING_SZ, self.rrd_ring.len() as u32); // TPD ring - self.write(TPD_PRI0_ADDR_LO, self.tpd_ring[0].physical() as u32); - self.write(TPD_PRI1_ADDR_LO, self.tpd_ring[1].physical() as u32); - self.write(TPD_PRI2_ADDR_LO, self.tpd_ring[2].physical() as u32); - self.write(TPD_PRI3_ADDR_LO, self.tpd_ring[3].physical() as u32); - self.write(TPD_RING_SZ, self.tpd_ring[0].len() as u32); + self.reg_write(TPD_PRI0_ADDR_LO, self.tpd_ring[0].physical() as u32); + self.reg_write(TPD_PRI1_ADDR_LO, self.tpd_ring[1].physical() as u32); + self.reg_write(TPD_PRI2_ADDR_LO, self.tpd_ring[2].physical() as u32); + self.reg_write(TPD_PRI3_ADDR_LO, self.tpd_ring[3].physical() as u32); + self.reg_write(TPD_RING_SZ, self.tpd_ring[0].len() as u32); // Write pointers into chip SRAM - self.write(SRAM9, SRAM_LOAD_PTR); + self.reg_write(SRAM9, SRAM_LOAD_PTR); } unsafe fn check_link(&mut self) { @@ -1587,7 +1591,7 @@ impl Alx { /* open interrutp mask */ self.imask |= ISR_PHY; let imask = self.imask; - self.write(IMR, imask); + self.reg_write(IMR, imask); if (!link_up && !self.link_up) { goto_out!(); @@ -1735,7 +1739,7 @@ impl Alx { self.flag &= !FLAG_HALT; /* clear old interrupts */ - self.write(ISR, !ISR_DIS); + self.reg_write(ISR, !ISR_DIS); self.irq_enable(); @@ -1746,19 +1750,19 @@ impl Alx { unsafe fn init(&mut self) -> Result<()> { { - let pci_id = self.read(0); + let pci_id = self.reg_read(0); self.vendor_id = pci_id as u16; self.device_id = (pci_id >> 16) as u16; } { - let pci_subid = self.read(0x2C); + let pci_subid = self.reg_read(0x2C); self.subven_id = pci_subid as u16; self.subdev_id = (pci_subid >> 16) as u16; } { - let pci_rev = self.read(8); + let pci_rev = self.reg_read(8); self.revision = pci_rev as u8; } @@ -1783,19 +1787,29 @@ impl Alx { } } -impl scheme::SchemeMut for Alx { - fn open(&mut self, _path: &str, flags: usize, uid: u32, _gid: u32) -> Result { - if uid == 0 { - Ok(flags) +impl SchemeSync for Alx { + fn open(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result { + if ctx.uid == 0 { + Ok(OpenResult::ThisScheme { + number: flags, + flags: NewFdFlags::empty(), + }) } else { Err(Error::new(EACCES)) } } - fn read(&mut self, id: usize, _buf: &mut [u8]) -> Result { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { /* - let head = unsafe { self.read(RDH) }; - let mut tail = unsafe { self.read(RDT) }; + let head = unsafe { self.reg_read(RDH) }; + let mut tail = unsafe { self.reg_read(RDT) }; tail += 1; if tail >= self.receive_ring.len() as u32 { @@ -1815,7 +1829,7 @@ impl scheme::SchemeMut for Alx { i += 1; } - unsafe { self.write(RDT, tail) }; + unsafe { self.reg_write(RDT, tail) }; return Ok(i); } @@ -1829,11 +1843,18 @@ impl scheme::SchemeMut for Alx { } } - fn write(&mut self, _id: usize, _buf: &[u8]) -> Result { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _flags: u32, + _ctx: &CallerCtx, + ) -> Result { /* loop { - let head = unsafe { self.read(TDH) }; - let mut tail = unsafe { self.read(TDT) }; + let head = unsafe { self.reg_read(TDH) }; + let mut tail = unsafe { self.reg_read(TDT) }; let old_tail = tail; tail += 1; @@ -1860,7 +1881,7 @@ impl scheme::SchemeMut for Alx { i += 1; } - unsafe { self.write(TDT, tail) }; + unsafe { self.reg_write(TDT, tail) }; while td.status == 0 { thread::yield_now(); @@ -1873,15 +1894,13 @@ impl scheme::SchemeMut for Alx { Ok(0) } - fn fevent(&mut self, _id: usize, _flags: EventFlags) -> Result { + fn fevent(&mut self, _id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result { Ok(EventFlags::empty()) } - fn fsync(&mut self, _id: usize) -> Result { - Ok(0) + fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> { + Ok(()) } - fn close(&mut self, _id: usize) -> Result { - Ok(0) - } + fn on_close(&mut self, _id: usize) {} } diff --git a/net/alxd/src/main.rs b/net/alxd/src/main.rs index 7f4c11d6a9..37351c8ccd 100644 --- a/net/alxd/src/main.rs +++ b/net/alxd/src/main.rs @@ -14,8 +14,10 @@ use std::{env, iter}; use event::{user_data, EventQueue}; use libredox::flag; +use redox_scheme::wrappers::ReadinessBased; +use redox_scheme::Socket; +use std::cell::RefCell; use syscall::error::EWOULDBLOCK; -use syscall::{Packet, SchemeMut}; pub mod device; @@ -35,13 +37,8 @@ fn main() { // Daemonize redox_daemon::Daemon::new(move |daemon| { - let socket_fd = libredox::call::open( - ":network", - flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, - 0, - ) - .expect("alxd: failed to create network scheme"); - let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; + let socket = Socket::nonblock("network").expect("alxd: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); daemon.ready().expect("alxd: failed to signal readiness"); @@ -58,8 +55,9 @@ fn main() { .expect("alxd: failed to map address") as usize }; { - let mut device = - unsafe { device::Alx::new(address).expect("alxd: failed to allocate device") }; + let device = RefCell::new(unsafe { + device::Alx::new(address).expect("alxd: failed to allocate device") + }); user_data! { enum Source { @@ -78,13 +76,15 @@ fn main() { ) .unwrap(); event_queue - .subscribe(socket_fd, Source::Scheme, event::EventFlags::READ) + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) .unwrap(); libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); - let mut todo = Vec::::new(); - for event in iter::once(Source::Scheme) .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) { @@ -92,53 +92,36 @@ fn main() { Source::Irq => { let mut irq = [0; 8]; irq_file.read(&mut irq).unwrap(); - if unsafe { device.intr_legacy() } { - irq_file.write(&mut irq).unwrap(); - - let mut i = 0; - while i < todo.len() { - let a = todo[i].a; - device.handle(&mut todo[i]); - if todo[i].a == (-EWOULDBLOCK) as usize { - todo[i].a = a; - i += 1; - } else { - socket - .write(&mut todo[i]) - .expect("alxd: failed to write to socket"); - todo.remove(i); - } - } - - /* TODO: Currently a no-op - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + if !unsafe { device.borrow_mut().intr_legacy() } { + continue; } - } - Source::Scheme => { - loop { - let mut packet = Packet::default(); - if socket - .read(&mut packet) - .expect("alxd: failed read from socket") - == 0 - { - break; - } + irq_file.write(&mut irq).unwrap(); - let a = packet.a; - device.handle(&mut packet); - if packet.a == (-EWOULDBLOCK) as usize { - packet.a = a; - todo.push(packet); - } else { - socket - .write(&mut packet) - .expect("alxd: failed to write to socket"); - } + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ihdad: failed to poll requests"); + + /* TODO: Currently a no-op + let next_read = device.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("alxd: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("alxd: failed to write to socket") + { + break; } // TODO