Skip to content

Commit 6cae97c

Browse files
committed
Use more specific [u8; 8] type for SETUP packets
Also, a minor change to return WouldBlock when read() encounters a SETUP packet, rather than InvalidState, which cleans up control logic.
1 parent be05445 commit 6cae97c

File tree

5 files changed

+47
-44
lines changed

5 files changed

+47
-44
lines changed

src/bus.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ pub trait UsbBus: Sized {
9393
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no packet to be read. Note that
9494
/// this is different from a received zero-length packet, which is valid in USB. A zero-length
9595
/// packet will return `Ok(0)`.
96+
///
97+
/// `WouldBlock` is also returned when the endpoint received a SETUP transaction, which can be
98+
/// read through [`read_setup()`](UsbBus::read_setup()).
9699
/// * [`BufferOverflow`](crate::UsbError::BufferOverflow) - The received packet is too long to
97100
/// fit in `buf`. This is generally an error in the class implementation, because the class
98101
/// should use a buffer that is large enough for the `max_packet_size` it specified when
@@ -114,14 +117,8 @@ pub trait UsbBus: Sized {
114117
///
115118
/// * [`InvalidEndpoint`](crate::UsbError::InvalidEndpoint) - The `ep_addr` does not point to a
116119
/// valid endpoint that was previously allocated with [`UsbBus::alloc_ep`].
117-
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no SETUP packet to be read. Note
118-
/// that this is different from a received zero-length packet, which is valid in USB. A
119-
/// zero-length packet will return `Ok(0)`.
120-
/// * [`BufferOverflow`](crate::UsbError::BufferOverflow) - The received packet is too long to
121-
/// fit in `buf`. This is generally an error in the class implementation, because the class
122-
/// should use a buffer that is large enough for the `max_packet_size` it specified when
123-
/// allocating the endpoint.
124-
fn read_setup(&self, ep_addr: EndpointAddress, buf: &mut [u8]) -> Result<usize>;
120+
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no SETUP packet to be read.
121+
fn read_setup(&self, ep_addr: EndpointAddress) -> Result<[u8; 8]>;
125122

126123
/// Sets or clears the STALL condition for an endpoint. If the endpoint is an OUT endpoint, it
127124
/// should be prepared to receive data again.

src/control_pipe.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,18 @@ impl<B: UsbBus> ControlPipe<'_, B> {
6565
}
6666

6767
pub fn handle_setup(&mut self) -> Option<Request> {
68-
let count = match self.ep_out.read_setup(&mut self.buf[..]) {
69-
Ok(count) => {
70-
usb_trace!("Read {} bytes on EP0-OUT: {:?}", count, &self.buf[..count]);
71-
count
68+
let packet = match self.ep_out.read_setup() {
69+
Ok(packet) => {
70+
usb_trace!("Read SETUP packet on EP0-OUT: {:?}", packet);
71+
packet
7272
}
7373
Err(UsbError::WouldBlock) => return None,
7474
Err(_) => {
7575
return None;
7676
}
7777
};
7878

79-
let req = match Request::parse(&self.buf[0..count]) {
79+
let req = match Request::parse(&packet) {
8080
Ok(req) => req,
8181
Err(_) => {
8282
// Failed to parse SETUP packet. We are supposed to silently ignore this.
@@ -167,7 +167,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
167167
);
168168
match self.ep_out.read(&mut []) {
169169
Ok(_) => {}
170-
Err(UsbError::InvalidState) => {
170+
Err(UsbError::WouldBlock) => {
171171
// Host sent a new SETUP transaction, which may have overwritten the ZLP
172172
}
173173
Err(err) => {

src/dummy.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ impl UsbBus for DummyUsbBus {
5959
fn read_setup(
6060
&self,
6161
ep_addr: crate::class_prelude::EndpointAddress,
62-
buf: &mut [u8],
63-
) -> crate::Result<usize> {
62+
) -> crate::Result<[u8; 8]> {
6463
unimplemented!()
6564
}
6665

src/endpoint.rs

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -199,49 +199,56 @@ impl<B: UsbBus> Endpoint<'_, B, In> {
199199
impl<B: UsbBus> Endpoint<'_, B, Out> {
200200
/// Reads a single packet of data and returns the length of the packet
201201
///
202-
/// The buffer should be large enough to fit at least as many bytes as the `max_packet_size`
203-
/// specified when allocating the endpoint.
202+
/// The buffer should be large enough to fit at least as many bytes as the
203+
/// `max_packet_size` specified when allocating the endpoint.
204204
///
205205
/// # Errors
206206
///
207-
/// Note: USB bus implementation errors are directly passed through, so be prepared to handle
208-
/// other errors as well.
207+
/// Note: USB bus implementation errors are directly passed through, so be
208+
/// prepared to handle other errors as well.
209209
///
210-
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no packet to be read. Note that
211-
/// this is different from a received zero-length packet, which is valid and significant in
212-
/// USB. A zero-length packet will return `Ok(0)`.
213-
/// * [`BufferOverflow`](crate::UsbError::BufferOverflow) - The received packet is too long to
214-
/// fit in `data`. This is generally an error in the class implementation.
215-
/// * [`InvalidState`](crate::UsbError::InvalidState) - The received packet is a SETUP
216-
/// transaction, and needs to be read through [`read_setup()`](Endpoint::read_setup())
217-
/// instead.
210+
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no OUT packet
211+
/// to be read. Note that this is different from a received zero-length
212+
/// packet, which is valid and significant in USB. A zero-length packet
213+
/// will return `Ok(0)`.
214+
///
215+
/// `WouldBlock` is also returned when the endpoint received a SETUP
216+
/// transaction, which can be read through
217+
/// [`read_setup()`](Endpoint::read_setup()).
218+
/// * [`BufferOverflow`](crate::UsbError::BufferOverflow) - The received
219+
/// packet is too long to fit in `data`. This is generally an error in the
220+
/// class implementation.
218221
pub fn read(&self, data: &mut [u8]) -> Result<usize> {
219222
self.bus().read(self.address, data)
220223
}
221224

222-
/// Reads a single packet of SETUP data and returns the length of the packet
225+
/// Reads a single packet of SETUP data and returns it
226+
///
227+
/// USB Spec 2.0 5.5.3 Control Transfer Packet Size Constraints: "A Setup
228+
/// packet is always eight bytes."
223229
///
224-
/// The buffer should be large enough to fit at least as many bytes as the `max_packet_size`
225-
/// specified when allocating the endpoint. See [`UsbBus::read_setup()`] for rationale for two
226-
/// distinct read methods.
230+
/// See [`UsbBus::read_setup()`] for rationale for two distinct read
231+
/// methods.
227232
///
228233
/// # Errors
229234
///
230-
/// Note: USB bus implementation errors are directly passed through, so be prepared to handle
231-
/// other errors as well.
235+
/// Note: USB bus implementation errors are directly passed through, so be
236+
/// prepared to handle other errors as well.
232237
///
233-
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no packet to be read. Note that
234-
/// this is different from a received zero-length packet, which is valid and significant in
235-
/// USB. A zero-length packet will return `Ok(0)`.
236-
/// * [`BufferOverflow`](crate::UsbError::BufferOverflow) - The received packet is too long to
237-
/// fit in `data`. This is generally an error in the class implementation.
238-
pub fn read_setup(&self, data: &mut [u8]) -> Result<usize> {
238+
/// * [`WouldBlock`](crate::UsbError::WouldBlock) - There is no packet to be
239+
/// read. Note that this is different from a received zero-length packet,
240+
/// which is valid and significant in USB. A zero-length packet will
241+
/// return `Ok(0)`.
242+
/// * [`InvalidEndpoint`](crate::UsbError::InvalidEndpoint) - SETUP packets
243+
/// can only be read from Control endpoints, this error is returned if the
244+
/// method is called on any other type endpoint.
245+
pub fn read_setup(&self) -> Result<[u8; 8]> {
239246
// SETUP transactions can only occur on control endpoints
240247
if self.ep_type != EndpointType::Control {
241-
Err(UsbError::InvalidEndpoint)
242-
} else {
243-
self.bus().read_setup(self.address, data)
248+
return Err(UsbError::InvalidEndpoint);
244249
}
250+
251+
self.bus().read_setup(self.address)
245252
}
246253
}
247254

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ fn _ensure_sync() {
258258
Err(UsbError::InvalidEndpoint)
259259
}
260260

261-
fn read_setup(&self, _ep_addr: EndpointAddress, _buf: &mut [u8]) -> Result<usize> {
261+
fn read_setup(&self, _ep_addr: EndpointAddress) -> Result<[u8; 8]> {
262262
Err(UsbError::InvalidEndpoint)
263263
}
264264

0 commit comments

Comments
 (0)