1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-07-05 05:57:38 +03:00

atusb/fw/usb/atu2.c: use implicit race-free "and" when writing to UDINT/UEINTX

The old code could accidently acknowledge interrupts that appeared
between the read and the write in UxINTx &= mask.

- atu2.c (handle_ep): writing to UEINTX implies a race-free "and"
- atu2.c (usb_poll): writing to UDINT implies a race-free "and"
This commit is contained in:
Werner Almesberger 2011-06-11 07:21:17 -03:00
parent a69916da52
commit f9681e5b4f

View File

@ -134,7 +134,7 @@ static void handle_ep(int n)
ep->state = EP_IDLE; ep->state = EP_IDLE;
if (!ep_setup()) if (!ep_setup())
goto stall; goto stall;
UEINTX &= ~(1 << RXSTPI); UEINTX = ~(1 << RXSTPI);
} }
if (UEINTX & (1 << RXOUTI)) { if (UEINTX & (1 << RXOUTI)) {
/* @@ EP_TX: cancel */ /* @@ EP_TX: cancel */
@ -142,18 +142,18 @@ static void handle_ep(int n)
goto stall; goto stall;
if (!ep_rx(ep)) if (!ep_rx(ep))
goto stall; goto stall;
// UEINTX &= ~(1 << RXOUTI); /* @@@ gcc 4.5.2 wants this cast */
UEINTX &= ~(1 << RXOUTI | 1 << FIFOCON); UEINTX = (uint8_t) ~(1 << RXOUTI | 1 << FIFOCON);
} }
if (UEINTX & (1 << STALLEDI)) { if (UEINTX & (1 << STALLEDI)) {
ep->state = EP_IDLE; ep->state = EP_IDLE;
UEINTX &= ~(1 << STALLEDI); UEINTX = ~(1 << STALLEDI);
} }
if (UEINTX & (1 << TXINI)) { if (UEINTX & (1 << TXINI)) {
/* @@ EP_RX: cancel (?) */ /* @@ EP_RX: cancel (?) */
if (ep->state == EP_TX) { if (ep->state == EP_TX) {
ep_tx(ep); ep_tx(ep);
UEINTX &= ~(1 << TXINI); UEINTX = ~(1 << TXINI);
if (ep->state == EP_IDLE && ep->callback) if (ep->state == EP_IDLE && ep->callback)
ep->callback(ep->user); ep->callback(ep->user);
} }
@ -161,7 +161,7 @@ static void handle_ep(int n)
return; return;
stall: stall:
UEINTX &= ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI); UEINTX = ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI);
ep->state = EP_IDLE; ep->state = EP_IDLE;
UECONX |= 1 << STALLRQ; UECONX |= 1 << STALLRQ;
} }
@ -191,7 +191,7 @@ void usb_poll(void)
if (user_reset) if (user_reset)
user_reset(); user_reset();
ep_init(); ep_init();
UDINT &= ~(1 << EORSTI); UDINT = ~(1 << EORSTI);
} }
flags = UEINT; flags = UEINT;
for (i = 0; i != NUM_EPS; i++) for (i = 0; i != NUM_EPS; i++)