From 28b9325e6ae45ffb5e99fedcafe00f25fcaacf06 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 19 Feb 2007 15:51:51 -0500 Subject: [PATCH] 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: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-debug.c | 9 ++++----- drivers/usb/host/uhci-hcd.c | 22 +++++++++------------- drivers/usb/host/uhci-hcd.h | 8 ++++++-- drivers/usb/host/uhci-q.c | 30 ++++++++++++++---------------- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 5d6c06bc4524..a0677133577b 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -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, 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", space, ""); i = nurbs = 0; @@ -393,7 +393,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) do { td = list_entry(tmp, struct uhci_td, fl_list); tmp = tmp->next; - if (cpu_to_le32(td->dma_handle) != link) { + if (link != LINK_TO_TD(td)) { if (nframes > 0) out += sprintf(out, " link does " "not match list entry!\n"); @@ -440,7 +440,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) if (qh->link != UHCI_PTR_TERM) 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"); continue; @@ -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); if (i > 1 && i < UHCI_NUM_SKELQH - 1) { - if (qh->link != - (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) + if (qh->link != LINK_TO_QH(uhci->skelqh[j])) out += sprintf(out, " last QH not linked to next skeleton!\n"); } } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index ded4df30a631..1f0833ab294a 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -116,7 +116,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); if (skelnum <= 1) 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" @@ -635,25 +635,21 @@ static int uhci_start(struct usb_hcd *hcd) uhci->skel_int16_qh->link = uhci->skel_int8_qh->link = uhci->skel_int4_qh->link = - uhci->skel_int2_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_int1_qh->dma_handle); + uhci->skel_int2_qh->link = LINK_TO_QH( + uhci->skel_int1_qh); - uhci->skel_int1_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_ls_control_qh->dma_handle); - uhci->skel_ls_control_qh->link = UHCI_PTR_QH | - cpu_to_le32(uhci->skel_fs_control_qh->dma_handle); - 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); + uhci->skel_int1_qh->link = LINK_TO_QH(uhci->skel_ls_control_qh); + uhci->skel_ls_control_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh); + uhci->skel_fs_control_qh->link = LINK_TO_QH(uhci->skel_bulk_qh); + uhci->skel_bulk_qh->link = LINK_TO_QH(uhci->skel_term_qh); /* This dummy TD is to work around a bug in Intel PIIX controllers */ uhci_fill_td(uhci->term_td, 0, uhci_explen(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->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 diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 74469b5bcb61..a8c256b44d8e 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -129,6 +129,8 @@ struct uhci_qh { __le32 element; /* Queue element (TD) pointer */ /* Software fields */ + dma_addr_t dma_handle; + struct list_head node; /* Node in the list of QHs */ struct usb_host_endpoint *hep; /* Endpoint information */ struct usb_device *udev; @@ -150,8 +152,6 @@ struct uhci_qh { int state; /* QH_STATE_xxx; see above */ int type; /* Queue type (control, bulk, etc) */ - dma_addr_t dma_handle; - unsigned int initial_toggle:1; /* Endpoint's current toggle value */ unsigned int needs_fixup:1; /* Must fix the TD toggle values */ unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ @@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) { return element; } +#define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle)) + /* * Transfer Descriptors @@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) { return le32_to_cpu(status); } +#define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle)) + /* * Skeleton Queue Headers diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 68e66b33e726..a0c6bf6128a3 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -46,8 +46,7 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) static void uhci_fsbr_on(struct uhci_hcd *uhci) { uhci->fsbr_is_on = 1; - uhci->skel_term_qh->link = cpu_to_le32( - uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh); } 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, td->link = ltd->link; wmb(); - ltd->link = cpu_to_le32(td->dma_handle); + ltd->link = LINK_TO_TD(td); } else { td->link = uhci->frame[framenum]; wmb(); - uhci->frame[framenum] = cpu_to_le32(td->dma_handle); + uhci->frame[framenum] = LINK_TO_TD(td); uhci->frame_cpu[framenum] = td; } } @@ -184,7 +183,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, struct uhci_td *ntd; 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; } } else { @@ -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, list); - qh->element = cpu_to_le32(td->dma_handle); + qh->element = LINK_TO_TD(td); } /* 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) pqh = list_entry(qh->node.prev, struct uhci_qh, node); qh->link = pqh->link; 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, td = uhci_alloc_td(uhci); if (!td) goto nomem; - *plink = cpu_to_le32(td->dma_handle); + *plink = LINK_TO_TD(td); /* Alternate Data0/1 (start with Data1) */ destination ^= TD_TOKEN_TOGGLE; @@ -757,7 +756,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, td = uhci_alloc_td(uhci); if (!td) 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 @@ -784,7 +783,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, td = uhci_alloc_td(uhci); if (!td) 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); wmb(); @@ -860,7 +859,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, td = uhci_alloc_td(uhci); if (!td) goto nomem; - *plink = cpu_to_le32(td->dma_handle); + *plink = LINK_TO_TD(td); } uhci_add_td_to_urbp(td, urbp); uhci_fill_td(td, status, @@ -888,7 +887,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, td = uhci_alloc_td(uhci); if (!td) goto nomem; - *plink = cpu_to_le32(td->dma_handle); + *plink = LINK_TO_TD(td); uhci_add_td_to_urbp(td, urbp); uhci_fill_td(td, status, @@ -914,7 +913,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, td = uhci_alloc_td(uhci); if (!td) 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); wmb(); @@ -1005,7 +1004,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, * the queue at the status stage transaction, which is * the last TD. */ 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; ret = -EINPROGRESS; @@ -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)) { /* Detect the Intel bug and work around it */ - if (qh->post_td && qh_element(qh) == - cpu_to_le32(qh->post_td->dma_handle)) { + if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) { qh->element = qh->post_td->link; qh->advance_jiffies = jiffies; ret = 1;