aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2023-01-18 02:31:28 +0200
committerchemicstry <[email protected]>2023-01-18 02:31:28 +0200
commitf07e59b24a2fff6dfbfd52ac5f55fb2667dae0d8 (patch)
tree3b3076e2af3b5b0ad2e420977c970f56bcf436a1
parentd2f2b451d084448d442c6f9cb1c6b9f94a4fd447 (diff)
stm32/usb_otg: prevent writes on disabled endpoint
-rw-r--r--embassy-stm32/src/usb_otg/usb.rs21
1 files changed, 13 insertions, 8 deletions
diff --git a/embassy-stm32/src/usb_otg/usb.rs b/embassy-stm32/src/usb_otg/usb.rs
index 504a90f25..48c3ec019 100644
--- a/embassy-stm32/src/usb_otg/usb.rs
+++ b/embassy-stm32/src/usb_otg/usb.rs
@@ -1126,6 +1126,8 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointOut for Endpoint<'d, T, Out> {
1126 1126
1127impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { 1127impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> {
1128 async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { 1128 async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> {
1129 trace!("write ep={} data={}", self.info.addr, buf);
1130
1129 if buf.len() > self.info.max_packet_size as usize { 1131 if buf.len() > self.info.max_packet_size as usize {
1130 return Err(EndpointError::BufferOverflow); 1132 return Err(EndpointError::BufferOverflow);
1131 } 1133 }
@@ -1134,18 +1136,21 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> {
1134 let index = self.info.addr.index(); 1136 let index = self.info.addr.index();
1135 let state = T::state(); 1137 let state = T::state();
1136 1138
1137 // Wait for previous transfer to complete 1139 // Wait for previous transfer to complete and check if endpoint is disabled
1138 poll_fn(|cx| { 1140 poll_fn(|cx| {
1139 state.ep_in_wakers[index].register(cx.waker()); 1141 state.ep_in_wakers[index].register(cx.waker());
1140 1142
1141 // SAFETY: atomic read with no side effects 1143 // SAFETY: atomic read with no side effects
1142 if unsafe { r.diepctl(index).read().epena() } { 1144 let diepctl = unsafe { r.diepctl(index).read() };
1143 Poll::Pending 1145 if !diepctl.usbaep() {
1146 Poll::Ready(Err(EndpointError::Disabled))
1147 } else if !diepctl.epena() {
1148 Poll::Ready(Ok(()))
1144 } else { 1149 } else {
1145 Poll::Ready(()) 1150 Poll::Pending
1146 } 1151 }
1147 }) 1152 })
1148 .await; 1153 .await?;
1149 1154
1150 if buf.len() > 0 { 1155 if buf.len() > 0 {
1151 poll_fn(|cx| { 1156 poll_fn(|cx| {
@@ -1201,7 +1206,7 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> {
1201 unsafe { r.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))) }; 1206 unsafe { r.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))) };
1202 } 1207 }
1203 1208
1204 trace!("WRITE OK"); 1209 trace!("write done ep={}", self.info.addr);
1205 1210
1206 Ok(()) 1211 Ok(())
1207 } 1212 }
@@ -1239,8 +1244,8 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> {
1239 // Clear NAK to indicate we are ready to receive more data 1244 // Clear NAK to indicate we are ready to receive more data
1240 T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| { 1245 T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| {
1241 w.set_cnak(true); 1246 w.set_cnak(true);
1242 }) 1247 });
1243 }; 1248 }
1244 1249
1245 trace!("SETUP received: {:?}", data); 1250 trace!("SETUP received: {:?}", data);
1246 Poll::Ready(data) 1251 Poll::Ready(data)