usb_queue: Use ldrex/strex to avoid disabling interrupts
This commit is contained in:
@ -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 */
|
||||||
|
Reference in New Issue
Block a user