diff options
| author | Keith Packard <keithp@keithp.com> | 2012-06-27 14:35:56 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-06-27 14:35:56 -0700 | 
| commit | e63d624f9670b5e2e002fcd5f24b80cf7f1effdf (patch) | |
| tree | 2a8b65d119e340643e463ad9873186502646823d /src | |
| parent | 08a4ed8fe794a2b2b52147bd5535fe0954822e95 (diff) | |
altos: reorder stm USB state stores to avoid races
Must set ao_usb_in_pending before telling USB about new data or an
interrupt could arrive at the wrong time to clear it.
Same for ao_usb_in_flushed.
Without these changes, I've seen the USB bus lock up on occasion,
waiting for an IN packet to consume data, but with no IN data pending
in the hardware.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/stm/ao_usb_stm.c | 4 | 
1 files changed, 2 insertions, 2 deletions
| diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index c093f526..4f37a7d9 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -792,10 +792,10 @@ static void  ao_usb_in_send(void)  {  	debug ("send %d\n", ao_usb_tx_count); +	ao_usb_in_pending = 1;  	ao_usb_write(ao_usb_tx_buffer, ao_usb_in_tx_buffer, 0, ao_usb_tx_count);  	ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = ao_usb_tx_count;  	ao_usb_set_stat_tx(AO_USB_IN_EPR, STM_USB_EPR_STAT_TX_VALID); -	ao_usb_in_pending = 1;  	ao_usb_tx_count = 0;  } @@ -848,12 +848,12 @@ ao_usb_putchar(char c) __critical __reentrant  	ao_usb_in_wait(); +	ao_usb_in_flushed = 0;  	ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c;  	/* Send the packet when full */  	if (ao_usb_tx_count == AO_USB_IN_SIZE)  		ao_usb_in_send(); -	ao_usb_in_flushed = 0;  }  static void | 
