usb_queue: Use ldrex/strex to avoid disabling interrupts

This commit is contained in:
Ben Gamari
2013-07-07 21:54:25 -04:00
parent e23cc9bd6c
commit f50253eaa3

View File

@ -26,6 +26,7 @@
#include <assert.h> #include <assert.h>
#include <libopencm3/cm3/cortex.h> #include <libopencm3/cm3/cortex.h>
#include <libopencm3/cm3/sync.h>
#include "usb.h" #include "usb.h"
#include "usb_queue.h" #include "usb_queue.h"
@ -61,19 +62,25 @@ void usb_queue_init() {
/* Allocate a transfer */ /* Allocate a transfer */
static usb_transfer_t* allocate_transfer() static usb_transfer_t* allocate_transfer()
{ {
bool aborted;
usb_transfer_t* transfer;
while (free_transfers == NULL); while (free_transfers == NULL);
cm_disable_interrupts(); do {
usb_transfer_t* const transfer = free_transfers; transfer = (void *) __ldrex((uint32_t *) &free_transfers);
free_transfers = transfer->next; aborted = __strex((uint32_t) transfer->next, (uint32_t *) &free_transfers);
cm_enable_interrupts(); } while (aborted);
transfer->next = NULL;
return transfer; return transfer;
} }
/* Place a transfer in the free list */ /* Place a transfer in the free list */
static void free_transfer(usb_transfer_t* const transfer) static void free_transfer(usb_transfer_t* const transfer)
{ {
transfer->next = free_transfers; bool aborted;
free_transfers = transfer; do {
transfer->next = (void *) __ldrex((uint32_t *) &free_transfers);
aborted = __strex((uint32_t) transfer, (uint32_t *) &free_transfers);
} while (aborted);
} }
/* Add a transfer to the end of an endpoint's queue */ /* Add a transfer to the end of an endpoint's queue */