uhci: switch to QTAILQ
This commit is contained in:
parent
19f3322379
commit
ddf6583f88
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue