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:
Generated
+14
@@ -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",
|
||||
|
||||
@@ -14,3 +14,4 @@ redox_syscall = "0.5"
|
||||
spin = "0.9"
|
||||
|
||||
pcid = { path = "../../pcid" }
|
||||
redox-scheme = "0.8.2"
|
||||
|
||||
+27
-17
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -14,3 +14,4 @@ spin = "0.9"
|
||||
|
||||
common = { path = "../../common" }
|
||||
pcid = { path = "../../pcid" }
|
||||
redox-scheme = "0.8.2"
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,3 +11,4 @@ redox-daemon = "0.1"
|
||||
|
||||
common = { path = "../../common" }
|
||||
libredox = "0.1.3"
|
||||
redox-scheme = "0.8.2"
|
||||
|
||||
+167
-148
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user