Skip to content

Commit bec5093

Browse files
committed
Updating tracing, changing EP0 handling
1 parent d09d74a commit bec5093

File tree

3 files changed

+52
-41
lines changed

3 files changed

+52
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface.
1313

1414
### Changed
1515
* Invalid LangIDs will default to `EN_US`
16+
* Changed handling of EP0 state to eliminate unexpected issues with device enumeration
1617

1718
## [0.3.1] - 2023-11-15
1819

src/control_pipe.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,28 +69,30 @@ impl<B: UsbBus> ControlPipe<'_, B> {
6969

7070
pub fn handle_setup(&mut self) -> Option<Request> {
7171
let count = match self.ep_out.read(&mut self.buf[..]) {
72-
Ok(count) => count,
72+
Ok(count) => {
73+
usb_trace!("Read {count} bytes on EP0-OUT: {:?}", &self.buf[..count]);
74+
count
75+
}
7376
Err(UsbError::WouldBlock) => return None,
7477
Err(_) => {
75-
self.set_error();
7678
return None;
7779
}
7880
};
7981

8082
let req = match Request::parse(&self.buf[0..count]) {
8183
Ok(req) => req,
8284
Err(_) => {
83-
// Failed to parse SETUP packet
84-
self.set_error();
85+
// Failed to parse SETUP packet. We are supposed to silently ignore this.
8586
return None;
8687
}
8788
};
8889

8990
// Now that we have properly parsed the setup packet, ensure the end-point is no longer in
9091
// a stalled state.
91-
usb_trace!("EP0 request received: {req:?}");
9292
self.ep_out.unstall();
9393

94+
usb_debug!("EP0 request received: {req:?}");
95+
9496
/*sprintln!("SETUP {:?} {:?} {:?} req:{} val:{} idx:{} len:{} {:?}",
9597
req.direction, req.request_type, req.recipient,
9698
req.request, req.value, req.index, req.length,
@@ -104,7 +106,6 @@ impl<B: UsbBus> ControlPipe<'_, B> {
104106

105107
if req.length as usize > self.buf.len() {
106108
// Data stage won't fit in buffer
107-
self.set_error();
108109
return None;
109110
}
110111

@@ -143,11 +144,11 @@ impl<B: UsbBus> ControlPipe<'_, B> {
143144
}
144145
};
145146

147+
usb_trace!("Read {count} bytes on EP0-OUT: {:?}", &self.buf[i..(i + count)]);
146148
self.i += count;
147-
usb_trace!("Read {count} bytes on EP0-OUT");
148149

149150
if self.i >= self.len {
150-
usb_debug!("Request OUT complete: {req}");
151+
usb_debug!("Request OUT complete: {req:?}");
151152
self.state = ControlState::CompleteOut;
152153
return Some(req);
153154
}
@@ -159,7 +160,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
159160
| ControlState::DataInZlp
160161
| ControlState::StatusOut => {
161162
usb_debug!(
162-
"Terminating DATA stage early. Current state: {:?}",
163+
"Control transfer completed. Current state: {:?}",
163164
self.state
164165
);
165166
let _ = self.ep_out.read(&mut []);
@@ -193,7 +194,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
193194
return false;
194195
}
195196

196-
usb_trace!("wrote EP0-IN: ZLP");
197+
usb_trace!("wrote EP0: ZLP");
197198
self.state = ControlState::DataInLast;
198199
}
199200
ControlState::DataInLast => {
@@ -205,15 +206,14 @@ impl<B: UsbBus> ControlPipe<'_, B> {
205206
return true;
206207
}
207208
ControlState::Idle => {
208-
usb_debug!("Ignoring EP0-IN while in IDLE");
209209
// If we received a message on EP0 while sending the last portion of an IN
210210
// transfer, we may have already transitioned to IDLE without getting the last
211211
// IN-complete status. Just ignore this indication.
212212
}
213213
_ => {
214-
// Unexpected IN packet
215-
usb_debug!("Unexpected EP0-IN. Current state: {:?}", self.state);
216-
self.set_error();
214+
// If we get IN-COMPLETE indications in unexpected states, it's generally because
215+
// of control flow in previous phases updating after our packet was successfully
216+
// sent. Ignore these indications if they don't drive any further behavior.
217217
}
218218
};
219219

@@ -229,12 +229,12 @@ impl<B: UsbBus> ControlPipe<'_, B> {
229229
// There isn't much we can do if the write fails, except to wait for another poll or for
230230
// the host to resend the request.
231231
Err(_err) => {
232-
usb_debug!("Failed to write EP0-IN: {_err:?}");
232+
usb_debug!("Failed to write EP0: {_err:?}");
233233
return;
234234
}
235235
};
236236

237-
usb_trace!("wrote EP0-IN: {:?}", &buffer[self.i..(self.i + count)]);
237+
usb_trace!("wrote EP0: {:?}", &buffer[self.i..(self.i + count)]);
238238

239239
self.i += count;
240240

@@ -252,7 +252,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
252252
pub fn accept_out(&mut self) -> Result<()> {
253253
match self.state {
254254
ControlState::CompleteOut => {}
255-
_ => return Err(UsbError::InvalidState),
255+
_ => {
256+
usb_debug!("Cannot ACK, invalid state: {:?}", self.state);
257+
return Err(UsbError::InvalidState)
258+
},
256259
};
257260

258261
let _ = self.ep_in.write(&[]);
@@ -263,7 +266,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
263266
pub fn accept_in(&mut self, f: impl FnOnce(&mut [u8]) -> Result<usize>) -> Result<()> {
264267
let req = match self.state {
265268
ControlState::CompleteIn(req) => req,
266-
_ => return Err(UsbError::InvalidState),
269+
_ => {
270+
usb_debug!("EP0-IN cannot ACK, invalid state: {:?}", self.state);
271+
return Err(UsbError::InvalidState);
272+
},
267273
};
268274

269275
let len = f(&mut self.buf[..])?;
@@ -279,7 +285,10 @@ impl<B: UsbBus> ControlPipe<'_, B> {
279285
pub fn accept_in_static(&mut self, data: &'static [u8]) -> Result<()> {
280286
let req = match self.state {
281287
ControlState::CompleteIn(req) => req,
282-
_ => return Err(UsbError::InvalidState),
288+
_ => {
289+
usb_debug!("EP0-IN cannot ACK, invalid state: {:?}", self.state);
290+
return Err(UsbError::InvalidState);
291+
}
283292
};
284293

285294
self.static_in_buf = Some(data);
@@ -297,6 +306,7 @@ impl<B: UsbBus> ControlPipe<'_, B> {
297306
}
298307

299308
pub fn reject(&mut self) -> Result<()> {
309+
usb_debug!("EP0 transfer rejected");
300310
if !self.waiting_for_response() {
301311
return Err(UsbError::InvalidState);
302312
}

src/device.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -205,28 +205,11 @@ impl<B: UsbBus> UsbDevice<'_, B> {
205205
// Pending events for endpoint 0?
206206
if (eps & 1) != 0 {
207207
usb_debug!(
208-
"EP0: setup={}, in={}, out={}",
208+
"EP0: setup={}, in_complete={}, out={}",
209209
ep_setup & 1,
210210
ep_in_complete & 1,
211211
ep_out & 1
212212
);
213-
// Handle EP0-IN conditions first. When both EP0-IN and EP0-OUT have completed,
214-
// it is possible that EP0-OUT is a zero-sized out packet to complete the STATUS
215-
// phase of the control transfer. We have to process EP0-IN first to update our
216-
// internal state properly.
217-
if (ep_in_complete & 1) != 0 {
218-
let completed = self.control.handle_in_complete();
219-
220-
if !B::QUIRK_SET_ADDRESS_BEFORE_STATUS
221-
&& completed
222-
&& self.pending_address != 0
223-
{
224-
self.bus.set_device_address(self.pending_address);
225-
self.pending_address = 0;
226-
227-
self.device_state = UsbDeviceState::Addressed;
228-
}
229-
}
230213

231214
let req = if (ep_setup & 1) != 0 {
232215
self.control.handle_setup()
@@ -236,17 +219,34 @@ impl<B: UsbBus> UsbDevice<'_, B> {
236219
None
237220
};
238221

239-
if let Some(_req) = req {
240-
usb_trace!("Handling EP0 request: {_req}");
241-
}
242-
243222
match req {
244223
Some(req) if req.direction == UsbDirection::In => {
245224
self.control_in(classes, req)
246225
}
247226
Some(req) if req.direction == UsbDirection::Out => {
248227
self.control_out(classes, req)
249228
}
229+
230+
None if ((ep_in_complete & 1) != 0) => {
231+
// We only handle EP0-IN completion if there's no other request being
232+
// processed. EP0-IN tokens may be issued due to completed STATUS
233+
// phases of the control transfer. If we just got a SETUP packet or
234+
// an OUT token, we can safely ignore the IN-COMPLETE indication and
235+
// continue with the next transfer.
236+
let completed = self.control.handle_in_complete();
237+
238+
if !B::QUIRK_SET_ADDRESS_BEFORE_STATUS
239+
&& completed
240+
&& self.pending_address != 0
241+
{
242+
self.bus.set_device_address(self.pending_address);
243+
self.pending_address = 0;
244+
245+
self.device_state = UsbDeviceState::Addressed;
246+
}
247+
248+
},
249+
250250
_ => (),
251251
};
252252

0 commit comments

Comments
 (0)