From f5e1d9568d8bc9e5aaa1501de49844925bb8d4e1 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 24 Aug 2017 05:50:59 +0000 Subject: [PATCH] firmware: update smoltcp. --- artiq/firmware/Cargo.lock | 6 +- artiq/firmware/runtime/Cargo.toml | 2 +- artiq/firmware/runtime/ethmac.rs | 4 +- artiq/firmware/runtime/sched.rs | 91 +++++++++++++++++++------------ 4 files changed, 61 insertions(+), 42 deletions(-) diff --git a/artiq/firmware/Cargo.lock b/artiq/firmware/Cargo.lock index 85ca48a47..6ef0db1fb 100644 --- a/artiq/firmware/Cargo.lock +++ b/artiq/firmware/Cargo.lock @@ -157,7 +157,7 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "logger_artiq 0.0.0", "proto 0.0.0", - "smoltcp 0.4.0-pre (git+https://github.com/m-labs/smoltcp?rev=5f16fc0)", + "smoltcp 0.4.0-pre (git+https://github.com/m-labs/smoltcp?rev=bc2a894)", "std_artiq 0.0.0", ] @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "smoltcp" version = "0.4.0-pre" -source = "git+https://github.com/m-labs/smoltcp?rev=5f16fc0#5f16fc0032dee3d8c50a7890a359369d1762c723" +source = "git+https://github.com/m-labs/smoltcp?rev=bc2a894#bc2a894c00c9e0cbc51d67c01f456e45b45abcc2" dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -221,7 +221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec57723b84bbe7bdf76aa93169c9b59e67473317c6de3a83cb2a0f8ccb2aa493" "checksum managed 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61eb783b4fa77e8fa4d27ec400f97ed9168546b8b30341a120b7ba9cc6571aaf" "checksum rustc-cfg 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56a596b5718bf5e059d59a30af12f7f462a152de147aa462b70892849ee18704" -"checksum smoltcp 0.4.0-pre (git+https://github.com/m-labs/smoltcp?rev=5f16fc0)" = "" +"checksum smoltcp 0.4.0-pre (git+https://github.com/m-labs/smoltcp?rev=bc2a894)" = "" "checksum walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7c16466ecc507c7cb5988db03e6eab4aaeab89a5c37a29251fcfd3ac9b7afe" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/artiq/firmware/runtime/Cargo.toml b/artiq/firmware/runtime/Cargo.toml index 950a27370..069a8da1f 100644 --- a/artiq/firmware/runtime/Cargo.toml +++ b/artiq/firmware/runtime/Cargo.toml @@ -32,6 +32,6 @@ features = ["mem"] [dependencies.smoltcp] git = "https://github.com/m-labs/smoltcp" -rev = "5f16fc0" +rev = "bc2a894" default-features = false features = ["alloc", "collections", "log"]#, "verbose"] diff --git a/artiq/firmware/runtime/ethmac.rs b/artiq/firmware/runtime/ethmac.rs index a2b4e281f..23047bab0 100644 --- a/artiq/firmware/runtime/ethmac.rs +++ b/artiq/firmware/runtime/ethmac.rs @@ -30,7 +30,7 @@ impl Device for EthernetDevice { limits } - fn receive(&mut self) -> Result { + fn receive(&mut self, _timestamp: u64) -> Result { unsafe { if csr::ethmac::sram_writer_ev_pending_read() != 0 { let slot = csr::ethmac::sram_writer_slot_read(); @@ -43,7 +43,7 @@ impl Device for EthernetDevice { } } - fn transmit(&mut self, length: usize) -> Result { + fn transmit(&mut self, _timestamp: u64, length: usize) -> Result { unsafe { if csr::ethmac::sram_reader_ready_read() != 0 { let slot = csr::ethmac::sram_reader_slot_read(); diff --git a/artiq/firmware/runtime/sched.rs b/artiq/firmware/runtime/sched.rs index 8de5f5de0..de0dbf4c6 100644 --- a/artiq/firmware/runtime/sched.rs +++ b/artiq/firmware/runtime/sched.rs @@ -8,8 +8,7 @@ use fringe::OwnedStack; use fringe::generator::{Generator, Yielder, State as GeneratorState}; use smoltcp::wire::IpEndpoint; -use smoltcp::socket::AsSocket; -use smoltcp::socket::SocketHandle; +use smoltcp::socket::{AsSocket, SocketHandle}; type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>; use board; @@ -248,6 +247,10 @@ macro_rules! until { }) } +use ::smoltcp::Error as ErrorLower; +// https://github.com/rust-lang/rust/issues/44057 +// type ErrorLower = ::smoltcp::Error; + type UdpPacketBuffer = ::smoltcp::socket::UdpPacketBuffer<'static>; type UdpSocketBuffer = ::smoltcp::socket::UdpSocketBuffer<'static, 'static>; type UdpSocketLower = ::smoltcp::socket::UdpSocket<'static, 'static>; @@ -280,29 +283,34 @@ impl<'a> UdpSocket<'a> { |sockets| sockets.get_mut(self.handle).as_socket()) } - pub fn bind>(&self, endpoint: T) { - self.as_lower().bind(endpoint) + pub fn bind>(&self, endpoint: T) -> Result<()> { + match self.as_lower().bind(endpoint) { + Ok(()) => Ok(()), + Err(ErrorLower::Illegal) => + Err(Error::new(ErrorKind::Other, "already listening")), + Err(ErrorLower::Unaddressable) => + Err(Error::new(ErrorKind::AddrNotAvailable, "port cannot be zero")), + _ => unreachable!() + } } pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, IpEndpoint)> { until!(self, UdpSocketLower, |s| s.can_recv())?; match self.as_lower().recv_slice(buf) { - Ok(r) => Ok(r), - Err(()) => { - // No data in the buffer--should never happen after the wait above. - unreachable!() - } + Ok(result) => Ok(result), + Err(_) => unreachable!() } } - pub fn send_to(&self, buf: &[u8], addr: IpEndpoint) -> Result { + pub fn send_to(&self, buf: &[u8], addr: IpEndpoint) -> Result<()> { until!(self, UdpSocketLower, |s| s.can_send())?; match self.as_lower().send_slice(buf, addr) { - Ok(r) => Ok(r), - Err(()) => { - // No space in the buffer--should never happen after the wait above. - unreachable!() - } + Ok(()) => Ok(()), + Err(ErrorLower::Unaddressable) => + Err(Error::new(ErrorKind::AddrNotAvailable, "unaddressable destination")), + Err(ErrorLower::Truncated) => + Err(Error::new(ErrorKind::Other, "packet does not fit in buffer")), + Err(_) => unreachable!() } } } @@ -363,9 +371,14 @@ impl<'a> TcpListener<'a> { pub fn listen>(&self, endpoint: T) -> Result<()> { let endpoint = endpoint.into(); - self.as_lower().listen(endpoint) - .map_err(|()| Error::new(ErrorKind::Other, - "cannot listen: already connected"))?; + match self.as_lower().listen(endpoint) { + Ok(()) => Ok(()), + Err(ErrorLower::Illegal) => + Err(Error::new(ErrorKind::Other, "already listening")), + Err(ErrorLower::Unaddressable) => + Err(Error::new(ErrorKind::InvalidInput, "port cannot be zero")), + _ => unreachable!() + }?; self.endpoint.set(endpoint); Ok(()) } @@ -383,7 +396,10 @@ impl<'a> TcpListener<'a> { let accepted = self.handle.get(); self.handle.set(Self::new_lower(self.io, self.buffer_size.get())); - self.listen(self.endpoint.get()).unwrap(); + match self.listen(self.endpoint.get()) { + Ok(()) => (), + _ => unreachable!() + } Ok(TcpStream { io: self.io, handle: accepted @@ -470,19 +486,20 @@ impl<'a> Read for TcpStream<'a> { let result = self.as_lower().recv_slice(buf); match result { // Slow path: we need to block until buffer is non-empty. - Ok(0) | Err(()) => { + Ok(0) => { until!(self, TcpSocketLower, |s| s.can_recv() || !s.may_recv())?; - let mut socket = self.as_lower(); - if socket.may_recv() { - Ok(socket.recv_slice(buf) - .expect("can_recv implies that data was available")) - } else { - // This socket will never receive data again. - Ok(0) + match self.as_lower().recv_slice(buf) { + Ok(length) => Ok(length), + Err(ErrorLower::Illegal) => Ok(0), + _ => unreachable!() } } // Fast path: we had data in buffer. - Ok(length) => Ok(length) + Ok(length) => Ok(length), + // Error path: the receive half of the socket is not open. + Err(ErrorLower::Illegal) => Ok(0), + // No other error may be returned. + Err(_) => unreachable!() } } } @@ -493,18 +510,20 @@ impl<'a> Write for TcpStream<'a> { let result = self.as_lower().send_slice(buf); match result { // Slow path: we need to block until buffer is non-full. - Ok(0) | Err(()) => { + Ok(0) => { until!(self, TcpSocketLower, |s| s.can_send() || !s.may_send())?; - if self.as_lower().may_send() { - Ok(self.as_lower().send_slice(buf) - .expect("can_send implies that data was available")) - } else { - // This socket will never send data again. - Ok(0) + match self.as_lower().send_slice(buf) { + Ok(length) => Ok(length), + Err(ErrorLower::Illegal) => Ok(0), + _ => unreachable!() } } // Fast path: we had space in buffer. - Ok(length) => Ok(length) + Ok(length) => Ok(length), + // Error path: the transmit half of the socket is not open. + Err(ErrorLower::Illegal) => Ok(0), + // No other error may be returned. + Err(_) => unreachable!() } }