libpayload: Remove bitfield use from OHCI data structures

We agreed that bitfields are a Bad Idea[tm].

Change-Id: Ic04f151091c359912835b8b3db488d2d41bd4bbb
Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Reviewed-on: http://review.coreboot.org/479
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:
Patrick Georgi 2011-11-24 09:12:11 +01:00 committed by Peter Stuge
parent ad6331d25f
commit c4348d0a44
2 changed files with 65 additions and 80 deletions

View File

@ -188,7 +188,8 @@ dump_td(td_t *cur, int level)
#ifdef USB_DEBUG #ifdef USB_DEBUG
static const char *spaces=" "; static const char *spaces=" ";
const char *spc=spaces+(10-level); const char *spc=spaces+(10-level);
debug("%std at %x (%s), condition code: %s\n", spc, cur, direction[cur->direction], completion_codes[cur->condition_code & 0xf]); debug("%std at %x (%s), condition code: %s\n", spc, cur, direction[(cur->config & TD_DIRECTION_MASK) >> TD_DIRECTION_SHIFT],
completion_codes[(cur->config & TD_CC_MASK) >> TD_CC_SHIFT]);
debug("%s toggle: %x\n", spc, cur->toggle); debug("%s toggle: %x\n", spc, cur->toggle);
#endif #endif
} }
@ -201,7 +202,7 @@ wait_for_ed(usbdev_t *dev, ed_t *head)
/* wait for results */ /* wait for results */
while (((head->head_pointer & ~3) != head->tail_pointer) && while (((head->head_pointer & ~3) != head->tail_pointer) &&
!(head->head_pointer & 1) && !(head->head_pointer & 1) &&
((((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code & 0xf)>=0xe)) { ((((td_t*)phys_to_virt(head->head_pointer & ~3))->config & TD_CC_MASK) >= TD_CC_NOACCESS)) {
debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n", debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n",
OHCI_INST(dev->controller)->opreg->HcInterruptStatus, OHCI_INST(dev->controller)->opreg->HcInterruptStatus,
OHCI_INST(dev->controller)->opreg->HcControl, OHCI_INST(dev->controller)->opreg->HcControl,
@ -209,7 +210,7 @@ wait_for_ed(usbdev_t *dev, ed_t *head)
head->head_pointer, head->head_pointer,
((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td, ((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td,
head->tail_pointer, head->tail_pointer,
((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code); (((td_t*)phys_to_virt(head->head_pointer & ~3))->config & TD_CC_MASK) >> TD_CC_SHIFT);
mdelay(1); mdelay(1);
} }
mdelay(5); mdelay(5);
@ -266,12 +267,11 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen
} }
tds[td_count + 3].next_td = 0; tds[td_count + 3].next_td = 0;
tds[0].direction = OHCI_SETUP; tds[0].config = TD_DIRECTION_SETUP |
tds[0].toggle_from_td = 1; TD_DELAY_INTERRUPT_NODELAY |
tds[0].toggle = 0; TD_TOGGLE_FROM_TD |
tds[0].error_count = 0; TD_TOGGLE_DATA0 |
tds[0].delay_interrupt = 7; TD_CC_NOACCESS;
tds[0].condition_code = 0xf;
tds[0].current_buffer_pointer = virt_to_phys(devreq); tds[0].current_buffer_pointer = virt_to_phys(devreq);
tds[0].buffer_end = virt_to_phys(devreq + drlen - 1); tds[0].buffer_end = virt_to_phys(devreq + drlen - 1);
@ -279,12 +279,10 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen
while (pages > 0) { while (pages > 0) {
cur++; cur++;
cur->direction = (dir==IN)?OHCI_IN:OHCI_OUT; cur->config = (dir==IN)?TD_DIRECTION_IN:TD_DIRECTION_OUT |
cur->toggle_from_td = 0; TD_DELAY_INTERRUPT_NODELAY |
cur->toggle = 1; TD_TOGGLE_FROM_ED |
cur->error_count = 0; TD_CC_NOACCESS;
cur->delay_interrupt = 7;
cur->condition_code = 0xf;
cur->current_buffer_pointer = virt_to_phys(data); cur->current_buffer_pointer = virt_to_phys(data);
pages--; pages--;
int consumed = (4096 - ((unsigned long)data % 4096)); int consumed = (4096 - ((unsigned long)data % 4096));
@ -308,12 +306,11 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen
} }
cur++; cur++;
cur->direction = (dir==IN)?OHCI_OUT:OHCI_IN; cur->config = (dir==IN)?TD_DIRECTION_OUT:TD_DIRECTION_IN |
cur->toggle_from_td = 1; TD_DELAY_INTERRUPT_NODELAY |
cur->toggle = 1; TD_TOGGLE_FROM_TD |
cur->error_count = 0; TD_TOGGLE_DATA1 |
cur->delay_interrupt = 7; TD_CC_NOACCESS;
cur->condition_code = 0xf;
cur->current_buffer_pointer = 0; cur->current_buffer_pointer = 0;
cur->buffer_end = 0; cur->buffer_end = 0;
@ -323,18 +320,15 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen
/* Data structures */ /* Data structures */
ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t)); ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
memset((void*)head, 0, sizeof(*head)); memset((void*)head, 0, sizeof(*head));
head->function_address = dev->address; head->config = (dev->address << ED_FUNC_SHIFT) |
head->endpoint_number = 0; (0 << ED_EP_SHIFT) |
head->direction = OHCI_FROM_TD; (OHCI_FROM_TD << ED_DIR_SHIFT) |
head->lowspeed = dev->speed; (dev->speed?ED_LOWSPEED:0) |
head->format = 0; (dev->endpoints[0].maxpacketsize << ED_MPS_SHIFT);
head->maximum_packet_size = dev->endpoints[0].maxpacketsize;
head->tail_pointer = virt_to_phys(cur); head->tail_pointer = virt_to_phys(cur);
head->head_pointer = virt_to_phys(tds); head->head_pointer = virt_to_phys(tds);
head->halted = 0;
head->toggle = 0;
debug("doing control transfer with %x. first_td at %x\n", head->function_address, virt_to_phys(tds)); debug("doing control transfer with %x. first_td at %x\n", head->config & ED_FUNC_MASK, virt_to_phys(tds));
/* activate schedule */ /* activate schedule */
OHCI_INST(dev->controller)->opreg->HcControlHeadED = virt_to_phys(head); OHCI_INST(dev->controller)->opreg->HcControlHeadED = virt_to_phys(head);
@ -379,11 +373,10 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize)
} }
for (cur = tds; cur->next_td != 0; cur++) { for (cur = tds; cur->next_td != 0; cur++) {
cur->toggle_from_td = 0; cur->config = (ep->direction==IN)?TD_DIRECTION_IN:TD_DIRECTION_OUT |
cur->error_count = 0; TD_DELAY_INTERRUPT_NODELAY |
cur->delay_interrupt = 7; TD_TOGGLE_FROM_ED |
cur->condition_code = 0xf; TD_CC_NOACCESS;
cur->direction = (ep->direction==IN)?OHCI_IN:OHCI_OUT;
cur->current_buffer_pointer = virt_to_phys(data); cur->current_buffer_pointer = virt_to_phys(data);
pages--; pages--;
if (dalen == 0) { if (dalen == 0) {
@ -415,18 +408,16 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize)
/* Data structures */ /* Data structures */
ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t)); ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
memset((void*)head, 0, sizeof(*head)); memset((void*)head, 0, sizeof(*head));
head->function_address = ep->dev->address; head->config = (ep->dev->address << ED_FUNC_SHIFT) |
head->endpoint_number = ep->endpoint & 0xf; ((ep->endpoint & 0xf) << ED_EP_SHIFT) |
head->direction = (ep->direction==IN)?OHCI_IN:OHCI_OUT; (((ep->direction==IN)?OHCI_IN:OHCI_OUT) << ED_DIR_SHIFT) |
head->lowspeed = ep->dev->speed; (ep->dev->speed?ED_LOWSPEED:0) |
head->format = 0; (ep->maxpacketsize << ED_MPS_SHIFT);
head->maximum_packet_size = ep->maxpacketsize;
head->tail_pointer = virt_to_phys(cur); head->tail_pointer = virt_to_phys(cur);
head->head_pointer = virt_to_phys(tds); head->head_pointer = virt_to_phys(tds) | (ep->toggle?ED_TOGGLE:0);
head->halted = 0;
head->toggle = ep->toggle;
debug("doing bulk transfer with %x(%x). first_td at %x, last %x\n", head->function_address, head->endpoint_number, virt_to_phys(tds), virt_to_phys(cur)); debug("doing bulk transfer with %x(%x). first_td at %x, last %x\n", head->config & ED_FUNC_MASK,
(head->config & ED_EP_MASK) >> ED_EP_SHIFT, virt_to_phys(tds), virt_to_phys(cur));
/* activate schedule */ /* activate schedule */
OHCI_INST(ep->dev->controller)->opreg->HcBulkHeadED = virt_to_phys(head); OHCI_INST(ep->dev->controller)->opreg->HcBulkHeadED = virt_to_phys(head);
@ -436,7 +427,7 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize)
int failure = wait_for_ed(ep->dev, head); int failure = wait_for_ed(ep->dev, head);
OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable; OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable;
ep->toggle = head->toggle; ep->toggle = head->head_pointer & ED_TOGGLE;
/* free memory */ /* free memory */
free((void*)tds); free((void*)tds);

View File

@ -206,49 +206,43 @@
typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t; typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t;
typedef volatile struct { typedef volatile struct {
union { u32 config;
u32 dword0;
struct {
unsigned long function_address:7;
unsigned long endpoint_number:4;
unsigned long direction:2;
unsigned long lowspeed:1;
unsigned long skip:1;
unsigned long format:1;
unsigned long maximum_packet_size:11;
unsigned long:5;
} __attribute__ ((packed));
};
u32 tail_pointer; u32 tail_pointer;
union { u32 head_pointer;
u32 head_pointer;
struct {
unsigned long halted:1;
unsigned long toggle:1;
unsigned long:30;
} __attribute__ ((packed));
};
u32 next_ed; u32 next_ed;
} __attribute__ ((packed)) ed_t; } __attribute__ ((packed)) ed_t;
#define ED_HALTED 1
#define ED_TOGGLE 2
#define ED_FUNC_SHIFT 0
#define ED_FUNC_MASK MASK(7, 0)
#define ED_EP_SHIFT 7
#define ED_EP_MASK MASK(4, 7)
#define ED_DIR_SHIFT 11
#define ED_DIR_MASK MASK(2, 11)
#define ED_LOWSPEED (1 << 13)
#define ED_MPS_SHIFT 16
typedef volatile struct { typedef volatile struct {
union { u32 config;
u32 dword0;
struct {
unsigned long:18;
unsigned long buffer_rounding:1;
unsigned long direction:2;
unsigned long delay_interrupt:3;
unsigned long toggle:1;
unsigned long toggle_from_td:1;
unsigned long error_count:2;
unsigned long condition_code:4;
} __attribute__ ((packed));
};
u32 current_buffer_pointer; u32 current_buffer_pointer;
u32 next_td; u32 next_td;
u32 buffer_end; u32 buffer_end;
} __attribute__ ((packed)) td_t; } __attribute__ ((packed)) td_t;
#define TD_DIRECTION_SHIFT 19
#define TD_DIRECTION_MASK MASK(2, TD_DIRECTION_SHIFT)
#define TD_DIRECTION_SETUP OHCI_SETUP << TD_DIRECTION_SHIFT
#define TD_DIRECTION_IN OHCI_IN << TD_DIRECTION_SHIFT
#define TD_DIRECTION_OUT OHCI_OUT << TD_DIRECTION_SHIFT
#define TD_DELAY_INTERRUPT_NODELAY (7 << 21)
#define TD_TOGGLE_DATA0 0
#define TD_TOGGLE_DATA1 (1 << 24)
#define TD_TOGGLE_FROM_ED 0
#define TD_TOGGLE_FROM_TD (1 << 25)
#define TD_CC_SHIFT 28
#define TD_CC_MASK MASK(4, TD_CC_SHIFT)
#define TD_CC_NOERR 0
#define TD_CC_NOACCESS (14 << TD_CC_SHIFT) /* the lower of the two values, so "no access" can be tested with >= */
#define OHCI_INST(controller) ((ohci_t*)((controller)->instance)) #define OHCI_INST(controller) ((ohci_t*)((controller)->instance))