uhci: switch to QTAILQ

This commit is contained in:
Gerd Hoffmann 2010-12-14 18:19:47 +01:00
parent 19f3322379
commit ddf6583f88

View file

@ -113,7 +113,7 @@ static void dump_data(const uint8_t *data, int len) {}
*/ */
typedef struct UHCIAsync { typedef struct UHCIAsync {
USBPacket packet; USBPacket packet;
struct UHCIAsync *next; QTAILQ_ENTRY(UHCIAsync) next;
uint32_t td; uint32_t td;
uint32_t token; uint32_t token;
int8_t valid; int8_t valid;
@ -145,8 +145,7 @@ typedef struct UHCIState {
uint32_t pending_int_mask; uint32_t pending_int_mask;
/* Active packets */ /* Active packets */
UHCIAsync *async_pending; QTAILQ_HEAD(,UHCIAsync) async_pending;
UHCIAsync *async_pool;
uint8_t num_ports_vmstate; uint8_t num_ports_vmstate;
} UHCIState; } UHCIState;
@ -172,7 +171,6 @@ static UHCIAsync *uhci_async_alloc(UHCIState *s)
async->token = 0; async->token = 0;
async->done = 0; async->done = 0;
async->isoc = 0; async->isoc = 0;
async->next = NULL;
return async; return async;
} }
@ -184,24 +182,12 @@ static void uhci_async_free(UHCIState *s, UHCIAsync *async)
static void uhci_async_link(UHCIState *s, UHCIAsync *async) static void uhci_async_link(UHCIState *s, UHCIAsync *async)
{ {
async->next = s->async_pending; QTAILQ_INSERT_HEAD(&s->async_pending, async, next);
s->async_pending = async;
} }
static void uhci_async_unlink(UHCIState *s, UHCIAsync *async) static void uhci_async_unlink(UHCIState *s, UHCIAsync *async)
{ {
UHCIAsync *curr = s->async_pending; QTAILQ_REMOVE(&s->async_pending, async, next);
UHCIAsync **prev = &s->async_pending;
while (curr) {
if (curr == async) {
*prev = curr->next;
return;
}
prev = &curr->next;
curr = curr->next;
}
} }
static void uhci_async_cancel(UHCIState *s, UHCIAsync *async) static void uhci_async_cancel(UHCIState *s, UHCIAsync *async)
@ -220,11 +206,10 @@ static void uhci_async_cancel(UHCIState *s, UHCIAsync *async)
*/ */
static UHCIAsync *uhci_async_validate_begin(UHCIState *s) static UHCIAsync *uhci_async_validate_begin(UHCIState *s)
{ {
UHCIAsync *async = s->async_pending; UHCIAsync *async;
while (async) { QTAILQ_FOREACH(async, &s->async_pending, next) {
async->valid--; async->valid--;
async = async->next;
} }
return NULL; return NULL;
} }
@ -234,47 +219,30 @@ static UHCIAsync *uhci_async_validate_begin(UHCIState *s)
*/ */
static void uhci_async_validate_end(UHCIState *s) static void uhci_async_validate_end(UHCIState *s)
{ {
UHCIAsync *curr = s->async_pending; UHCIAsync *curr, *n;
UHCIAsync **prev = &s->async_pending;
UHCIAsync *next;
while (curr) { QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
if (curr->valid > 0) { if (curr->valid > 0) {
prev = &curr->next;
curr = curr->next;
continue; continue;
} }
uhci_async_unlink(s, curr);
next = curr->next;
/* Unlink */
*prev = next;
uhci_async_cancel(s, curr); uhci_async_cancel(s, curr);
curr = next;
} }
} }
static void uhci_async_cancel_all(UHCIState *s) static void uhci_async_cancel_all(UHCIState *s)
{ {
UHCIAsync *curr = s->async_pending; UHCIAsync *curr, *n;
UHCIAsync *next;
while (curr) {
next = curr->next;
QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
uhci_async_unlink(s, curr);
uhci_async_cancel(s, curr); uhci_async_cancel(s, curr);
curr = next;
} }
s->async_pending = NULL;
} }
static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token) static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token)
{ {
UHCIAsync *async = s->async_pending; UHCIAsync *async;
UHCIAsync *match = NULL; UHCIAsync *match = NULL;
int count = 0; int count = 0;
@ -291,7 +259,7 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token
* If we ever do we'd want to optimize this algorithm. * If we ever do we'd want to optimize this algorithm.
*/ */
while (async) { QTAILQ_FOREACH(async, &s->async_pending, next) {
if (async->token == token) { if (async->token == token) {
/* Good match */ /* Good match */
match = async; match = async;
@ -301,8 +269,6 @@ static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token
break; break;
} }
} }
async = async->next;
count++; count++;
} }
@ -1137,6 +1103,7 @@ static int usb_uhci_common_initfn(UHCIState *s)
s->expire_time = qemu_get_clock_ns(vm_clock) + s->expire_time = qemu_get_clock_ns(vm_clock) +
(get_ticks_per_sec() / FRAME_TIMER_FREQ); (get_ticks_per_sec() / FRAME_TIMER_FREQ);
s->num_ports_vmstate = NB_PORTS; s->num_ports_vmstate = NB_PORTS;
QTAILQ_INIT(&s->async_pending);
qemu_register_reset(uhci_reset, s); qemu_register_reset(uhci_reset, s);