@@ -207,69 +207,60 @@ static void usbd_write(uint8_t epnr, const void *buf, uint32_t len)
207207 usb -> epr [epnr ] = epr ;
208208}
209209
210- static void usbd_stall (uint8_t ep )
210+ static void usbd_stall (uint8_t epnr )
211211{
212- uint16_t epr = usb -> epr [ep ];
213- epr &= 0x073f ;
214- epr |= 0x8080 ;
215- epr ^= USB_EPR_STAT_TX (USB_STAT_STALL );
216- usb -> epr [ep ] = epr ;
212+ bool_t in ;
213+ uint16_t epr ;
214+
215+ in = !!(epnr & 0x80 );
216+ epnr &= 0x7f ;
217+ epr = usb -> epr [epnr ];
218+ epr |= 0x8080 ; /* preserve rc_w0 fields */
219+
220+ if (in ) {
221+ epr &= 0x073f ;
222+ epr ^= USB_EPR_STAT_TX (USB_STAT_STALL );
223+ } else {
224+ epr &= 0x370f ;
225+ epr ^= USB_EPR_STAT_RX (USB_STAT_STALL );
226+ }
227+
228+ usb -> epr [epnr ] = epr ;
217229}
218230
219- static void usbd_clear_halt (uint8_t epnr )
231+ static void usbd_clear_stall (uint8_t epnr )
220232{
221- bool_t in = !!(epnr & 0x80 );
222- struct ep * ep ;
223- volatile struct usb_bufd * bd ;
224- uint16_t old_epr , new_epr ;
225- uint32_t oldpri ;
233+ bool_t in , dbl_buf ;
234+ uint16_t epr ;
235+ int new_status = USB_STAT_VALID ;
226236
237+ in = !!(epnr & 0x80 );
227238 epnr &= 0x7f ;
228- ep = & eps [epnr ];
229- bd = & usb_bufd [epnr ];
230-
231- old_epr = usb -> epr [epnr ];
232- new_epr = old_epr & 0x070f ; /* preserve rw & t fields */
233-
234- if (ep -> is_dblbuf ) {
239+ epr = usb -> epr [epnr ];
240+ dbl_buf = !!(epr & USB_EPR_EP_KIND_DBL_BUF );
235241
236- /* Reset double-buffer ring and endpoint state to match
237- * usbd_configure_ep() initialisation. Buffer addresses
238- * (bd->addr_0/1) are not changed. */
239- oldpri = IRQ_save (USB_IRQ_PRI );
240- ep -> db .bufc = ep -> db .bufp = ep -> db .tx_hw_slots = 0 ;
241- if (in ) {
242- bd -> count_0 = bd -> count_1 = 0 ;
243- /* TX: Clears SW_BUF. */
244- new_epr |= old_epr & 0x4000 ;
245- /* TX: Clears data toggle and sets status to VALID. */
246- new_epr |= (old_epr & 0x0070 )
247- ^ USB_EPR_STAT_TX (USB_STAT_VALID );
248- ep -> db .kick = TRUE;
242+ /* Clear data toggle and set status to VALID or NAK as appropriate. */
243+ if (in ) {
244+ if (dbl_buf ) {
245+ epr ^= 0x4000 ; /* Set SW_BUF */
249246 } else {
250- bd -> count_0 = bd -> count_1 = 0x8400 ; /* USB_FS_MPS */
251- /* RX: Sets SW_BUF. */
252- new_epr |= (old_epr & 0x0040 ) ^ 0x0040 ;
253- ep -> db .kick = FALSE;
254- /* RX: Clears data toggle and sets status to VALID. */
255- new_epr |= (old_epr & 0x7000 )
256- ^ USB_EPR_STAT_RX (USB_STAT_VALID );
247+ epr &= ~0x4000 ;
248+ new_status = USB_STAT_NAK ;
257249 }
258- barrier ();
259- usb -> epr [epnr ] = new_epr ;
260- IRQ_restore (oldpri );
261-
250+ epr &= 0x477f ; /* preserve rw & t, except tx toggle and status */
251+ epr ^= USB_EPR_STAT_TX (new_status );
262252 } else {
263-
264- /* Standard endpoint: clear data toggle only. */
265- new_epr |= 0x8080 ; /* preserve rc_w0 fields */
266- if (in )
267- new_epr |= old_epr & USB_EPR_DTOG_TX ;
268- else
269- new_epr |= old_epr & USB_EPR_DTOG_RX ;
270- usb -> epr [epnr ] = new_epr ;
271-
253+ if (dbl_buf ) {
254+ epr |= 0x0040 ; /* Clear SW_BUF */
255+ } else {
256+ epr &= ~0x0040 ;
257+ }
258+ epr &= 0x774f ; /* preserve rw & t, except rx toggle and status */
259+ epr ^= USB_EPR_STAT_RX (new_status );
272260 }
261+
262+ epr |= 0x8080 ; /* preserve rc_w0 fields */
263+ usb -> epr [epnr ] = epr ;
273264}
274265
275266static void usbd_configure_ep (uint8_t epnr , uint8_t type , uint32_t size )
@@ -583,7 +574,7 @@ const struct usb_driver usbd = {
583574 .read = usbd_read ,
584575 .write = usbd_write ,
585576 .stall = usbd_stall ,
586- .clear_halt = usbd_clear_halt
577+ .clear_stall = usbd_clear_stall
587578};
588579
589580/*
0 commit comments