Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
O
OpenSK
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
koenigl2
OpenSK
Commits
951268b5
Commit
951268b5
authored
5 years ago
by
Guillaume Endignoux
Browse files
Options
Downloads
Patches
Plain Diff
Add patch for bidirectional USB endpoints to fix panics in case of cancellation.
parent
47bd524c
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
patches/tock/05-usb-cancel.patch
+747
-0
747 additions, 0 deletions
patches/tock/05-usb-cancel.patch
with
747 additions
and
0 deletions
patches/tock/05-usb-cancel.patch
0 → 100644
+
747
−
0
View file @
951268b5
diff --git a/capsules/src/usb/usbc_client.rs b/capsules/src/usb/usbc_client.rs
index b0678c23..9fb43781 100644
--- a/capsules/src/usb/usbc_client.rs
+++ b/capsules/src/usb/usbc_client.rs
@@ -115,11 +115,11 @@
impl<'a, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for Client<'a, C>
self.client_ctrl.enable();
// Set up a bulk-in endpoint for debugging
- self.controller().endpoint_set_buffer(1, self.buffer(1));
+ self.controller().endpoint_set_in_buffer(1, self.buffer(1));
self.controller().endpoint_in_enable(TransferType::Bulk, 1);
// Set up a bulk-out endpoint for debugging
- self.controller().endpoint_set_buffer(2, self.buffer(2));
+ self.controller().endpoint_set_out_buffer(2, self.buffer(2));
self.controller().endpoint_out_enable(TransferType::Bulk, 2);
}
diff --git a/capsules/src/usb/usbc_client_ctrl.rs b/capsules/src/usb/usbc_client_ctrl.rs
index 2aaca0cc..5f9b253c 100644
--- a/capsules/src/usb/usbc_client_ctrl.rs
+++ b/capsules/src/usb/usbc_client_ctrl.rs
@@ -201,7 +201,7 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, C> {
pub fn enable(&'a self) {
// Set up the default control endpoint
self.controller
- .endpoint_set_buffer(0, &self.ctrl_buffer.buf);
+ .endpoint_set_ctrl_buffer(&self.ctrl_buffer.buf);
self.controller
.enable_as_device(hil::usb::DeviceSpeed::Full); // must be Full for Bulk transfers
self.controller
diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs
index fdf7263a..4b1916cf 100644
--- a/capsules/src/usb/usbc_ctap_hid.rs
+++ b/capsules/src/usb/usbc_ctap_hid.rs
@@ -88,8 +88,9 @@
static HID: HIDDescriptor<'static> = HIDDescriptor {
pub struct ClientCtapHID<'a, 'b, C: 'a> {
client_ctrl: ClientCtrl<'a, 'static, C>,
- // A 64-byte buffer for the endpoint
- buffer: Buffer64,
+ // 64-byte buffers for the endpoint
+ in_buffer: Buffer64,
+ out_buffer: Buffer64,
// Interaction with the client
client: OptionalCell<&'b dyn CtapUsbClient>,
@@ -133,7 +134,8 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> {
LANGUAGES,
STRINGS,
),
- buffer: Default::default(),
+ in_buffer: Default::default(),
+ out_buffer: Default::default(),
client: OptionalCell::empty(),
tx_packet: OptionalCell::empty(),
pending_in: Cell::new(false),
@@ -187,7 +189,7 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> {
fn send_packet_to_client(&'a self) -> bool {
// Copy the packet into a buffer to send to the client.
let mut buf: [u8; 64] = [0; 64];
- for (i, x) in self.buffer.buf.iter().enumerate() {
+ for (i, x) in self.out_buffer.buf.iter().enumerate() {
buf[i] = x.get();
}
@@ -220,11 +222,7 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> {
fn cancel_in_transaction(&'a self) -> bool {
self.tx_packet.take();
- let result = self.pending_in.take();
- if result {
- self.controller().endpoint_cancel_in(1);
- }
- result
+ self.pending_in.take()
}
fn cancel_out_transaction(&'a self) -> bool {
@@ -243,7 +241,10 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap
self.client_ctrl.enable();
// Set up the interrupt in-out endpoint
- self.controller().endpoint_set_buffer(1, &self.buffer.buf);
+ self.controller()
+ .endpoint_set_in_buffer(1, &self.in_buffer.buf);
+ self.controller()
+ .endpoint_set_out_buffer(1, &self.out_buffer.buf);
self.controller()
.endpoint_in_out_enable(TransferType::Interrupt, 1);
}
@@ -293,7 +294,7 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap
}
if let Some(packet) = self.tx_packet.take() {
- let buf = &self.buffer.buf;
+ let buf = &self.in_buffer.buf;
for i in 0..64 {
buf[i].set(packet[i]);
}
@@ -346,6 +347,12 @@
impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap
panic!("Unexpected tx_packet while a packet was being transmitted.");
}
self.pending_in.set(false);
+
+ // Clear any pending packet on the receiving side.
+ // It's up to the client to handle the transmitted packet and decide if they want to
+ // receive another packet.
+ self.cancel_out_transaction();
+
// Notify the client
self.client.map(|client| client.packet_transmitted());
}
diff --git a/chips/nrf52/src/usbd.rs b/chips/nrf52/src/usbd.rs
index 8c1992cc..972871d0 100644
--- a/chips/nrf52/src/usbd.rs
+++ b/chips/nrf52/src/usbd.rs
@@ -623,7 +623,7 @@
pub enum UsbState {
pub enum EndpointState {
Disabled,
Ctrl(CtrlState),
- Bulk(TransferType, EndpointDirection, BulkState),
+ Bulk(TransferType, Option<BulkInState>, Option<BulkOutState>),
}
impl EndpointState {
@@ -634,10 +634,10 @@
impl EndpointState {
}
}
- fn bulk_state(self) -> (TransferType, EndpointDirection, BulkState) {
+ fn bulk_state(self) -> (TransferType, Option<BulkInState>, Option<BulkOutState>) {
match self {
- EndpointState::Bulk(transfer_type, direction, state) => {
- (transfer_type, direction, state)
+ EndpointState::Bulk(transfer_type, in_state, out_state) => {
+ (transfer_type, in_state, out_state)
}
_ => panic!("Expected EndpointState::Bulk"),
}
@@ -651,31 +651,18 @@
pub enum CtrlState {
ReadStatus,
}
-#[derive(Copy, Clone, Debug)]
-pub enum EndpointDirection {
- In,
- Out,
- InOut,
-}
-
-impl EndpointDirection {
- fn has_in(&self) -> bool {
- match self {
- EndpointDirection::In | EndpointDirection::InOut => true,
- EndpointDirection::Out => false,
- }
- }
-
- fn has_out(&self) -> bool {
- match self {
- EndpointDirection::Out | EndpointDirection::InOut => true,
- EndpointDirection::In => false,
- }
- }
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum BulkInState {
+ // The endpoint is ready to perform transactions.
+ Init,
+ // There is a pending DMA transfer on this IN endpoint.
+ InDma,
+ // There is a pending IN packet transfer on this endpoint.
+ InData,
}
#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum BulkState {
+pub enum BulkOutState {
// The endpoint is ready to perform transactions.
Init,
// There is a pending OUT packet in this endpoint's buffer, to be read by
@@ -685,14 +672,11 @@
pub enum BulkState {
OutData,
// There is a pending DMA transfer on this OUT endpoint.
OutDma,
- // There is a pending DMA transfer on this IN endpoint.
- InDma,
- // There is a pending IN packet transfer on this endpoint.
- InData,
}
pub struct Endpoint<'a> {
- slice: OptionalCell<&'a [VolatileCell<u8>]>,
+ slice_in: OptionalCell<&'a [VolatileCell<u8>]>,
+ slice_out: OptionalCell<&'a [VolatileCell<u8>]>,
state: Cell<EndpointState>,
// The USB controller can only process one DMA transfer at a time (over all endpoints). The
// request_transmit_* bits allow to queue transfers until the DMA becomes available again.
@@ -705,7 +689,8 @@
pub struct Endpoint<'a> {
impl Endpoint<'_> {
const fn new() -> Self {
Endpoint {
- slice: OptionalCell::empty(),
+ slice_in: OptionalCell::empty(),
+ slice_out: OptionalCell::empty(),
state: Cell::new(EndpointState::Disabled),
request_transmit_in: Cell::new(false),
request_transmit_out: Cell::new(false),
@@ -914,18 +899,12 @@
impl<'a> Usbd<'a> {
chip_revision.get()
);
}
- Some(ChipRevision::REV::Value::REVC) => {
+ Some(ChipRevision::REV::Value::REVC) | Some(ChipRevision::REV::Value::REVD) => {
debug_info!(
"Your chip is NRF52840 revision {}. The USB stack was tested on your chip :)",
chip_revision.get()
);
}
- Some(ChipRevision::REV::Value::REVD) => {
- internal_warn!(
- "Your chip is NRF52840 revision {}. Although this USB implementation should be compatible, your chip hasn't been tested.",
- chip_revision.get()
- );
- }
None => {
internal_warn!(
"Your chip is NRF52840 revision {} (unknown revision). Although this USB implementation should be compatible, your chip hasn't been tested.",
@@ -1026,7 +1005,7 @@
impl<'a> Usbd<'a> {
});
self.descriptors[endpoint].state.set(match endpoint {
0 => EndpointState::Ctrl(CtrlState::Init),
- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::In, BulkState::Init),
+ 1..=7 => EndpointState::Bulk(transfer_type, Some(BulkInState::Init), None),
8 => unimplemented!("isochronous endpoint"),
_ => unreachable!("unexisting endpoint"),
});
@@ -1064,7 +1043,7 @@
impl<'a> Usbd<'a> {
});
self.descriptors[endpoint].state.set(match endpoint {
0 => EndpointState::Ctrl(CtrlState::Init),
- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::Out, BulkState::Init),
+ 1..=7 => EndpointState::Bulk(transfer_type, None, Some(BulkOutState::Init)),
8 => unimplemented!("isochronous endpoint"),
_ => unreachable!("unexisting endpoint"),
});
@@ -1114,7 +1093,11 @@
impl<'a> Usbd<'a> {
});
self.descriptors[endpoint].state.set(match endpoint {
0 => EndpointState::Ctrl(CtrlState::Init),
- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::InOut, BulkState::Init),
+ 1..=7 => EndpointState::Bulk(
+ transfer_type,
+ Some(BulkInState::Init),
+ Some(BulkOutState::Init),
+ ),
8 => unimplemented!("isochronous endpoint"),
_ => unreachable!("unexisting endpoint"),
});
@@ -1304,13 +1287,13 @@
impl<'a> Usbd<'a> {
match desc.state.get() {
EndpointState::Disabled => {}
EndpointState::Ctrl(_) => desc.state.set(EndpointState::Ctrl(CtrlState::Init)),
- EndpointState::Bulk(transfer_type, direction, _) => {
+ EndpointState::Bulk(transfer_type, in_state, out_state) => {
desc.state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::Init,
+ in_state.map(|_| BulkInState::Init),
+ out_state.map(|_| BulkOutState::Init),
));
- if direction.has_out() {
+ if out_state.is_some() {
// Accept incoming OUT packets.
regs.size_epout[ep].set(0);
}
@@ -1347,13 +1330,13 @@
impl<'a> Usbd<'a> {
match endpoint {
0 => {}
1..=7 => {
- let (transfer_type, direction, state) =
+ let (transfer_type, in_state, out_state) =
self.descriptors[endpoint].state.get().bulk_state();
- assert_eq!(state, BulkState::InDma);
+ assert_eq!(in_state, Some(BulkInState::InDma));
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::InData,
+ Some(BulkInState::InData),
+ out_state,
));
}
8 => unimplemented!("isochronous endpoint"),
@@ -1405,25 +1388,25 @@
impl<'a> Usbd<'a> {
1..=7 => {
// Notify the client about the new packet.
let packet_bytes = regs.size_epout[endpoint].get();
- let (transfer_type, direction, state) =
+ let (transfer_type, in_state, out_state) =
self.descriptors[endpoint].state.get().bulk_state();
- assert_eq!(state, BulkState::OutDma);
+ assert_eq!(out_state, Some(BulkOutState::OutDma));
- self.debug_packet("out", packet_bytes as usize, endpoint);
+ self.debug_out_packet(packet_bytes as usize, endpoint);
self.client.map(|client| {
let result = client.packet_out(transfer_type, endpoint, packet_bytes);
debug_packets!("packet_out => {:?}", result);
- let newstate = match result {
+ let new_out_state = match result {
hil::usb::OutResult::Ok => {
// Indicate that the endpoint is ready to receive data again.
regs.size_epout[endpoint].set(0);
- BulkState::Init
+ BulkOutState::Init
}
hil::usb::OutResult::Delay => {
// We can't send the packet now. Wait for a resume_out call from the client.
- BulkState::OutDelay
+ BulkOutState::OutDelay
}
hil::usb::OutResult::Error => {
@@ -1432,13 +1415,13 @@
impl<'a> Usbd<'a> {
+ EndpointStall::IO::Out
+ EndpointStall::STALL::Stall,
);
- BulkState::Init
+ BulkOutState::Init
}
};
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- newstate,
+ in_state,
+ Some(new_out_state),
));
});
}
@@ -1497,29 +1480,27 @@
impl<'a> Usbd<'a> {
// Endpoint 8 (isochronous) doesn't receive any EPDATA event.
for endpoint in 1..NUM_ENDPOINTS {
if epdatastatus.is_set(status_epin(endpoint)) {
- let (transfer_type, direction, state) =
+ let (transfer_type, in_state, out_state) =
self.descriptors[endpoint].state.get().bulk_state();
- match state {
- BulkState::InData => {
+ assert!(in_state.is_some());
+ match in_state.unwrap() {
+ BulkInState::InData => {
// Totally expected state. Nothing to do.
}
- BulkState::Init => {
+ BulkInState::Init => {
internal_warn!(
"Received a stale epdata IN in an unexpected state: {:?}",
- state
+ in_state
);
}
- BulkState::OutDelay
- | BulkState::OutData
- | BulkState::OutDma
- | BulkState::InDma => {
- internal_err!("Unexpected state: {:?}", state);
+ BulkInState::InDma => {
+ internal_err!("Unexpected state: {:?}", in_state);
}
}
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::Init,
+ Some(BulkInState::Init),
+ out_state,
));
self.client
.map(|client| client.packet_transmitted(endpoint));
@@ -1530,28 +1511,26 @@
impl<'a> Usbd<'a> {
// Endpoint 8 (isochronous) doesn't receive any EPDATA event.
for ep in 1..NUM_ENDPOINTS {
if epdatastatus.is_set(status_epout(ep)) {
- let (transfer_type, direction, state) =
+ let (transfer_type, in_state, out_state) =
self.descriptors[ep].state.get().bulk_state();
- match state {
- BulkState::Init => {
+ assert!(out_state.is_some());
+ match out_state.unwrap() {
+ BulkOutState::Init => {
// The endpoint is ready to receive data. Request a transmit_out.
self.descriptors[ep].request_transmit_out.set(true);
}
- BulkState::OutDelay => {
+ BulkOutState::OutDelay => {
// The endpoint will be resumed later by the client application with transmit_out().
}
- BulkState::OutData
- | BulkState::OutDma
- | BulkState::InDma
- | BulkState::InData => {
- internal_err!("Unexpected state: {:?}", state);
+ BulkOutState::OutData | BulkOutState::OutDma => {
+ internal_err!("Unexpected state: {:?}", out_state);
}
}
// Indicate that the endpoint now has data available.
self.descriptors[ep].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::OutData,
+ in_state,
+ Some(BulkOutState::OutData),
));
}
}
@@ -1564,8 +1543,8 @@
impl<'a> Usbd<'a> {
let state = self.descriptors[endpoint].state.get().ctrl_state();
match state {
CtrlState::Init => {
- let ep_buf = &self.descriptors[endpoint].slice;
- let ep_buf = ep_buf.expect("No slice set for this descriptor");
+ let ep_buf = &self.descriptors[endpoint].slice_out;
+ let ep_buf = ep_buf.expect("No OUT slice set for this descriptor");
if ep_buf.len() < 8 {
panic!("EP0 DMA buffer length < 8");
}
@@ -1697,21 +1676,21 @@
impl<'a> Usbd<'a> {
let regs = &*self.registers;
self.client.map(|client| {
- let (transfer_type, direction, state) =
+ let (transfer_type, in_state, out_state) =
self.descriptors[endpoint].state.get().bulk_state();
- assert_eq!(state, BulkState::Init);
+ assert_eq!(in_state, Some(BulkInState::Init));
let result = client.packet_in(transfer_type, endpoint);
debug_packets!("packet_in => {:?}", result);
- let newstate = match result {
+ let new_in_state = match result {
hil::usb::InResult::Packet(size) => {
self.start_dma_in(endpoint, size);
- BulkState::InDma
+ BulkInState::InDma
}
hil::usb::InResult::Delay => {
// No packet to send now. Wait for a resume call from the client.
- BulkState::Init
+ BulkInState::Init
}
hil::usb::InResult::Error => {
@@ -1720,14 +1699,14 @@
impl<'a> Usbd<'a> {
+ EndpointStall::IO::In
+ EndpointStall::STALL::Stall,
);
- BulkState::Init
+ BulkInState::Init
}
};
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- newstate,
+ Some(new_in_state),
+ out_state,
));
});
}
@@ -1735,15 +1714,16 @@
impl<'a> Usbd<'a> {
fn transmit_out(&self, endpoint: usize) {
debug_events!("transmit_out({})", endpoint);
- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state();
+ let (transfer_type, in_state, out_state) =
+ self.descriptors[endpoint].state.get().bulk_state();
// Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event.
- assert_eq!(state, BulkState::OutData);
+ assert_eq!(out_state, Some(BulkOutState::OutData));
self.start_dma_out(endpoint);
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::OutDma,
+ in_state,
+ Some(BulkOutState::OutDma),
));
}
@@ -1751,9 +1731,9 @@
impl<'a> Usbd<'a> {
let regs = &*self.registers;
let slice = self.descriptors[endpoint]
- .slice
- .expect("No slice set for this descriptor");
- self.debug_packet("in", size, endpoint);
+ .slice_in
+ .expect("No IN slice set for this descriptor");
+ self.debug_in_packet(size, endpoint);
// Start DMA transfer
self.set_pending_dma();
@@ -1766,8 +1746,8 @@
impl<'a> Usbd<'a> {
let regs = &*self.registers;
let slice = self.descriptors[endpoint]
- .slice
- .expect("No slice set for this descriptor");
+ .slice_out
+ .expect("No OUT slice set for this descriptor");
// Start DMA transfer
self.set_pending_dma();
@@ -1777,10 +1757,27 @@
impl<'a> Usbd<'a> {
}
// Debug-only function
- fn debug_packet(&self, _title: &str, size: usize, endpoint: usize) {
+ fn debug_in_packet(&self, size: usize, endpoint: usize) {
+ let slice = self.descriptors[endpoint]
+ .slice_in
+ .expect("No IN slice set for this descriptor");
+ if size > slice.len() {
+ panic!("Packet is too large: {}", size);
+ }
+
+ let mut packet_hex = [0; 128];
+ packet_to_hex(slice, &mut packet_hex);
+ debug_packets!(
+ "in={}",
+ core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
+ );
+ }
+
+ // Debug-only function
+ fn debug_out_packet(&self, size: usize, endpoint: usize) {
let slice = self.descriptors[endpoint]
- .slice
- .expect("No slice set for this descriptor");
+ .slice_out
+ .expect("No OUT slice set for this descriptor");
if size > slice.len() {
panic!("Packet is too large: {}", size);
}
@@ -1788,8 +1785,7 @@
impl<'a> Usbd<'a> {
let mut packet_hex = [0; 128];
packet_to_hex(slice, &mut packet_hex);
debug_packets!(
- "{}={}",
- _title,
+ "out={}",
core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap()
);
}
@@ -1807,17 +1803,41 @@
impl<'a> power::PowerClient for Usbd<'a> {
}
impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) {
+ if buf.len() < 8 {
+ panic!("Endpoint buffer must be at least 8 bytes");
+ }
+ if !buf.len().is_power_of_two() {
+ panic!("Buffer size must be a power of 2");
+ }
+ self.descriptors[0].slice_in.set(buf);
+ self.descriptors[0].slice_out.set(buf);
+ }
+
+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
+ if buf.len() < 8 {
+ panic!("Endpoint buffer must be at least 8 bytes");
+ }
+ if !buf.len().is_power_of_two() {
+ panic!("Buffer size must be a power of 2");
+ }
+ if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
+ panic!("Endpoint number is invalid");
+ }
+ self.descriptors[endpoint].slice_in.set(buf);
+ }
+
+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
if buf.len() < 8 {
panic!("Endpoint buffer must be at least 8 bytes");
}
if !buf.len().is_power_of_two() {
panic!("Buffer size must be a power of 2");
}
- if endpoint >= NUM_ENDPOINTS {
- panic!("Endpoint number is too high");
+ if endpoint == 0 || endpoint >= NUM_ENDPOINTS {
+ panic!("Endpoint number is invalid");
}
- self.descriptors[endpoint].slice.set(buf);
+ self.descriptors[endpoint].slice_out.set(buf);
}
fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
@@ -1900,8 +1920,8 @@
impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
fn endpoint_resume_in(&self, endpoint: usize) {
debug_events!("endpoint_resume_in({})", endpoint);
- let (_, direction, _) = self.descriptors[endpoint].state.get().bulk_state();
- assert!(direction.has_in());
+ let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state();
+ assert!(in_state.is_some());
if self.dma_pending.get() {
debug_events!("requesting resume_in[{}]", endpoint);
@@ -1916,20 +1936,21 @@
impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
fn endpoint_resume_out(&self, endpoint: usize) {
debug_events!("endpoint_resume_out({})", endpoint);
- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state();
- assert!(direction.has_out());
+ let (transfer_type, in_state, out_state) =
+ self.descriptors[endpoint].state.get().bulk_state();
+ assert!(out_state.is_some());
- match state {
- BulkState::OutDelay => {
+ match out_state.unwrap() {
+ BulkOutState::OutDelay => {
// The endpoint has now finished processing the last ENDEPOUT. No EPDATA event
// happened in the meantime, so the state is now back to Init.
self.descriptors[endpoint].state.set(EndpointState::Bulk(
transfer_type,
- direction,
- BulkState::Init,
+ in_state,
+ Some(BulkOutState::Init),
));
}
- BulkState::OutData => {
+ BulkOutState::OutData => {
// Although the client reported a delay before, an EPDATA event has
// happened in the meantime. This pending transaction will now
// continue in transmit_out().
@@ -1942,25 +1963,11 @@
impl<'a> hil::usb::UsbController<'a> for Usbd<'a> {
self.transmit_out(endpoint);
}
}
- BulkState::Init | BulkState::OutDma | BulkState::InDma | BulkState::InData => {
- internal_err!("Unexpected state: {:?}", state);
+ BulkOutState::Init | BulkOutState::OutDma => {
+ internal_err!("Unexpected state: {:?}", out_state);
}
}
}
-
- fn endpoint_cancel_in(&self, endpoint: usize) {
- debug_events!("endpoint_cancel_in({})", endpoint);
-
- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state();
- assert!(direction.has_in());
- assert_eq!(state, BulkState::InData);
-
- self.descriptors[endpoint].state.set(EndpointState::Bulk(
- transfer_type,
- direction,
- BulkState::Init,
- ));
- }
}
fn status_epin(ep: usize) -> Field<u32, EndpointStatus::Register> {
diff --git a/chips/sam4l/src/usbc/mod.rs b/chips/sam4l/src/usbc/mod.rs
index 28a0b9f9..ab5b636f 100644
--- a/chips/sam4l/src/usbc/mod.rs
+++ b/chips/sam4l/src/usbc/mod.rs
@@ -1438,11 +1438,28 @@
fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointCon
}
impl hil::usb::UsbController<'a> for Usbc<'a> {
- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) {
if buf.len() != 8 {
client_err!("Bad endpoint buffer size");
}
+ self._endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf);
+ }
+
+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
+ if buf.len() != 8 {
+ client_err!("Bad endpoint buffer size");
+ }
+
+ self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
+ }
+
+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) {
+ if buf.len() != 8 {
+ client_err!("Bad endpoint buffer size");
+ }
+
+ // XXX: when implementing in_out endpoints, this should probably set a different slice than endpoint_set_in_buffer.
self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
}
@@ -1547,10 +1564,6 @@
impl hil::usb::UsbController<'a> for Usbc<'a> {
requests.resume_out = true;
self.requests[endpoint].set(requests);
}
-
- fn endpoint_cancel_in(&self, _endpoint: usize) {
- unimplemented!()
- }
}
/// Static state to manage the USBC
diff --git a/kernel/src/hil/usb.rs b/kernel/src/hil/usb.rs
index 64610fa5..a114b30d 100644
--- a/kernel/src/hil/usb.rs
+++ b/kernel/src/hil/usb.rs
@@ -5,7 +5,9 @@
use crate::common::cells::VolatileCell;
/// USB controller interface
pub trait UsbController<'a> {
// Should be called before `enable_as_device()`
- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]);
+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]);
+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]);
+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]);
// Must be called before `attach()`
fn enable_as_device(&self, speed: DeviceSpeed);
@@ -27,8 +29,6 @@
pub trait UsbController<'a> {
fn endpoint_resume_in(&self, endpoint: usize);
fn endpoint_resume_out(&self, endpoint: usize);
-
- fn endpoint_cancel_in(&self, endpoint: usize);
}
#[derive(Clone, Copy, Debug)]
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment