libpayload: Remove bitfield use from UHCI data structures
We agreed that bitfields are a Bad Idea[tm]. Change-Id: I1b2bcda28c52ad10bbe9429e04d126b555f7828a Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com> Reviewed-on: http://review.coreboot.org/478 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-by: Peter Stuge <peter@stuge.se>
This commit is contained in:
parent
c4348d0a44
commit
b0b4a52b70
|
@ -66,7 +66,7 @@ td_dump (td_t *td)
|
|||
{
|
||||
char td_value[3];
|
||||
const char *td_type;
|
||||
switch (td->pid) {
|
||||
switch (td->token & TD_PID_MASK) {
|
||||
case UHCI_SETUP:
|
||||
td_type="SETUP";
|
||||
break;
|
||||
|
@ -77,23 +77,24 @@ td_dump (td_t *td)
|
|||
td_type="OUT";
|
||||
break;
|
||||
default:
|
||||
sprintf(td_value, "%x", td->pid);
|
||||
sprintf(td_value, "%x", td->token & TD_PID_MASK);
|
||||
td_type=td_value;
|
||||
}
|
||||
debug ("%s packet (at %lx) to %x.%x failed\n", td_type,
|
||||
virt_to_phys (td), td->dev_addr, td->endp);
|
||||
debug ("td (counter at %x) returns: ", td->counter);
|
||||
debug (" bitstuff err: %x, ", td->status_bitstuff_err);
|
||||
debug (" CRC err: %x, ", td->status_crc_err);
|
||||
debug (" NAK rcvd: %x, ", td->status_nakrcvd);
|
||||
debug (" Babble: %x, ", td->status_babble);
|
||||
debug (" Data Buffer err: %x, ", td->status_databuf_err);
|
||||
debug (" Stalled: %x, ", td->status_stalled);
|
||||
debug (" Active: %x\n", td->status_active);
|
||||
if (td->status_babble)
|
||||
virt_to_phys (td), (td->token & TD_DEVADDR_MASK) >> TD_DEVADDR_SHIFT,
|
||||
(td->token & TD_EP_MASK) >> TD_EP_SHIFT);
|
||||
debug ("td (counter at %x) returns: ", td->ctrlsts >> TD_COUNTER_SHIFT);
|
||||
debug (" bitstuff err: %x, ", !!(td->ctrlsts & TD_STATUS_BITSTUFF_ERR));
|
||||
debug (" CRC err: %x, ", !!(td->ctrlsts & TD_STATUS_CRC_ERR));
|
||||
debug (" NAK rcvd: %x, ", !!(td->ctrlsts & TD_STATUS_NAK_RCVD));
|
||||
debug (" Babble: %x, ", !!(td->ctrlsts & TD_STATUS_BABBLE));
|
||||
debug (" Data Buffer err: %x, ", !!(td->ctrlsts & TD_STATUS_DATABUF_ERR));
|
||||
debug (" Stalled: %x, ", !!(td->ctrlsts & TD_STATUS_STALLED));
|
||||
debug (" Active: %x\n", !!(td->ctrlsts & TD_STATUS_ACTIVE));
|
||||
if (td->ctrlsts & TD_STATUS_BABBLE)
|
||||
debug (" Babble because of %s\n",
|
||||
td->status_bitstuff_err ? "host" : "device");
|
||||
if (td->status_active)
|
||||
(td->ctrlsts & TD_STATUS_BITSTUFF_ERR) ? "host" : "device");
|
||||
if (td->ctrlsts & TD_STATUS_ACTIVE)
|
||||
debug (" still active - timeout?\n");
|
||||
}
|
||||
|
||||
|
@ -197,34 +198,24 @@ uhci_init (pcidev_t addr)
|
|||
! UHCI_INST (controller)->qh_last)
|
||||
fatal("Not enough memory for USB controller queues.\n");
|
||||
|
||||
UHCI_INST (controller)->qh_prei->headlinkptr.ptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_intr);
|
||||
UHCI_INST (controller)->qh_prei->headlinkptr.queue_head = 1;
|
||||
UHCI_INST (controller)->qh_prei->elementlinkptr.ptr = 0;
|
||||
UHCI_INST (controller)->qh_prei->elementlinkptr.terminate = 1;
|
||||
UHCI_INST (controller)->qh_prei->headlinkptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_intr) | FLISTP_QH;
|
||||
UHCI_INST (controller)->qh_prei->elementlinkptr = 0 | FLISTP_TERMINATE;
|
||||
|
||||
UHCI_INST (controller)->qh_intr->headlinkptr.ptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_data);
|
||||
UHCI_INST (controller)->qh_intr->headlinkptr.queue_head = 1;
|
||||
UHCI_INST (controller)->qh_intr->elementlinkptr.ptr = 0;
|
||||
UHCI_INST (controller)->qh_intr->elementlinkptr.terminate = 1;
|
||||
UHCI_INST (controller)->qh_intr->headlinkptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_QH;
|
||||
UHCI_INST (controller)->qh_intr->elementlinkptr = 0 | FLISTP_TERMINATE;
|
||||
|
||||
UHCI_INST (controller)->qh_data->headlinkptr.ptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_last);
|
||||
UHCI_INST (controller)->qh_data->headlinkptr.queue_head = 1;
|
||||
UHCI_INST (controller)->qh_data->elementlinkptr.ptr = 0;
|
||||
UHCI_INST (controller)->qh_data->elementlinkptr.terminate = 1;
|
||||
UHCI_INST (controller)->qh_data->headlinkptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_last) | FLISTP_QH;
|
||||
UHCI_INST (controller)->qh_data->elementlinkptr = 0 | FLISTP_TERMINATE;
|
||||
|
||||
UHCI_INST (controller)->qh_last->headlinkptr.ptr = virt_to_phys (UHCI_INST (controller)->qh_data);
|
||||
UHCI_INST (controller)->qh_last->headlinkptr.terminate = 1;
|
||||
UHCI_INST (controller)->qh_last->elementlinkptr.ptr = virt_to_phys (antiberserk);
|
||||
UHCI_INST (controller)->qh_last->elementlinkptr.terminate = 1;
|
||||
UHCI_INST (controller)->qh_last->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_TERMINATE;
|
||||
UHCI_INST (controller)->qh_last->elementlinkptr = virt_to_phys (antiberserk) | FLISTP_TERMINATE;
|
||||
|
||||
for (i = 0; i < 1024; i++) {
|
||||
UHCI_INST (controller)->framelistptr[i].ptr =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_prei);
|
||||
UHCI_INST (controller)->framelistptr[i].terminate = 0;
|
||||
UHCI_INST (controller)->framelistptr[i].queue_head = 1;
|
||||
UHCI_INST (controller)->framelistptr[i] =
|
||||
virt_to_phys (UHCI_INST (controller)->qh_prei) | FLISTP_QH;
|
||||
}
|
||||
controller->devices[0]->controller = controller;
|
||||
controller->devices[0]->init = uhci_rh_init;
|
||||
|
@ -272,18 +263,18 @@ static td_t *
|
|||
wait_for_completed_qh (hci_t *controller, qh_t *qh)
|
||||
{
|
||||
int timeout = 1000000; /* max 30 ms. */
|
||||
void *current = GET_TD (qh->elementlinkptr.ptr);
|
||||
while ((qh->elementlinkptr.terminate == 0) && (timeout-- > 0)) {
|
||||
if (current != GET_TD (qh->elementlinkptr.ptr)) {
|
||||
current = GET_TD (qh->elementlinkptr.ptr);
|
||||
void *current = GET_TD (qh->elementlinkptr);
|
||||
while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) {
|
||||
if (current != GET_TD (qh->elementlinkptr)) {
|
||||
current = GET_TD (qh->elementlinkptr);
|
||||
timeout = 1000000;
|
||||
}
|
||||
uhci_reg_write16(controller, USBSTS,
|
||||
uhci_reg_read16(controller, USBSTS) | 0); // clear resettable registers
|
||||
udelay (30);
|
||||
}
|
||||
return (GET_TD (qh->elementlinkptr.ptr) ==
|
||||
0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr.ptr));
|
||||
return (GET_TD (qh->elementlinkptr) ==
|
||||
0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -314,57 +305,51 @@ uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen
|
|||
memset (tds, 0, sizeof (td_t) * count);
|
||||
count--; /* to compensate for 0-indexed array */
|
||||
for (i = 0; i < count; i++) {
|
||||
tds[i].ptr = virt_to_phys (&tds[i + 1]);
|
||||
tds[i].depth_first = 1;
|
||||
tds[i].terminate = 0;
|
||||
tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
|
||||
}
|
||||
tds[count].ptr = 0;
|
||||
tds[count].depth_first = 1;
|
||||
tds[count].terminate = 1;
|
||||
tds[count].ptr = 0 | TD_DEPTH_FIRST | TD_TERMINATE;
|
||||
|
||||
tds[0].pid = UHCI_SETUP;
|
||||
tds[0].dev_addr = dev->address;
|
||||
tds[0].endp = endp;
|
||||
tds[0].maxlen = maxlen (drlen);
|
||||
tds[0].counter = 3;
|
||||
tds[0].data_toggle = 0;
|
||||
tds[0].lowspeed = dev->speed;
|
||||
tds[0].token = UHCI_SETUP |
|
||||
dev->address << TD_DEVADDR_SHIFT |
|
||||
endp << TD_EP_SHIFT |
|
||||
TD_TOGGLE_DATA0 |
|
||||
maxlen(drlen) << TD_MAXLEN_SHIFT;
|
||||
tds[0].bufptr = virt_to_phys (devreq);
|
||||
tds[0].status_active = 1;
|
||||
tds[0].ctrlsts = (3 << TD_COUNTER_SHIFT) |
|
||||
(dev->speed?TD_LOWSPEED:0) |
|
||||
TD_STATUS_ACTIVE;
|
||||
|
||||
int toggle = 1;
|
||||
for (i = 1; i < count; i++) {
|
||||
switch (dir) {
|
||||
case SETUP: tds[i].pid = UHCI_SETUP; break;
|
||||
case IN: tds[i].pid = UHCI_IN; break;
|
||||
case OUT: tds[i].pid = UHCI_OUT; break;
|
||||
case SETUP: tds[i].token = UHCI_SETUP; break;
|
||||
case IN: tds[i].token = UHCI_IN; break;
|
||||
case OUT: tds[i].token = UHCI_OUT; break;
|
||||
}
|
||||
tds[i].dev_addr = dev->address;
|
||||
tds[i].endp = endp;
|
||||
tds[i].maxlen = maxlen (min (mlen, dalen));
|
||||
tds[i].counter = 3;
|
||||
tds[i].data_toggle = toggle;
|
||||
tds[i].lowspeed = dev->speed;
|
||||
tds[i].token |= dev->address << TD_DEVADDR_SHIFT |
|
||||
endp << TD_EP_SHIFT |
|
||||
maxlen (min (mlen, dalen)) << TD_MAXLEN_SHIFT |
|
||||
toggle << TD_TOGGLE_SHIFT;
|
||||
tds[i].bufptr = virt_to_phys (data);
|
||||
tds[i].status_active = 1;
|
||||
tds[i].ctrlsts = (3 << TD_COUNTER_SHIFT) |
|
||||
(dev->speed?TD_LOWSPEED:0) |
|
||||
TD_STATUS_ACTIVE;
|
||||
toggle ^= 1;
|
||||
dalen -= mlen;
|
||||
data += mlen;
|
||||
}
|
||||
|
||||
tds[count].pid = (dir == OUT) ? UHCI_IN : UHCI_OUT;
|
||||
tds[count].dev_addr = dev->address;
|
||||
tds[count].endp = endp;
|
||||
tds[count].maxlen = maxlen (0);
|
||||
tds[count].counter = 0; /* as per linux 2.4.10 */
|
||||
tds[count].data_toggle = 1;
|
||||
tds[count].lowspeed = dev->speed;
|
||||
tds[count].token = (dir == OUT) ? UHCI_IN : UHCI_OUT |
|
||||
dev->address << TD_DEVADDR_SHIFT |
|
||||
endp << TD_EP_SHIFT |
|
||||
maxlen(0) << TD_MAXLEN_SHIFT |
|
||||
TD_TOGGLE_DATA1;
|
||||
tds[count].bufptr = 0;
|
||||
tds[count].status_active = 1;
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
|
||||
virt_to_phys (tds);
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
|
||||
tds[0].ctrlsts = (0 << TD_COUNTER_SHIFT) | /* as Linux 2.4.10 does */
|
||||
(dev->speed?TD_LOWSPEED:0) |
|
||||
TD_STATUS_ACTIVE;
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr =
|
||||
virt_to_phys (tds) & ~(FLISTP_QH | FLISTP_TERMINATE);
|
||||
td_t *td = wait_for_completed_qh (dev->controller,
|
||||
UHCI_INST (dev->controller)->
|
||||
qh_data);
|
||||
|
@ -389,15 +374,9 @@ create_schedule (int numpackets)
|
|||
memset (tds, 0, sizeof (td_t) * numpackets);
|
||||
int i;
|
||||
for (i = 0; i < numpackets; i++) {
|
||||
tds[i].ptr = virt_to_phys (&tds[i + 1]);
|
||||
tds[i].terminate = 0;
|
||||
tds[i].queue_head = 0;
|
||||
tds[i].depth_first = 1;
|
||||
tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
|
||||
}
|
||||
tds[numpackets - 1].ptr = 0;
|
||||
tds[numpackets - 1].terminate = 1;
|
||||
tds[numpackets - 1].queue_head = 0;
|
||||
tds[numpackets - 1].depth_first = 0;
|
||||
tds[numpackets - 1].ptr = 0 | TD_TERMINATE;
|
||||
return tds;
|
||||
}
|
||||
|
||||
|
@ -406,32 +385,26 @@ fill_schedule (td_t *td, endpoint_t *ep, int length, unsigned char *data,
|
|||
int *toggle)
|
||||
{
|
||||
switch (ep->direction) {
|
||||
case IN: td->pid = UHCI_IN; break;
|
||||
case OUT: td->pid = UHCI_OUT; break;
|
||||
case SETUP: td->pid = UHCI_SETUP; break;
|
||||
case IN: td->token = UHCI_IN; break;
|
||||
case OUT: td->token = UHCI_OUT; break;
|
||||
case SETUP: td->token = UHCI_SETUP; break;
|
||||
}
|
||||
td->dev_addr = ep->dev->address;
|
||||
td->endp = ep->endpoint & 0xf;
|
||||
td->maxlen = maxlen (length);
|
||||
if (ep->direction == SETUP)
|
||||
td->counter = 3;
|
||||
else
|
||||
td->counter = 0;
|
||||
td->data_toggle = *toggle & 1;
|
||||
td->lowspeed = ep->dev->speed;
|
||||
td->token |= ep->dev->address << TD_DEVADDR_SHIFT |
|
||||
(ep->endpoint & 0xf) << TD_EP_SHIFT |
|
||||
maxlen (length) << TD_MAXLEN_SHIFT |
|
||||
(*toggle & 1) << TD_TOGGLE_SHIFT;
|
||||
td->bufptr = virt_to_phys (data);
|
||||
|
||||
td->status_active = 1;
|
||||
td->ctrlsts = ((ep->direction == SETUP?3:0) << TD_COUNTER_SHIFT) |
|
||||
ep->dev->speed?TD_LOWSPEED:0 |
|
||||
TD_STATUS_ACTIVE;
|
||||
*toggle ^= 1;
|
||||
}
|
||||
|
||||
static int
|
||||
run_schedule (usbdev_t *dev, td_t *td)
|
||||
{
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
|
||||
virt_to_phys (td);
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
|
||||
UHCI_INST (dev->controller)->qh_data->elementlinkptr =
|
||||
virt_to_phys (td) | ~(FLISTP_QH | FLISTP_TERMINATE);
|
||||
td = wait_for_completed_qh (dev->controller,
|
||||
UHCI_INST (dev->controller)->qh_data);
|
||||
if (td == 0) {
|
||||
|
@ -493,9 +466,7 @@ uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming
|
|||
if (!data || !tds || !qh)
|
||||
fatal("Not enough memory to create USB intr queue prerequisites.\n");
|
||||
|
||||
qh->elementlinkptr.ptr = virt_to_phys(tds);
|
||||
qh->elementlinkptr.queue_head = 0;
|
||||
qh->elementlinkptr.terminate = 0;
|
||||
qh->elementlinkptr = virt_to_phys(tds);
|
||||
|
||||
intr_q *q = malloc(sizeof(intr_q));
|
||||
if (!q)
|
||||
|
@ -512,37 +483,28 @@ uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming
|
|||
int i;
|
||||
for (i = 0; i < reqcount; i++) {
|
||||
tds[i].ptr = virt_to_phys (&tds[i + 1]);
|
||||
tds[i].terminate = 0;
|
||||
tds[i].queue_head = 0;
|
||||
tds[i].depth_first = 0;
|
||||
|
||||
switch (ep->direction) {
|
||||
case IN: tds[i].pid = UHCI_IN; break;
|
||||
case OUT: tds[i].pid = UHCI_OUT; break;
|
||||
case SETUP: tds[i].pid = UHCI_SETUP; break;
|
||||
case IN: tds[i].token = UHCI_IN; break;
|
||||
case OUT: tds[i].token = UHCI_OUT; break;
|
||||
case SETUP: tds[i].token = UHCI_SETUP; break;
|
||||
}
|
||||
tds[i].dev_addr = ep->dev->address;
|
||||
tds[i].endp = ep->endpoint & 0xf;
|
||||
tds[i].maxlen = maxlen (reqsize);
|
||||
tds[i].counter = 0;
|
||||
tds[i].data_toggle = ep->toggle & 1;
|
||||
tds[i].lowspeed = ep->dev->speed;
|
||||
tds[i].token |= ep->dev->address << TD_DEVADDR_SHIFT |
|
||||
(ep->endpoint & 0xf) << TD_EP_SHIFT |
|
||||
maxlen (reqsize) << TD_MAXLEN_SHIFT |
|
||||
(ep->toggle & 1) << TD_TOGGLE_SHIFT;
|
||||
tds[i].bufptr = virt_to_phys (data);
|
||||
tds[i].status_active = 1;
|
||||
tds[i].ctrlsts = (0 << TD_COUNTER_SHIFT) |
|
||||
ep->dev->speed?TD_LOWSPEED:0 |
|
||||
TD_STATUS_ACTIVE;
|
||||
ep->toggle ^= 1;
|
||||
data += reqsize;
|
||||
}
|
||||
tds[reqcount - 1].ptr = 0;
|
||||
tds[reqcount - 1].terminate = 1;
|
||||
tds[reqcount - 1].queue_head = 0;
|
||||
tds[reqcount - 1].depth_first = 0;
|
||||
tds[reqcount - 1].ptr = 0 | TD_TERMINATE;
|
||||
for (i = reqtiming; i < 1024; i += reqtiming) {
|
||||
/* FIXME: wrap in another qh, one for each occurance of the qh in the framelist */
|
||||
qh->headlinkptr.ptr = UHCI_INST (ep->dev->controller)->framelistptr[i].ptr;
|
||||
qh->headlinkptr.terminate = 0;
|
||||
UHCI_INST (ep->dev->controller)->framelistptr[i].ptr = virt_to_phys(qh);
|
||||
UHCI_INST (ep->dev->controller)->framelistptr[i].terminate = 0;
|
||||
UHCI_INST (ep->dev->controller)->framelistptr[i].queue_head = 1;
|
||||
qh->headlinkptr = UHCI_INST (ep->dev->controller)->framelistptr[i] & ~FLISTP_TERMINATE;
|
||||
UHCI_INST (ep->dev->controller)->framelistptr[i] = virt_to_phys(qh) | FLISTP_QH;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
@ -557,15 +519,15 @@ uhci_destroy_intr_queue (endpoint_t *ep, void *q_)
|
|||
int i;
|
||||
for (i=0; i<1024; i++) {
|
||||
u32 oldptr = 0;
|
||||
u32 ptr = UHCI_INST (ep->dev->controller)->framelistptr[i].ptr;
|
||||
u32 ptr = UHCI_INST (ep->dev->controller)->framelistptr[i];
|
||||
while (ptr != end) {
|
||||
if (((qh_t*)phys_to_virt(ptr))->elementlinkptr.ptr == val) {
|
||||
((qh_t*)phys_to_virt(oldptr))->headlinkptr.ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr.ptr;
|
||||
if (((qh_t*)phys_to_virt(ptr))->elementlinkptr == val) {
|
||||
((qh_t*)phys_to_virt(oldptr))->headlinkptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr;
|
||||
free(phys_to_virt(ptr));
|
||||
break;
|
||||
}
|
||||
oldptr = ptr;
|
||||
ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr.ptr;
|
||||
ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr;
|
||||
}
|
||||
}
|
||||
free(q->data);
|
||||
|
@ -582,7 +544,7 @@ static u8*
|
|||
uhci_poll_intr_queue (void *q_)
|
||||
{
|
||||
intr_q *q = (intr_q*)q_;
|
||||
if (q->tds[q->lastread].status_active == 0) {
|
||||
if ((q->tds[q->lastread].ctrlsts & TD_STATUS_ACTIVE) == 0) {
|
||||
/* FIXME: handle errors */
|
||||
int current = q->lastread;
|
||||
int previous;
|
||||
|
@ -591,15 +553,13 @@ uhci_poll_intr_queue (void *q_)
|
|||
} else {
|
||||
previous = q->lastread - 1;
|
||||
}
|
||||
q->tds[previous].status = 0;
|
||||
q->tds[previous].ptr = 0;
|
||||
q->tds[previous].terminate = 1;
|
||||
q->tds[previous].ctrlsts &= ~TD_STATUS_MASK;
|
||||
q->tds[previous].ptr = 0 | TD_TERMINATE;
|
||||
if (q->last_td != &q->tds[previous]) {
|
||||
q->last_td->ptr = virt_to_phys(&q->tds[previous]);
|
||||
q->last_td->terminate = 0;
|
||||
q->last_td->ptr = virt_to_phys(&q->tds[previous]) & ~TD_TERMINATE;
|
||||
q->last_td = &q->tds[previous];
|
||||
}
|
||||
q->tds[previous].status_active = 1;
|
||||
q->tds[previous].ctrlsts |= TD_STATUS_ACTIVE;
|
||||
q->lastread = (q->lastread + 1) % q->total;
|
||||
return &q->data[current*q->reqsize];
|
||||
}
|
||||
|
|
|
@ -32,55 +32,38 @@
|
|||
|
||||
typedef enum { UHCI_SETUP = 0x2d, UHCI_IN = 0x69, UHCI_OUT = 0xe1 } uhci_pid_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
unsigned long terminate:1;
|
||||
unsigned long queue_head:1;
|
||||
unsigned long:2;
|
||||
unsigned long ptr_part:28;
|
||||
};
|
||||
u32 ptr;
|
||||
} __attribute__ ((packed)) flistp_t;
|
||||
typedef u32 flistp_t;
|
||||
#define FLISTP_TERMINATE 1
|
||||
#define FLISTP_QH 2
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned long terminate:1;
|
||||
unsigned long queue_head:1;
|
||||
unsigned long depth_first:1;
|
||||
unsigned long:29;
|
||||
} __attribute__ ((packed));
|
||||
u32 ptr;
|
||||
} __attribute__ ((packed));
|
||||
u32 ptr;
|
||||
#define TD_TERMINATE 1
|
||||
#define TD_QH 2
|
||||
#define TD_DEPTH_FIRST 4
|
||||
|
||||
volatile unsigned long actlen:11;
|
||||
volatile unsigned long:5;
|
||||
union {
|
||||
struct {
|
||||
unsigned long:1; // bit 0
|
||||
unsigned long status_bitstuff_err:1;
|
||||
unsigned long status_crc_err:1;
|
||||
unsigned long status_nakrcvd:1;
|
||||
unsigned long status_babble:1;
|
||||
unsigned long status_databuf_err:1;
|
||||
unsigned long status_stalled:1;
|
||||
unsigned long status_active:1; // bit 7
|
||||
} __attribute__ ((packed));
|
||||
unsigned char status;
|
||||
} __attribute__ ((packed));
|
||||
volatile unsigned long ioc:1; /* interrupt on complete */
|
||||
volatile unsigned long isochronous:1;
|
||||
volatile unsigned long lowspeed:1;
|
||||
volatile unsigned long counter:2;
|
||||
volatile unsigned long shortpck:1;
|
||||
volatile unsigned long:2;
|
||||
u32 ctrlsts;
|
||||
#define TD_STATUS_MASK (0xff << 16)
|
||||
#define TD_STATUS_BITSTUFF_ERR (1 << 17)
|
||||
#define TD_STATUS_CRC_ERR (1 << 18)
|
||||
#define TD_STATUS_NAK_RCVD (1 << 19)
|
||||
#define TD_STATUS_BABBLE (1 << 20)
|
||||
#define TD_STATUS_DATABUF_ERR (1 << 21)
|
||||
#define TD_STATUS_STALLED (1 << 22)
|
||||
#define TD_STATUS_ACTIVE (1 << 23)
|
||||
#define TD_LOWSPEED (1 << 26)
|
||||
#define TD_COUNTER_SHIFT 27
|
||||
|
||||
unsigned long pid:8;
|
||||
unsigned long dev_addr:7;
|
||||
unsigned long endp:4;
|
||||
unsigned long data_toggle:1;
|
||||
unsigned long:1;
|
||||
unsigned long maxlen:11;
|
||||
u32 token;
|
||||
#define TD_PID_MASK 0xff
|
||||
#define TD_DEVADDR_SHIFT 8
|
||||
#define TD_DEVADDR_MASK (((1<<7)-1) << TD_DEVADDR_SHIFT)
|
||||
#define TD_EP_SHIFT 15
|
||||
#define TD_EP_MASK (0xf << TD_EP_SHIFT)
|
||||
#define TD_TOGGLE_SHIFT 19
|
||||
#define TD_MAXLEN_SHIFT 21
|
||||
#define TD_TOGGLE_DATA0 0
|
||||
#define TD_TOGGLE_DATA1 (1 << TD_TOGGLE_SHIFT)
|
||||
|
||||
u32 bufptr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue