usb: ohci: Add proper cache flushing / invalidating for non cache coherent cpus
Add proper cache flushing / invalidating for non cache coherent cpus, for now only enable this for new (driver-model) usb code to avoid regressions. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
cae01cb2a9
commit
8d005ef81a
@ -103,6 +103,32 @@ static struct pci_device_id ehci_pci_ids[] = {
|
|||||||
# define m32_swap(x) cpu_to_le32(x)
|
# define m32_swap(x) cpu_to_le32(x)
|
||||||
#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */
|
#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */
|
||||||
|
|
||||||
|
#ifdef CONFIG_DM_USB
|
||||||
|
/*
|
||||||
|
* We really should do proper cache flushing everywhere, but for now we only
|
||||||
|
* do it for new (driver-model) usb code to avoid regressions.
|
||||||
|
*/
|
||||||
|
#define flush_dcache_buffer(addr, size) \
|
||||||
|
flush_dcache_range((unsigned long)(addr), \
|
||||||
|
ALIGN((unsigned long)(addr) + size, ARCH_DMA_MINALIGN))
|
||||||
|
#define invalidate_dcache_buffer(addr, size) \
|
||||||
|
invalidate_dcache_range((unsigned long)(addr), \
|
||||||
|
ALIGN((unsigned long)(addr) + size, ARCH_DMA_MINALIGN))
|
||||||
|
#else
|
||||||
|
#define flush_dcache_buffer(addr, size)
|
||||||
|
#define invalidate_dcache_buffer(addr, size)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Do not use sizeof(ed / td) as our ed / td structs contain extra members */
|
||||||
|
#define flush_dcache_ed(addr) flush_dcache_buffer(addr, 16)
|
||||||
|
#define flush_dcache_td(addr) flush_dcache_buffer(addr, 16)
|
||||||
|
#define flush_dcache_iso_td(addr) flush_dcache_buffer(addr, 32)
|
||||||
|
#define flush_dcache_hcca(addr) flush_dcache_buffer(addr, 256)
|
||||||
|
#define invalidate_dcache_ed(addr) invalidate_dcache_buffer(addr, 16)
|
||||||
|
#define invalidate_dcache_td(addr) invalidate_dcache_buffer(addr, 16)
|
||||||
|
#define invalidate_dcache_iso_td(addr) invalidate_dcache_buffer(addr, 32)
|
||||||
|
#define invalidate_dcache_hcca(addr) invalidate_dcache_buffer(addr, 256)
|
||||||
|
|
||||||
/* global ohci_t */
|
/* global ohci_t */
|
||||||
static ohci_t gohci;
|
static ohci_t gohci;
|
||||||
/* this must be aligned to a 256 byte boundary */
|
/* this must be aligned to a 256 byte boundary */
|
||||||
@ -293,9 +319,11 @@ void ep_print_int_eds(ohci_t *ohci, char *str)
|
|||||||
ed_p = &(ohci->hcca->int_table [i]);
|
ed_p = &(ohci->hcca->int_table [i]);
|
||||||
if (*ed_p == 0)
|
if (*ed_p == 0)
|
||||||
continue;
|
continue;
|
||||||
|
invalidate_dcache_ed(ed_p);
|
||||||
printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);
|
printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);
|
||||||
while (*ed_p != 0 && j--) {
|
while (*ed_p != 0 && j--) {
|
||||||
ed_t *ed = (ed_t *)m32_swap(ed_p);
|
ed_t *ed = (ed_t *)m32_swap(ed_p);
|
||||||
|
invalidate_dcache_ed(ed);
|
||||||
printf(" ed: %4x;", ed->hwINFO);
|
printf(" ed: %4x;", ed->hwINFO);
|
||||||
ed_p = &ed->hwNextED;
|
ed_p = &ed->hwNextED;
|
||||||
}
|
}
|
||||||
@ -326,6 +354,7 @@ static void maybe_print_eds(char *label, __u32 value)
|
|||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
dbg("%s %08x", label, value);
|
dbg("%s %08x", label, value);
|
||||||
|
invalidate_dcache_ed(edp);
|
||||||
dbg("%08x", edp->hwINFO);
|
dbg("%08x", edp->hwINFO);
|
||||||
dbg("%08x", edp->hwTailP);
|
dbg("%08x", edp->hwTailP);
|
||||||
dbg("%08x", edp->hwHeadP);
|
dbg("%08x", edp->hwHeadP);
|
||||||
@ -460,6 +489,7 @@ static void ohci_dump(ohci_t *controller, int verbose)
|
|||||||
ohci_dump_status(controller);
|
ohci_dump_status(controller);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
ep_print_int_eds(controller, "hcca");
|
ep_print_int_eds(controller, "hcca");
|
||||||
|
invalidate_dcache_hcca(controller->hcca);
|
||||||
dbg("hcca frame #%04x", controller->hcca->frame_no);
|
dbg("hcca frame #%04x", controller->hcca->frame_no);
|
||||||
ohci_dump_roothub(controller, 1);
|
ohci_dump_roothub(controller, 1);
|
||||||
}
|
}
|
||||||
@ -597,6 +627,7 @@ static inline int sohci_return_job(struct ohci *hc, urb_priv_t *urb)
|
|||||||
/* tell us the current USB frame number */
|
/* tell us the current USB frame number */
|
||||||
static int sohci_get_current_frame_number(ohci_t *ohci)
|
static int sohci_get_current_frame_number(ohci_t *ohci)
|
||||||
{
|
{
|
||||||
|
invalidate_dcache_hcca(ohci->hcca);
|
||||||
return m16_swap(ohci->hcca->frame_no);
|
return m16_swap(ohci->hcca->frame_no);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -675,6 +706,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
|||||||
switch (ed->type) {
|
switch (ed->type) {
|
||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
ed->hwNextED = 0;
|
ed->hwNextED = 0;
|
||||||
|
flush_dcache_ed(ed);
|
||||||
if (ohci->ed_controltail == NULL)
|
if (ohci->ed_controltail == NULL)
|
||||||
ohci_writel(ed, &ohci->regs->ed_controlhead);
|
ohci_writel(ed, &ohci->regs->ed_controlhead);
|
||||||
else
|
else
|
||||||
@ -692,6 +724,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
|||||||
|
|
||||||
case PIPE_BULK:
|
case PIPE_BULK:
|
||||||
ed->hwNextED = 0;
|
ed->hwNextED = 0;
|
||||||
|
flush_dcache_ed(ed);
|
||||||
if (ohci->ed_bulktail == NULL)
|
if (ohci->ed_bulktail == NULL)
|
||||||
ohci_writel(ed, &ohci->regs->ed_bulkhead);
|
ohci_writel(ed, &ohci->regs->ed_bulkhead);
|
||||||
else
|
else
|
||||||
@ -724,7 +757,9 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
|||||||
inter = ep_rev(6,
|
inter = ep_rev(6,
|
||||||
((ed_t *)ed_p)->int_interval);
|
((ed_t *)ed_p)->int_interval);
|
||||||
ed->hwNextED = *ed_p;
|
ed->hwNextED = *ed_p;
|
||||||
|
flush_dcache_ed(ed);
|
||||||
*ed_p = m32_swap((unsigned long)ed);
|
*ed_p = m32_swap((unsigned long)ed);
|
||||||
|
flush_dcache_hcca(ohci->hcca);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -737,6 +772,8 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
|||||||
static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed,
|
static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed,
|
||||||
unsigned index, unsigned period)
|
unsigned index, unsigned period)
|
||||||
{
|
{
|
||||||
|
__maybe_unused unsigned long aligned_ed_p;
|
||||||
|
|
||||||
for (; index < NUM_INTS; index += period) {
|
for (; index < NUM_INTS; index += period) {
|
||||||
__u32 *ed_p = &ohci->hcca->int_table [index];
|
__u32 *ed_p = &ohci->hcca->int_table [index];
|
||||||
|
|
||||||
@ -745,6 +782,12 @@ static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed,
|
|||||||
if (((struct ed *)
|
if (((struct ed *)
|
||||||
m32_swap((unsigned long)ed_p)) == ed) {
|
m32_swap((unsigned long)ed_p)) == ed) {
|
||||||
*ed_p = ed->hwNextED;
|
*ed_p = ed->hwNextED;
|
||||||
|
#ifdef CONFIG_DM_USB
|
||||||
|
aligned_ed_p = (unsigned long)ed_p;
|
||||||
|
aligned_ed_p &= ~(ARCH_DMA_MINALIGN - 1);
|
||||||
|
flush_dcache_range(aligned_ed_p,
|
||||||
|
aligned_ed_p + ARCH_DMA_MINALIGN);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ed_p = &(((struct ed *)
|
ed_p = &(((struct ed *)
|
||||||
@ -764,6 +807,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
ed->hwINFO |= m32_swap(OHCI_ED_SKIP);
|
ed->hwINFO |= m32_swap(OHCI_ED_SKIP);
|
||||||
|
flush_dcache_ed(ed);
|
||||||
|
|
||||||
switch (ed->type) {
|
switch (ed->type) {
|
||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
@ -777,6 +821,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)
|
|||||||
&ohci->regs->ed_controlhead);
|
&ohci->regs->ed_controlhead);
|
||||||
} else {
|
} else {
|
||||||
ed->ed_prev->hwNextED = ed->hwNextED;
|
ed->ed_prev->hwNextED = ed->hwNextED;
|
||||||
|
flush_dcache_ed(ed->ed_prev);
|
||||||
}
|
}
|
||||||
if (ohci->ed_controltail == ed) {
|
if (ohci->ed_controltail == ed) {
|
||||||
ohci->ed_controltail = ed->ed_prev;
|
ohci->ed_controltail = ed->ed_prev;
|
||||||
@ -797,6 +842,7 @@ static int ep_unlink(ohci_t *ohci, ed_t *edi)
|
|||||||
&ohci->regs->ed_bulkhead);
|
&ohci->regs->ed_bulkhead);
|
||||||
} else {
|
} else {
|
||||||
ed->ed_prev->hwNextED = ed->hwNextED;
|
ed->ed_prev->hwNextED = ed->hwNextED;
|
||||||
|
flush_dcache_ed(ed->ed_prev);
|
||||||
}
|
}
|
||||||
if (ohci->ed_bulktail == ed) {
|
if (ohci->ed_bulktail == ed) {
|
||||||
ohci->ed_bulktail = ed->ed_prev;
|
ohci->ed_bulktail = ed->ed_prev;
|
||||||
@ -865,6 +911,8 @@ static ed_t *ep_add_ed(ohci_dev_t *ohci_dev, struct usb_device *usb_dev,
|
|||||||
ed->int_load = load;
|
ed->int_load = load;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_dcache_ed(ed);
|
||||||
|
|
||||||
return ed_ret;
|
return ed_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,6 +938,7 @@ static void td_fill(ohci_t *ohci, unsigned int info,
|
|||||||
/* use this td as the next dummy */
|
/* use this td as the next dummy */
|
||||||
td_pt = urb_priv->td [index];
|
td_pt = urb_priv->td [index];
|
||||||
td_pt->hwNextTD = 0;
|
td_pt->hwNextTD = 0;
|
||||||
|
flush_dcache_td(td_pt);
|
||||||
|
|
||||||
/* fill the old dummy TD */
|
/* fill the old dummy TD */
|
||||||
td = urb_priv->td [index] =
|
td = urb_priv->td [index] =
|
||||||
@ -917,9 +966,11 @@ static void td_fill(ohci_t *ohci, unsigned int info,
|
|||||||
td->hwBE = 0;
|
td->hwBE = 0;
|
||||||
|
|
||||||
td->hwNextTD = m32_swap((unsigned long)td_pt);
|
td->hwNextTD = m32_swap((unsigned long)td_pt);
|
||||||
|
flush_dcache_td(td);
|
||||||
|
|
||||||
/* append to queue */
|
/* append to queue */
|
||||||
td->ed->hwTailP = td->hwNextTD;
|
td->ed->hwTailP = td->hwNextTD;
|
||||||
|
flush_dcache_ed(td->ed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -937,6 +988,8 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev,
|
|||||||
__u32 info = 0;
|
__u32 info = 0;
|
||||||
unsigned int toggle = 0;
|
unsigned int toggle = 0;
|
||||||
|
|
||||||
|
flush_dcache_buffer(buffer, data_len);
|
||||||
|
|
||||||
/* OHCI handles the DATA-toggles itself, we just use the USB-toggle
|
/* OHCI handles the DATA-toggles itself, we just use the USB-toggle
|
||||||
* bits for reseting */
|
* bits for reseting */
|
||||||
if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
|
if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
|
||||||
@ -976,6 +1029,7 @@ static void td_submit_job(ohci_t *ohci, struct usb_device *dev,
|
|||||||
case PIPE_CONTROL:
|
case PIPE_CONTROL:
|
||||||
/* Setup phase */
|
/* Setup phase */
|
||||||
info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
|
info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
|
||||||
|
flush_dcache_buffer(setup, 8);
|
||||||
td_fill(ohci, info, setup, 8, dev, cnt++, urb);
|
td_fill(ohci, info, setup, 8, dev, cnt++, urb);
|
||||||
|
|
||||||
/* Optional Data phase */
|
/* Optional Data phase */
|
||||||
@ -1047,6 +1101,7 @@ static void check_status(td_t *td_list)
|
|||||||
if (cc) {
|
if (cc) {
|
||||||
err(" USB-error: %s (%x)", cc_to_string[cc], cc);
|
err(" USB-error: %s (%x)", cc_to_string[cc], cc);
|
||||||
|
|
||||||
|
invalidate_dcache_ed(td_list->ed);
|
||||||
if (*phwHeadP & m32_swap(0x1)) {
|
if (*phwHeadP & m32_swap(0x1)) {
|
||||||
if (lurb_priv &&
|
if (lurb_priv &&
|
||||||
((td_list->index + 1) < urb_len)) {
|
((td_list->index + 1) < urb_len)) {
|
||||||
@ -1059,9 +1114,11 @@ static void check_status(td_t *td_list)
|
|||||||
td_list->index - 1;
|
td_list->index - 1;
|
||||||
} else
|
} else
|
||||||
*phwHeadP &= m32_swap(0xfffffff2);
|
*phwHeadP &= m32_swap(0xfffffff2);
|
||||||
|
flush_dcache_ed(td_list->ed);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_MPC5200
|
#ifdef CONFIG_MPC5200
|
||||||
td_list->hwNextTD = 0;
|
td_list->hwNextTD = 0;
|
||||||
|
flush_dcache_td(td_list);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1074,11 +1131,14 @@ static td_t *dl_reverse_done_list(ohci_t *ohci)
|
|||||||
td_t *td_rev = NULL;
|
td_t *td_rev = NULL;
|
||||||
td_t *td_list = NULL;
|
td_t *td_list = NULL;
|
||||||
|
|
||||||
|
invalidate_dcache_hcca(ohci->hcca);
|
||||||
td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0;
|
td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0;
|
||||||
ohci->hcca->done_head = 0;
|
ohci->hcca->done_head = 0;
|
||||||
|
flush_dcache_hcca(ohci->hcca);
|
||||||
|
|
||||||
while (td_list_hc) {
|
while (td_list_hc) {
|
||||||
td_list = (td_t *)td_list_hc;
|
td_list = (td_t *)td_list_hc;
|
||||||
|
invalidate_dcache_td(td_list);
|
||||||
check_status(td_list);
|
check_status(td_list);
|
||||||
td_list->next_dl_td = td_rev;
|
td_list->next_dl_td = td_rev;
|
||||||
td_rev = td_list;
|
td_rev = td_list;
|
||||||
@ -1113,6 +1173,7 @@ static int takeback_td(ohci_t *ohci, td_t *td_list)
|
|||||||
urb_priv_t *lurb_priv;
|
urb_priv_t *lurb_priv;
|
||||||
__u32 tdINFO, edHeadP, edTailP;
|
__u32 tdINFO, edHeadP, edTailP;
|
||||||
|
|
||||||
|
invalidate_dcache_td(td_list);
|
||||||
tdINFO = m32_swap(td_list->hwINFO);
|
tdINFO = m32_swap(td_list->hwINFO);
|
||||||
|
|
||||||
ed = td_list->ed;
|
ed = td_list->ed;
|
||||||
@ -1138,6 +1199,7 @@ static int takeback_td(ohci_t *ohci, td_t *td_list)
|
|||||||
lurb_priv->td_cnt, lurb_priv->length);
|
lurb_priv->td_cnt, lurb_priv->length);
|
||||||
|
|
||||||
if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe))) {
|
if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe))) {
|
||||||
|
invalidate_dcache_ed(ed);
|
||||||
edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0;
|
edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0;
|
||||||
edTailP = m32_swap(ed->hwTailP);
|
edTailP = m32_swap(ed->hwTailP);
|
||||||
|
|
||||||
@ -1521,6 +1583,9 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
|
|||||||
dev->status = stat;
|
dev->status = stat;
|
||||||
dev->act_len = urb->actual_length;
|
dev->act_len = urb->actual_length;
|
||||||
|
|
||||||
|
if (usb_pipein(pipe) && dev->status == 0 && dev->act_len)
|
||||||
|
invalidate_dcache_buffer(buffer, dev->act_len);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
pkt_print(ohci, urb, dev, pipe, buffer, transfer_len,
|
pkt_print(ohci, urb, dev, pipe, buffer, transfer_len,
|
||||||
setup, "RET(ctlr)", usb_pipein(pipe));
|
setup, "RET(ctlr)", usb_pipein(pipe));
|
||||||
@ -1727,6 +1792,8 @@ static int hc_interrupt(ohci_t *ohci)
|
|||||||
int ints;
|
int ints;
|
||||||
int stat = -1;
|
int stat = -1;
|
||||||
|
|
||||||
|
invalidate_dcache_hcca(ohci->hcca);
|
||||||
|
|
||||||
if ((ohci->hcca->done_head != 0) &&
|
if ((ohci->hcca->done_head != 0) &&
|
||||||
!(m32_swap(ohci->hcca->done_head) & 0x01)) {
|
!(m32_swap(ohci->hcca->done_head) & 0x01)) {
|
||||||
ints = OHCI_INTR_WDH;
|
ints = OHCI_INTR_WDH;
|
||||||
|
@ -18,6 +18,18 @@
|
|||||||
# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
|
# define ohci_writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a))
|
||||||
#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
|
#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
|
||||||
|
|
||||||
|
#if defined CONFIG_DM_USB && ARCH_DMA_MINALIGN > 16
|
||||||
|
#define ED_ALIGNMENT ARCH_DMA_MINALIGN
|
||||||
|
#else
|
||||||
|
#define ED_ALIGNMENT 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined CONFIG_DM_USB && ARCH_DMA_MINALIGN > 32
|
||||||
|
#define TD_ALIGNMENT ARCH_DMA_MINALIGN
|
||||||
|
#else
|
||||||
|
#define TD_ALIGNMENT 32
|
||||||
|
#endif
|
||||||
|
|
||||||
/* functions for doing board or CPU specific setup/cleanup */
|
/* functions for doing board or CPU specific setup/cleanup */
|
||||||
int usb_board_stop(void);
|
int usb_board_stop(void);
|
||||||
|
|
||||||
@ -52,7 +64,7 @@ struct ed {
|
|||||||
struct usb_device *usb_dev;
|
struct usb_device *usb_dev;
|
||||||
void *purb;
|
void *purb;
|
||||||
__u32 unused[2];
|
__u32 unused[2];
|
||||||
} __attribute__((aligned(16)));
|
} __attribute__((aligned(ED_ALIGNMENT)));
|
||||||
typedef struct ed ed_t;
|
typedef struct ed ed_t;
|
||||||
|
|
||||||
|
|
||||||
@ -112,7 +124,7 @@ struct td {
|
|||||||
__u32 data;
|
__u32 data;
|
||||||
|
|
||||||
__u32 unused2[2];
|
__u32 unused2[2];
|
||||||
} __attribute__((aligned(32)));
|
} __attribute__((aligned(TD_ALIGNMENT)));
|
||||||
typedef struct td td_t;
|
typedef struct td td_t;
|
||||||
|
|
||||||
#define OHCI_ED_SKIP (1 << 14)
|
#define OHCI_ED_SKIP (1 << 14)
|
||||||
@ -356,8 +368,8 @@ typedef struct
|
|||||||
#define NUM_TD 64 /* we need more TDs than EDs */
|
#define NUM_TD 64 /* we need more TDs than EDs */
|
||||||
|
|
||||||
typedef struct ohci_device {
|
typedef struct ohci_device {
|
||||||
ed_t ed[NUM_EDS] __aligned(16);
|
ed_t ed[NUM_EDS] __aligned(ED_ALIGNMENT);
|
||||||
td_t tds[NUM_TD] __aligned(32);
|
td_t tds[NUM_TD] __aligned(TD_ALIGNMENT);
|
||||||
int ed_cnt;
|
int ed_cnt;
|
||||||
} ohci_dev_t;
|
} ohci_dev_t;
|
||||||
|
|
||||||
@ -371,7 +383,7 @@ typedef struct ohci_device {
|
|||||||
|
|
||||||
typedef struct ohci {
|
typedef struct ohci {
|
||||||
/* this allocates EDs for all possible endpoints */
|
/* this allocates EDs for all possible endpoints */
|
||||||
struct ohci_device ohci_dev __aligned(32);
|
struct ohci_device ohci_dev __aligned(TD_ALIGNMENT);
|
||||||
struct ohci_hcca *hcca; /* hcca */
|
struct ohci_hcca *hcca; /* hcca */
|
||||||
/*dma_addr_t hcca_dma;*/
|
/*dma_addr_t hcca_dma;*/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user