stm32/usb_otg: prevent writes on disabled endpoint
This commit is contained in:
		
							parent
							
								
									d2f2b451d0
								
							
						
					
					
						commit
						f07e59b24a
					
				| @ -1126,6 +1126,8 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointOut for Endpoint<'d, T, Out> { | |||||||
| 
 | 
 | ||||||
| impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { | impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { | ||||||
|     async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { |     async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { | ||||||
|  |         trace!("write ep={} data={}", self.info.addr, buf); | ||||||
|  | 
 | ||||||
|         if buf.len() > self.info.max_packet_size as usize { |         if buf.len() > self.info.max_packet_size as usize { | ||||||
|             return Err(EndpointError::BufferOverflow); |             return Err(EndpointError::BufferOverflow); | ||||||
|         } |         } | ||||||
| @ -1134,18 +1136,21 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { | |||||||
|         let index = self.info.addr.index(); |         let index = self.info.addr.index(); | ||||||
|         let state = T::state(); |         let state = T::state(); | ||||||
| 
 | 
 | ||||||
|         // Wait for previous transfer to complete
 |         // Wait for previous transfer to complete and check if endpoint is disabled
 | ||||||
|         poll_fn(|cx| { |         poll_fn(|cx| { | ||||||
|             state.ep_in_wakers[index].register(cx.waker()); |             state.ep_in_wakers[index].register(cx.waker()); | ||||||
| 
 | 
 | ||||||
|             // SAFETY: atomic read with no side effects
 |             // SAFETY: atomic read with no side effects
 | ||||||
|             if unsafe { r.diepctl(index).read().epena() } { |             let diepctl = unsafe { r.diepctl(index).read() }; | ||||||
|                 Poll::Pending |             if !diepctl.usbaep() { | ||||||
|  |                 Poll::Ready(Err(EndpointError::Disabled)) | ||||||
|  |             } else if !diepctl.epena() { | ||||||
|  |                 Poll::Ready(Ok(())) | ||||||
|             } else { |             } else { | ||||||
|                 Poll::Ready(()) |                 Poll::Pending | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|         .await; |         .await?; | ||||||
| 
 | 
 | ||||||
|         if buf.len() > 0 { |         if buf.len() > 0 { | ||||||
|             poll_fn(|cx| { |             poll_fn(|cx| { | ||||||
| @ -1201,7 +1206,7 @@ impl<'d, T: Instance> embassy_usb_driver::EndpointIn for Endpoint<'d, T, In> { | |||||||
|             unsafe { r.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))) }; |             unsafe { r.fifo(index).write_value(regs::Fifo(u32::from_ne_bytes(tmp))) }; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         trace!("WRITE OK"); |         trace!("write done ep={}", self.info.addr); | ||||||
| 
 | 
 | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| @ -1239,8 +1244,8 @@ impl<'d, T: Instance> embassy_usb_driver::ControlPipe for ControlPipe<'d, T> { | |||||||
|                     // Clear NAK to indicate we are ready to receive more data
 |                     // Clear NAK to indicate we are ready to receive more data
 | ||||||
|                     T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| { |                     T::regs().doepctl(self.ep_out.info.addr.index()).modify(|w| { | ||||||
|                         w.set_cnak(true); |                         w.set_cnak(true); | ||||||
|                     }) |                     }); | ||||||
|                 }; |                 } | ||||||
| 
 | 
 | ||||||
|                 trace!("SETUP received: {:?}", data); |                 trace!("SETUP received: {:?}", data); | ||||||
|                 Poll::Ready(data) |                 Poll::Ready(data) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user