diff --git a/rtl8168d/src/device.rs b/rtl8168d/src/device.rs index b49466d332d3bbaa7a5da4c8fbea9af9bda49d86..37dbb744565c558dd39073c870c1fb0f06281031 100644 --- a/rtl8168d/src/device.rs +++ b/rtl8168d/src/device.rs @@ -1,7 +1,8 @@ use std::{mem, thread}; +use std::collections::BTreeMap; use netutils::setcfg; -use syscall::error::{Error, EACCES, EINVAL, EWOULDBLOCK, Result}; +use syscall::error::{Error, EACCES, EBADF, EINVAL, EWOULDBLOCK, Result}; use syscall::flag::O_NONBLOCK; use syscall::io::{Dma, Mmio, Io, ReadOnly}; use syscall::scheme::SchemeMut; @@ -73,13 +74,17 @@ pub struct Rtl8168 { transmit_ring: Dma<[Td; 16]>, transmit_i: usize, transmit_buffer_h: [Dma<[Mmio; 7552]>; 1], - transmit_ring_h: Dma<[Td; 1]> + transmit_ring_h: Dma<[Td; 1]>, + next_id: usize, + pub handles: BTreeMap } impl SchemeMut for Rtl8168 { fn open(&mut self, _path: &[u8], flags: usize, uid: u32, _gid: u32) -> Result { if uid == 0 { - Ok(flags) + self.next_id += 1; + self.handles.insert(self.next_id, flags); + Ok(self.next_id) } else { Err(Error::new(EACCES)) } @@ -90,10 +95,18 @@ impl SchemeMut for Rtl8168 { return Err(Error::new(EINVAL)); } - Ok(id) + let flags = { + let flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + *flags + }; + self.next_id += 1; + self.handles.insert(self.next_id, flags); + Ok(self.next_id) } fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { + let flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + if self.receive_i >= self.receive_ring.len() { self.receive_i = 0; } @@ -118,14 +131,16 @@ impl SchemeMut for Rtl8168 { return Ok(i); } - if id & O_NONBLOCK == O_NONBLOCK { + if flags & O_NONBLOCK == O_NONBLOCK { Ok(0) } else { Err(Error::new(EWOULDBLOCK)) } } - fn write(&mut self, _id: usize, buf: &[u8]) -> Result { + fn write(&mut self, id: usize, buf: &[u8]) -> Result { + let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + loop { if self.transmit_i >= self.transmit_ring.len() { self.transmit_i = 0; @@ -159,15 +174,30 @@ impl SchemeMut for Rtl8168 { } } - fn fevent(&mut self, _id: usize, _flags: usize) -> Result { - Ok(0) + fn fevent(&mut self, id: usize, _flags: usize) -> Result { + let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + Ok(id) + } + + fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { + let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; + + let mut i = 0; + let scheme_path = b"network:"; + while i < buf.len() && i < scheme_path.len() { + buf[i] = scheme_path[i]; + i += 1; + } + Ok(i) } - fn fsync(&mut self, _id: usize) -> Result { + fn fsync(&mut self, id: usize) -> Result { + let _flags = self.handles.get(&id).ok_or(Error::new(EBADF))?; Ok(0) } - fn close(&mut self, _id: usize) -> Result { + fn close(&mut self, id: usize) -> Result { + self.handles.remove(&id).ok_or(Error::new(EBADF))?; Ok(0) } } @@ -214,7 +244,9 @@ impl Rtl8168 { transmit_ring: Dma::zeroed()?, transmit_i: 0, transmit_buffer_h: [Dma::zeroed()?], - transmit_ring_h: Dma::zeroed()? + transmit_ring_h: Dma::zeroed()?, + next_id: 0, + handles: BTreeMap::new() }; module.init(); diff --git a/rtl8168d/src/main.rs b/rtl8168d/src/main.rs index 46b53ccbc8e989201ee3b2483d1c10744f62344b..460da0ac57b5dd3cdcb8a7793ea1a6514d8092ca 100644 --- a/rtl8168d/src/main.rs +++ b/rtl8168d/src/main.rs @@ -81,7 +81,7 @@ fn main() { Ok(None) }).expect("rtl8168d: failed to catch events on IRQ file"); - let socket_fd = socket.borrow().as_raw_fd(); + let device_packet = device.clone(); let socket_packet = socket.clone(); event_queue.add(socket_fd, move |_event| -> Result> { loop { @@ -91,7 +91,7 @@ fn main() { } let a = packet.a; - device.borrow_mut().handle(&mut packet); + device_packet.borrow_mut().handle(&mut packet); if packet.a == (-EWOULDBLOCK) as usize { packet.a = a; todo.borrow_mut().push(packet); @@ -100,7 +100,7 @@ fn main() { } } - let next_read = device.borrow().next_read(); + let next_read = device_packet.borrow().next_read(); if next_read > 0 { return Ok(Some(next_read)); } @@ -108,35 +108,31 @@ fn main() { Ok(None) }).expect("rtl8168d: failed to catch events on scheme file"); + let send_events = |event_count| { + for (handle_id, _handle) in device.borrow().handles.iter() { + socket.borrow_mut().write(&Packet { + id: 0, + pid: 0, + uid: 0, + gid: 0, + a: syscall::number::SYS_FEVENT, + b: *handle_id, + c: syscall::flag::EVENT_READ, + d: event_count + }).expect("e1000d: failed to write event"); + } + }; + for event_count in event_queue.trigger_all(event::Event { fd: 0, flags: 0, }).expect("rtl8168d: failed to trigger events") { - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("rtl8168d: failed to write event"); + send_events(event_count); } loop { let event_count = event_queue.run().expect("rtl8168d: failed to handle events"); - - socket.borrow_mut().write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: 0, - c: syscall::flag::EVENT_READ, - d: event_count - }).expect("rtl8168d: failed to write event"); + send_events(event_count); } } unsafe { let _ = syscall::physunmap(address); }