Merge branch 'latest-redox-scheme' into 'master'

feat: Update some drivers to latest redox-scheme from the legacy scheme.

See merge request redox-os/drivers!296
This commit is contained in:
bjorn3
2025-11-29 14:20:44 +00:00
13 changed files with 469 additions and 484 deletions
Generated
+14
View File
@@ -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",
+1
View File
@@ -14,3 +14,4 @@ redox_syscall = "0.5"
spin = "0.9"
pcid = { path = "../../pcid" }
redox-scheme = "0.8.2"
+27 -17
View File
@@ -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<Option<usize>> {
if uid == 0 {
impl SchemeSync for Ac97 {
fn open(&mut self, _path: &str, _flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
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<Option<usize>> {
fn write(
&mut self,
id: usize,
buf: &[u8],
_offset: u64,
_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
{
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<Option<usize>> {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
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<Option<usize>> {
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);
}
}
+42 -58
View File
@@ -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::<Packet>::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;
}
/*
+1
View File
@@ -14,3 +14,4 @@ spin = "0.9"
common = { path = "../../common" }
pcid = { path = "../../pcid" }
redox-scheme = "0.8.2"
+64 -69
View File
@@ -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<u8>, usize),
StrBuf(Vec<u8>),
}
#[repr(C, packed)]
@@ -389,7 +392,7 @@ impl IntelHDA {
pub fn find_best_output_pin(&mut self) -> Result<WidgetAddr> {
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<Option<usize>> {
pub fn write_to_output(&mut self, index: u8, buf: &[u8]) -> Poll<Result<usize>> {
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<Option<usize>> {
impl SchemeSync for IntelHDA {
fn open(&mut self, path: &str, _flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
//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<Option<usize>> {
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<usize> {
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<Option<usize>> {
fn write(
&mut self,
id: usize,
buf: &[u8],
_offset: u64,
_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
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<Option<isize>> {
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<Option<usize>> {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
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<Option<usize>> {
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);
}
}
+44 -61
View File
@@ -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::<Source>::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::<Source>::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::<Packet>::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;
}
/*
+1
View File
@@ -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"
+24 -15
View File
@@ -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<Option<usize>> {
if uid == 0 {
impl SchemeSync for Sb16 {
fn open(&mut self, _path: &str, _flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
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<Option<usize>> {
fn write(
&mut self,
_id: usize,
_buf: &[u8],
_offset: u64,
_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
//TODO
Err(Error::new(EBADF))
}
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
fn fpath(&mut self, id: usize, buf: &mut [u8], _ctx: &CallerCtx) -> Result<usize> {
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<Option<usize>> {
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);
}
}
+42 -58
View File
@@ -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::<Packet>::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);
}
},
}
}
+1
View File
@@ -11,3 +11,4 @@ redox-daemon = "0.1"
common = { path = "../../common" }
libredox = "0.1.3"
redox-scheme = "0.8.2"
+167 -148
View File
@@ -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<usize> {
if uid == 0 {
Ok(flags)
impl SchemeSync for Alx {
fn open(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
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<usize> {
fn read(
&mut self,
id: usize,
buf: &mut [u8],
offset: u64,
_flags: u32,
_ctx: &CallerCtx,
) -> Result<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 {
@@ -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<usize> {
fn write(
&mut self,
id: usize,
buf: &[u8],
_offset: u64,
_flags: u32,
_ctx: &CallerCtx,
) -> Result<usize> {
/*
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<EventFlags> {
fn fevent(&mut self, _id: usize, _flags: EventFlags, _ctx: &CallerCtx) -> Result<EventFlags> {
Ok(EventFlags::empty())
}
fn fsync(&mut self, _id: usize) -> Result<usize> {
Ok(0)
fn fsync(&mut self, _id: usize, _ctx: &CallerCtx) -> Result<()> {
Ok(())
}
fn close(&mut self, _id: usize) -> Result<usize> {
Ok(0)
}
fn on_close(&mut self, _id: usize) {}
}
+41 -58
View File
@@ -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::<Packet>::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