Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 265142
b: refs/heads/master
c: 68aa95d
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Oct 18, 2011
1 parent c0701b6 commit c57dbfc
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 91960c2ef095c4b0744349e80a933921cbdcfd6e
refs/heads/master: 68aa95d5d4de31c9348c1628ffa85c805305ebc5
2 changes: 1 addition & 1 deletion trunk/drivers/usb/host/ehci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
next += temp;

temp = scnprintf (next, size, "uframe %04x\n",
ehci_readl(ehci, &ehci->regs->frame_index));
ehci_read_frame_index(ehci));
size -= temp;
next += temp;

Expand Down
3 changes: 1 addition & 2 deletions trunk/drivers/usb/host/ehci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,8 +1195,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
static int ehci_get_frame (struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) %
ehci->periodic_size;
return (ehci_read_frame_index(ehci) >> 3) % ehci->periodic_size;
}

/*-------------------------------------------------------------------------*/
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/usb/host/ehci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
pci_dev_put(p_smbus);
}
break;
case PCI_VENDOR_ID_NETMOS:
/* MosChip frame-index-register bug */
ehci_info(ehci, "applying MosChip frame-index workaround\n");
ehci->frame_index_bug = 1;
break;
}

/* optional debug port, normally in the first BAR */
Expand Down
30 changes: 25 additions & 5 deletions trunk/drivers/usb/host/ehci-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@

static int ehci_get_frame (struct usb_hcd *hcd);

#ifdef CONFIG_PCI

static unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
{
unsigned uf;

/*
* The MosChip MCS9990 controller updates its microframe counter
* a little before the frame counter, and occasionally we will read
* the invalid intermediate value. Avoid problems by checking the
* microframe number (the low-order 3 bits); if they are 0 then
* re-read the register to get the correct value.
*/
uf = ehci_readl(ehci, &ehci->regs->frame_index);
if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0)))
uf = ehci_readl(ehci, &ehci->regs->frame_index);
return uf;
}

#endif

/*-------------------------------------------------------------------------*/

/*
Expand Down Expand Up @@ -481,7 +502,7 @@ static int enable_periodic (struct ehci_hcd *ehci)
/* posted write ... PSS happens later */

/* make sure ehci_work scans these */
ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
ehci->next_uframe = ehci_read_frame_index(ehci)
% (ehci->periodic_size << 3);
if (unlikely(ehci->broken_periodic))
ehci->last_periodic_enable = ktime_get_real();
Expand Down Expand Up @@ -1408,7 +1429,7 @@ iso_stream_schedule (
goto fail;
}

now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1);
now = ehci_read_frame_index(ehci) & (mod - 1);

/* Typical case: reuse current schedule, stream is still active.
* Hopefully there are no gaps from the host falling behind
Expand Down Expand Up @@ -2275,7 +2296,7 @@ scan_periodic (struct ehci_hcd *ehci)
*/
now_uframe = ehci->next_uframe;
if (ehci->rh_state == EHCI_RH_RUNNING) {
clock = ehci_readl(ehci, &ehci->regs->frame_index);
clock = ehci_read_frame_index(ehci);
clock_frame = (clock >> 3) & (ehci->periodic_size - 1);
} else {
clock = now_uframe + mod - 1;
Expand Down Expand Up @@ -2454,8 +2475,7 @@ scan_periodic (struct ehci_hcd *ehci)
|| ehci->periodic_sched == 0)
break;
ehci->next_uframe = now_uframe;
now = ehci_readl(ehci, &ehci->regs->frame_index) &
(mod - 1);
now = ehci_read_frame_index(ehci) & (mod - 1);
if (now_uframe == now)
break;

Expand Down
17 changes: 17 additions & 0 deletions trunk/drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct ehci_hcd { /* one per controller */
unsigned fs_i_thresh:1; /* Intel iso scheduling */
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */

/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
Expand Down Expand Up @@ -747,6 +748,22 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)

/*-------------------------------------------------------------------------*/

#ifdef CONFIG_PCI

/* For working around the MosChip frame-index-register bug */
static unsigned ehci_read_frame_index(struct ehci_hcd *ehci);

#else

static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
{
return ehci_readl(ehci, &ehci->regs->frame_index);
}

#endif

/*-------------------------------------------------------------------------*/

#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
Expand Down

0 comments on commit c57dbfc

Please sign in to comment.