Commit 28b9325e authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

UHCI: Add macros for computing DMA values

This patch (as855) adds some convenience macros to uhci-hcd, to help
simplify the code for computing hardware DMA pointers.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d0374f4f
...@@ -196,7 +196,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) ...@@ -196,7 +196,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
struct uhci_td *td = list_entry(urbp->td_list.next, struct uhci_td *td = list_entry(urbp->td_list.next,
struct uhci_td, list); struct uhci_td, list);
if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS)) if (element != LINK_TO_TD(td))
out += sprintf(out, "%*s Element != First TD\n", out += sprintf(out, "%*s Element != First TD\n",
space, ""); space, "");
i = nurbs = 0; i = nurbs = 0;
...@@ -393,7 +393,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) ...@@ -393,7 +393,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
do { do {
td = list_entry(tmp, struct uhci_td, fl_list); td = list_entry(tmp, struct uhci_td, fl_list);
tmp = tmp->next; tmp = tmp->next;
if (cpu_to_le32(td->dma_handle) != link) { if (link != LINK_TO_TD(td)) {
if (nframes > 0) if (nframes > 0)
out += sprintf(out, " link does " out += sprintf(out, " link does "
"not match list entry!\n"); "not match list entry!\n");
...@@ -440,7 +440,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) ...@@ -440,7 +440,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
if (qh->link != UHCI_PTR_TERM) if (qh->link != UHCI_PTR_TERM)
out += sprintf(out, " bandwidth reclamation on!\n"); out += sprintf(out, " bandwidth reclamation on!\n");
if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle)) if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); out += sprintf(out, " skel_term_qh element is not set to term_td!\n");
continue; continue;
...@@ -461,8 +461,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) ...@@ -461,8 +461,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
out += sprintf(out, " Skipped %d QHs\n", cnt); out += sprintf(out, " Skipped %d QHs\n", cnt);
if (i > 1 && i < UHCI_NUM_SKELQH - 1) { if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
if (qh->link != if (qh->link != LINK_TO_QH(uhci->skelqh[j]))
(cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH))
out += sprintf(out, " last QH not linked to next skeleton!\n"); out += sprintf(out, " last QH not linked to next skeleton!\n");
} }
} }
......
...@@ -116,7 +116,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) ...@@ -116,7 +116,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)
skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
if (skelnum <= 1) if (skelnum <= 1)
skelnum = 9; skelnum = 9;
return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); return LINK_TO_QH(uhci->skelqh[skelnum]);
} }
#include "uhci-debug.c" #include "uhci-debug.c"
...@@ -635,25 +635,21 @@ static int uhci_start(struct usb_hcd *hcd) ...@@ -635,25 +635,21 @@ static int uhci_start(struct usb_hcd *hcd)
uhci->skel_int16_qh->link = uhci->skel_int16_qh->link =
uhci->skel_int8_qh->link = uhci->skel_int8_qh->link =
uhci->skel_int4_qh->link = uhci->skel_int4_qh->link =
uhci->skel_int2_qh->link = UHCI_PTR_QH | uhci->skel_int2_qh->link = LINK_TO_QH(
cpu_to_le32(uhci->skel_int1_qh->dma_handle); uhci->skel_int1_qh);
uhci->skel_int1_qh->link = UHCI_PTR_QH | uhci->skel_int1_qh->link = LINK_TO_QH(uhci->skel_ls_control_qh);
cpu_to_le32(uhci->skel_ls_control_qh->dma_handle); uhci->skel_ls_control_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh);
uhci->skel_ls_control_qh->link = UHCI_PTR_QH | uhci->skel_fs_control_qh->link = LINK_TO_QH(uhci->skel_bulk_qh);
cpu_to_le32(uhci->skel_fs_control_qh->dma_handle); uhci->skel_bulk_qh->link = LINK_TO_QH(uhci->skel_term_qh);
uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
uhci->skel_bulk_qh->link = UHCI_PTR_QH |
cpu_to_le32(uhci->skel_term_qh->dma_handle);
/* This dummy TD is to work around a bug in Intel PIIX controllers */ /* This dummy TD is to work around a bug in Intel PIIX controllers */
uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); uhci->term_td->link = LINK_TO_TD(uhci->term_td);
uhci->skel_term_qh->link = UHCI_PTR_TERM; uhci->skel_term_qh->link = UHCI_PTR_TERM;
uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle); uhci->skel_term_qh->element = LINK_TO_TD(uhci->term_td);
/* /*
* Fill the frame list: make all entries point to the proper * Fill the frame list: make all entries point to the proper
......
...@@ -129,6 +129,8 @@ struct uhci_qh { ...@@ -129,6 +129,8 @@ struct uhci_qh {
__le32 element; /* Queue element (TD) pointer */ __le32 element; /* Queue element (TD) pointer */
/* Software fields */ /* Software fields */
dma_addr_t dma_handle;
struct list_head node; /* Node in the list of QHs */ struct list_head node; /* Node in the list of QHs */
struct usb_host_endpoint *hep; /* Endpoint information */ struct usb_host_endpoint *hep; /* Endpoint information */
struct usb_device *udev; struct usb_device *udev;
...@@ -150,8 +152,6 @@ struct uhci_qh { ...@@ -150,8 +152,6 @@ struct uhci_qh {
int state; /* QH_STATE_xxx; see above */ int state; /* QH_STATE_xxx; see above */
int type; /* Queue type (control, bulk, etc) */ int type; /* Queue type (control, bulk, etc) */
dma_addr_t dma_handle;
unsigned int initial_toggle:1; /* Endpoint's current toggle value */ unsigned int initial_toggle:1; /* Endpoint's current toggle value */
unsigned int needs_fixup:1; /* Must fix the TD toggle values */ unsigned int needs_fixup:1; /* Must fix the TD toggle values */
unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ unsigned int is_stopped:1; /* Queue was stopped by error/unlink */
...@@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) { ...@@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) {
return element; return element;
} }
#define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
/* /*
* Transfer Descriptors * Transfer Descriptors
...@@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) { ...@@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) {
return le32_to_cpu(status); return le32_to_cpu(status);
} }
#define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle))
/* /*
* Skeleton Queue Headers * Skeleton Queue Headers
......
...@@ -46,8 +46,7 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) ...@@ -46,8 +46,7 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
static void uhci_fsbr_on(struct uhci_hcd *uhci) static void uhci_fsbr_on(struct uhci_hcd *uhci)
{ {
uhci->fsbr_is_on = 1; uhci->fsbr_is_on = 1;
uhci->skel_term_qh->link = cpu_to_le32( uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh);
uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
} }
static void uhci_fsbr_off(struct uhci_hcd *uhci) static void uhci_fsbr_off(struct uhci_hcd *uhci)
...@@ -158,11 +157,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, ...@@ -158,11 +157,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci,
td->link = ltd->link; td->link = ltd->link;
wmb(); wmb();
ltd->link = cpu_to_le32(td->dma_handle); ltd->link = LINK_TO_TD(td);
} else { } else {
td->link = uhci->frame[framenum]; td->link = uhci->frame[framenum];
wmb(); wmb();
uhci->frame[framenum] = cpu_to_le32(td->dma_handle); uhci->frame[framenum] = LINK_TO_TD(td);
uhci->frame_cpu[framenum] = td; uhci->frame_cpu[framenum] = td;
} }
} }
...@@ -184,7 +183,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, ...@@ -184,7 +183,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
struct uhci_td *ntd; struct uhci_td *ntd;
ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); uhci->frame[td->frame] = LINK_TO_TD(ntd);
uhci->frame_cpu[td->frame] = ntd; uhci->frame_cpu[td->frame] = ntd;
} }
} else { } else {
...@@ -421,7 +420,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) ...@@ -421,7 +420,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
struct uhci_td *td = list_entry(urbp->td_list.next, struct uhci_td *td = list_entry(urbp->td_list.next,
struct uhci_td, list); struct uhci_td, list);
qh->element = cpu_to_le32(td->dma_handle); qh->element = LINK_TO_TD(td);
} }
/* Treat the queue as if it has just advanced */ /* Treat the queue as if it has just advanced */
...@@ -443,7 +442,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) ...@@ -443,7 +442,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
pqh = list_entry(qh->node.prev, struct uhci_qh, node); pqh = list_entry(qh->node.prev, struct uhci_qh, node);
qh->link = pqh->link; qh->link = pqh->link;
wmb(); wmb();
pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); pqh->link = LINK_TO_QH(qh);
} }
/* /*
...@@ -737,7 +736,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, ...@@ -737,7 +736,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
/* Alternate Data0/1 (start with Data1) */ /* Alternate Data0/1 (start with Data1) */
destination ^= TD_TOKEN_TOGGLE; destination ^= TD_TOKEN_TOGGLE;
...@@ -757,7 +756,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, ...@@ -757,7 +756,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
/* /*
* It's IN if the pipe is an output pipe or we're not expecting * It's IN if the pipe is an output pipe or we're not expecting
...@@ -784,7 +783,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, ...@@ -784,7 +783,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb(); wmb();
...@@ -860,7 +859,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, ...@@ -860,7 +859,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
} }
uhci_add_td_to_urbp(td, urbp); uhci_add_td_to_urbp(td, urbp);
uhci_fill_td(td, status, uhci_fill_td(td, status,
...@@ -888,7 +887,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, ...@@ -888,7 +887,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
uhci_add_td_to_urbp(td, urbp); uhci_add_td_to_urbp(td, urbp);
uhci_fill_td(td, status, uhci_fill_td(td, status,
...@@ -914,7 +913,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, ...@@ -914,7 +913,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
td = uhci_alloc_td(uhci); td = uhci_alloc_td(uhci);
if (!td) if (!td)
goto nomem; goto nomem;
*plink = cpu_to_le32(td->dma_handle); *plink = LINK_TO_TD(td);
uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
wmb(); wmb();
...@@ -1005,7 +1004,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, ...@@ -1005,7 +1004,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci,
* the queue at the status stage transaction, which is * the queue at the status stage transaction, which is
* the last TD. */ * the last TD. */
WARN_ON(list_empty(&urbp->td_list)); WARN_ON(list_empty(&urbp->td_list));
qh->element = cpu_to_le32(td->dma_handle); qh->element = LINK_TO_TD(td);
tmp = td->list.prev; tmp = td->list.prev;
ret = -EINPROGRESS; ret = -EINPROGRESS;
...@@ -1566,8 +1565,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) ...@@ -1566,8 +1565,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh)
if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
/* Detect the Intel bug and work around it */ /* Detect the Intel bug and work around it */
if (qh->post_td && qh_element(qh) == if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
cpu_to_le32(qh->post_td->dma_handle)) {
qh->element = qh->post_td->link; qh->element = qh->post_td->link;
qh->advance_jiffies = jiffies; qh->advance_jiffies = jiffies;
ret = 1; ret = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment