Commit e03f0410 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleed-2.5

into kroah.com:/home/greg/linux/BK/usb-2.6
parents 15902084 5c8f77da
...@@ -465,7 +465,7 @@ show_periodic (struct class_device *class_dev, char *buf) ...@@ -465,7 +465,7 @@ show_periodic (struct class_device *class_dev, char *buf)
spin_lock_irqsave (&ehci->lock, flags); spin_lock_irqsave (&ehci->lock, flags);
for (i = 0; i < ehci->periodic_size; i++) { for (i = 0; i < ehci->periodic_size; i++) {
p = ehci->pshadow [i]; p = ehci->pshadow [i];
if (!p.ptr) if (likely (!p.ptr))
continue; continue;
tag = Q_NEXT_TYPE (ehci->periodic [i]); tag = Q_NEXT_TYPE (ehci->periodic [i]);
...@@ -495,7 +495,7 @@ show_periodic (struct class_device *class_dev, char *buf) ...@@ -495,7 +495,7 @@ show_periodic (struct class_device *class_dev, char *buf)
break; break;
} }
/* show more info the first time around */ /* show more info the first time around */
if (temp == seen_count) { if (temp == seen_count && p.ptr) {
u32 scratch = cpu_to_le32p ( u32 scratch = cpu_to_le32p (
&p.qh->hw_info1); &p.qh->hw_info1);
struct ehci_qtd *qtd; struct ehci_qtd *qtd;
...@@ -528,8 +528,10 @@ show_periodic (struct class_device *class_dev, char *buf) ...@@ -528,8 +528,10 @@ show_periodic (struct class_device *class_dev, char *buf)
seen [seen_count++].qh = p.qh; seen [seen_count++].qh = p.qh;
} else } else
temp = 0; temp = 0;
tag = Q_NEXT_TYPE (p.qh->hw_next); if (p.qh) {
p = p.qh->qh_next; tag = Q_NEXT_TYPE (p.qh->hw_next);
p = p.qh->qh_next;
}
break; break;
case Q_TYPE_FSTN: case Q_TYPE_FSTN:
temp = snprintf (next, size, temp = snprintf (next, size,
......
...@@ -184,7 +184,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs) ...@@ -184,7 +184,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */ /* S-mask in a QH means it's an interrupt urb */
if ((qh->hw_info2 & cpu_to_le32 (0x00ff)) != 0) { if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */ /* ... update hc-wide periodic stats (for usbfs) */
hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--; hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
...@@ -224,7 +224,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs) ...@@ -224,7 +224,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
* Chases up to qh->hw_current. Returns number of completions called, * Chases up to qh->hw_current. Returns number of completions called,
* indicating how much "real" work we did. * indicating how much "real" work we did.
*/ */
#define HALT_BIT cpu_to_le32(QTD_STS_HALT) #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
static unsigned static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
{ {
...@@ -377,10 +377,14 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) ...@@ -377,10 +377,14 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
return count; return count;
} }
#undef HALT_BIT
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
// ... and packet size, for any kind of endpoint descriptor
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
/* /*
* reverse of qh_urb_transaction: free a list of TDs. * reverse of qh_urb_transaction: free a list of TDs.
* used for cleanup after errors, before HC sees an URB's TDs. * used for cleanup after errors, before HC sees an URB's TDs.
...@@ -461,7 +465,7 @@ qh_urb_transaction ( ...@@ -461,7 +465,7 @@ qh_urb_transaction (
token |= (1 /* "in" */ << 8); token |= (1 /* "in" */ << 8);
/* else it's already initted to "out" pid (0 << 8) */ /* else it's already initted to "out" pid (0 << 8) */
maxpacket = usb_maxpacket (urb->dev, urb->pipe, !is_input) & 0x03ff; maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
/* /*
* buffer gets wrapped in one or more qtds; * buffer gets wrapped in one or more qtds;
...@@ -564,11 +568,6 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh) ...@@ -564,11 +568,6 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh)
// That'd mean updating how usbcore talks to HCDs. (2.5?) // That'd mean updating how usbcore talks to HCDs. (2.5?)
// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
// ... and packet size, for any kind of endpoint descriptor
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x03ff)
/* /*
* Each QH holds a qtd list; a QH is used for everything except iso. * Each QH holds a qtd list; a QH is used for everything except iso.
* *
...@@ -728,7 +727,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -728,7 +727,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
} }
} }
qh->hw_token &= ~__constant_cpu_to_le32 (QTD_STS_HALT); qh->hw_token &= ~HALT_BIT;
/* splice right after start */ /* splice right after start */
qh->qh_next = head->qh_next; qh->qh_next = head->qh_next;
...@@ -744,6 +743,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ...@@ -744,6 +743,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#define QH_ADDR_MASK __constant_le32_to_cpu(0x7f)
/* /*
* For control/bulk/interrupt, return QH with these TDs appended. * For control/bulk/interrupt, return QH with these TDs appended.
* Allocates and initializes the QH if necessary. * Allocates and initializes the QH if necessary.
...@@ -778,12 +779,13 @@ static struct ehci_qh *qh_append_tds ( ...@@ -778,12 +779,13 @@ static struct ehci_qh *qh_append_tds (
/* control qh may need patching after enumeration */ /* control qh may need patching after enumeration */
if (unlikely (epnum == 0)) { if (unlikely (epnum == 0)) {
/* set_address changes the address */ /* set_address changes the address */
if (le32_to_cpu (qh->hw_info1 & 0x7f) == 0) if ((qh->hw_info1 & QH_ADDR_MASK) == 0)
qh->hw_info1 |= cpu_to_le32 ( qh->hw_info1 |= cpu_to_le32 (
usb_pipedevice (urb->pipe)); usb_pipedevice (urb->pipe));
/* for full speed, ep0 maxpacket can grow */ /* for full speed, ep0 maxpacket can grow */
else if (!(qh->hw_info1 & cpu_to_le32 (0x3 << 12))) { else if (!(qh->hw_info1
& __constant_cpu_to_le32 (0x3 << 12))) {
u32 info, max; u32 info, max;
info = le32_to_cpu (qh->hw_info1); info = le32_to_cpu (qh->hw_info1);
...@@ -797,7 +799,7 @@ static struct ehci_qh *qh_append_tds ( ...@@ -797,7 +799,7 @@ static struct ehci_qh *qh_append_tds (
/* usb_reset_device() briefly reverts to address 0 */ /* usb_reset_device() briefly reverts to address 0 */
if (usb_pipedevice (urb->pipe) == 0) if (usb_pipedevice (urb->pipe) == 0)
qh->hw_info1 &= cpu_to_le32(~0x7f); qh->hw_info1 &= ~QH_ADDR_MASK;
} }
/* usb_clear_halt() means qh data toggle gets reset */ /* usb_clear_halt() means qh data toggle gets reset */
...@@ -833,7 +835,7 @@ static struct ehci_qh *qh_append_tds ( ...@@ -833,7 +835,7 @@ static struct ehci_qh *qh_append_tds (
* HC is allowed to fetch the old dummy (4.10.2). * HC is allowed to fetch the old dummy (4.10.2).
*/ */
token = qtd->hw_token; token = qtd->hw_token;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); qtd->hw_token = HALT_BIT;
wmb (); wmb ();
dummy = qh->dummy; dummy = qh->dummy;
......
...@@ -325,6 +325,7 @@ union ehci_shadow { ...@@ -325,6 +325,7 @@ union ehci_shadow {
struct ehci_itd *itd; /* Q_TYPE_ITD */ struct ehci_itd *itd; /* Q_TYPE_ITD */
struct ehci_sitd *sitd; /* Q_TYPE_SITD */ struct ehci_sitd *sitd; /* Q_TYPE_SITD */
struct ehci_fstn *fstn; /* Q_TYPE_FSTN */ struct ehci_fstn *fstn; /* Q_TYPE_FSTN */
u32 *hw_next; /* (all types) */
void *ptr; void *ptr;
}; };
...@@ -469,27 +470,12 @@ struct ehci_fstn { ...@@ -469,27 +470,12 @@ struct ehci_fstn {
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb)
#define STUB_DEBUG_FILES
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_new_device (hcd_to_bus (hcd)->root_hub);
}
#else /* LINUX_VERSION_CODE */
#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags) #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
#ifndef DEBUG #ifndef DEBUG
#define STUB_DEBUG_FILES #define STUB_DEBUG_FILES
#endif /* DEBUG */ #endif /* DEBUG */
#endif /* LINUX_VERSION_CODE */
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#endif /* __LINUX_EHCI_HCD_H */ #endif /* __LINUX_EHCI_HCD_H */
...@@ -102,14 +102,8 @@ ...@@ -102,14 +102,8 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
/*
* TO DO:
*
* - "disabled" and "sleeping" should be in hcd->state
* - lots more testing!!
*/
#define DRIVER_VERSION "2003 Feb 24" #define DRIVER_VERSION "2003 Oct 13"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
...@@ -131,7 +125,6 @@ static const char hcd_name [] = "ohci_hcd"; ...@@ -131,7 +125,6 @@ static const char hcd_name [] = "ohci_hcd";
static inline void disable (struct ohci_hcd *ohci) static inline void disable (struct ohci_hcd *ohci)
{ {
ohci->disabled = 1;
ohci->hcd.state = USB_STATE_HALT; ohci->hcd.state = USB_STATE_HALT;
} }
...@@ -222,7 +215,7 @@ static int ohci_urb_enqueue ( ...@@ -222,7 +215,7 @@ static int ohci_urb_enqueue (
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */ /* don't submit to a dead HC */
if (ohci->disabled || ohci->sleeping) { if (!HCD_IS_RUNNING(ohci->hcd.state)) {
retval = -ENODEV; retval = -ENODEV;
goto fail; goto fail;
} }
...@@ -278,7 +271,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -278,7 +271,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
#endif #endif
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irqsave (&ohci->lock, flags);
if (!ohci->disabled) { if (HCD_IS_RUNNING(ohci->hcd.state)) {
urb_priv_t *urb_priv; urb_priv_t *urb_priv;
/* Unless an IRQ completed the unlink while it was being /* Unless an IRQ completed the unlink while it was being
...@@ -287,7 +280,6 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -287,7 +280,6 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
*/ */
urb_priv = urb->hcpriv; urb_priv = urb->hcpriv;
if (urb_priv) { if (urb_priv) {
urb_priv->state = URB_DEL;
if (urb_priv->ed->state == ED_OPER) if (urb_priv->ed->state == ED_OPER)
start_urb_unlink (ohci, urb_priv->ed); start_urb_unlink (ohci, urb_priv->ed);
} }
...@@ -334,7 +326,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep) ...@@ -334,7 +326,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
if (!ed) if (!ed)
goto done; goto done;
if (!HCD_IS_RUNNING (ohci->hcd.state) || ohci->disabled) if (!HCD_IS_RUNNING (ohci->hcd.state))
ed->state = ED_IDLE; ed->state = ED_IDLE;
switch (ed->state) { switch (ed->state) {
case ED_UNLINK: /* wait for hw to finish? */ case ED_UNLINK: /* wait for hw to finish? */
...@@ -355,9 +347,9 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep) ...@@ -355,9 +347,9 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
/* caller was supposed to have unlinked any requests; /* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed. * that's not our job. can't recover; must leak ed.
*/ */
ohci_err (ohci, "ed %p (#%d) state %d%s\n", ohci_err (ohci, "leak ed %p (#%d) state %d%s\n",
ed, epnum, ed->state, ed, epnum, ed->state,
list_empty (&ed->td_list) ? "" : "(has tds)"); list_empty (&ed->td_list) ? "" : " (has tds)");
td_free (ohci, ed->dummy); td_free (ohci, ed->dummy);
break; break;
} }
...@@ -466,8 +458,7 @@ static int hc_start (struct ohci_hcd *ohci) ...@@ -466,8 +458,7 @@ static int hc_start (struct ohci_hcd *ohci)
struct usb_bus *bus; struct usb_bus *bus;
spin_lock_init (&ohci->lock); spin_lock_init (&ohci->lock);
ohci->disabled = 1; disable (ohci);
ohci->sleeping = 0;
/* Tell the controller where the control and bulk lists are /* Tell the controller where the control and bulk lists are
* The lists are empty now. */ * The lists are empty now. */
...@@ -496,8 +487,8 @@ static int hc_start (struct ohci_hcd *ohci) ...@@ -496,8 +487,8 @@ static int hc_start (struct ohci_hcd *ohci)
/* start controller operations */ /* start controller operations */
ohci->hc_control &= OHCI_CTRL_RWC; ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
ohci->hcd.state = USB_STATE_RUNNING;
/* Choose the interrupts we care about now, others later on demand */ /* Choose the interrupts we care about now, others later on demand */
mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH; mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
...@@ -586,9 +577,11 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -586,9 +577,11 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
} }
if (ints & OHCI_INTR_WDH) { if (ints & OHCI_INTR_WDH) {
writel (OHCI_INTR_WDH, &regs->intrdisable); if (HCD_IS_RUNNING(hcd->state))
writel (OHCI_INTR_WDH, &regs->intrdisable);
dl_done_list (ohci, dl_reverse_done_list (ohci), ptregs); dl_done_list (ohci, dl_reverse_done_list (ohci), ptregs);
writel (OHCI_INTR_WDH, &regs->intrenable); if (HCD_IS_RUNNING(hcd->state))
writel (OHCI_INTR_WDH, &regs->intrenable);
} }
/* could track INTR_SO to reduce available PCI/... bandwidth */ /* could track INTR_SO to reduce available PCI/... bandwidth */
...@@ -600,14 +593,17 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -600,14 +593,17 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
if (ohci->ed_rm_list) if (ohci->ed_rm_list)
finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no), finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no),
ptregs); ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list) if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
&& HCD_IS_RUNNING(ohci->hcd.state))
writel (OHCI_INTR_SF, &regs->intrdisable); writel (OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock); spin_unlock (&ohci->lock);
writel (ints, &regs->intrstatus); if (HCD_IS_RUNNING(ohci->hcd.state)) {
writel (OHCI_INTR_MIE, &regs->intrenable); writel (ints, &regs->intrstatus);
// flush those pci writes writel (OHCI_INTR_MIE, &regs->intrenable);
(void) readl (&ohci->regs->control); // flush those pci writes
(void) readl (&ohci->regs->control);
}
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -616,13 +612,12 @@ static void ohci_stop (struct usb_hcd *hcd) ...@@ -616,13 +612,12 @@ static void ohci_stop (struct usb_hcd *hcd)
{ {
struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
ohci_dbg (ohci, "stop %s controller%s\n", ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
ohci->disabled ? " (disabled)" : "" ohci->hcd.state);
);
ohci_dump (ohci, 1); ohci_dump (ohci, 1);
if (!ohci->disabled) if (HCD_IS_RUNNING(ohci->hcd.state))
hc_reset (ohci); hc_reset (ohci);
remove_debug_files (ohci); remove_debug_files (ohci);
...@@ -649,8 +644,7 @@ static int hc_restart (struct ohci_hcd *ohci) ...@@ -649,8 +644,7 @@ static int hc_restart (struct ohci_hcd *ohci)
int temp; int temp;
int i; int i;
ohci->disabled = 1; disable (ohci);
ohci->sleeping = 0;
if (hcd_to_bus (&ohci->hcd)->root_hub) if (hcd_to_bus (&ohci->hcd)->root_hub)
usb_disconnect (&hcd_to_bus (&ohci->hcd)->root_hub); usb_disconnect (&hcd_to_bus (&ohci->hcd)->root_hub);
......
...@@ -73,7 +73,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) ...@@ -73,7 +73,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
ports = roothub_a (ohci) & RH_A_NDP; ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) { if (ports > MAX_ROOT_PORTS) {
if (ohci->disabled) if (!HCD_IS_RUNNING(ohci->hcd.state))
return -ESHUTDOWN; return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
ports, readl (&ohci->regs->roothub.a) & RH_A_NDP); ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
......
...@@ -117,7 +117,6 @@ ohci_pci_start (struct usb_hcd *hcd) ...@@ -117,7 +117,6 @@ ohci_pci_start (struct usb_hcd *hcd)
static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state) static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
{ {
struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
u16 cmd; u16 cmd;
u32 tmp; u32 tmp;
...@@ -129,16 +128,15 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state) ...@@ -129,16 +128,15 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
/* act as if usb suspend can always be used */ /* act as if usb suspend can always be used */
ohci_dbg (ohci, "suspend to %d\n", state); ohci_dbg (ohci, "suspend to %d\n", state);
ohci->sleeping = 1;
/* First stop processing */ /* First stop processing */
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irq (&ohci->lock);
ohci->hc_control &= ohci->hc_control &=
~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE); ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus); writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
(void) readl (&ohci->regs->intrstatus); (void) readl (&ohci->regs->intrstatus);
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irq (&ohci->lock);
/* Wait a frame or two */ /* Wait a frame or two */
mdelay (1); mdelay (1);
...@@ -156,10 +154,14 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state) ...@@ -156,10 +154,14 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
&ohci->regs->intrenable); &ohci->regs->intrenable);
/* Suspend chip and let things settle down a bit */ /* Suspend chip and let things settle down a bit */
spin_lock_irq (&ohci->lock);
ohci->hc_control = OHCI_USB_SUSPEND; ohci->hc_control = OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
mdelay (500); /* No schedule here ! */ spin_unlock_irq (&ohci->lock);
set_current_state (TASK_UNINTERRUPTIBLE);
schedule_timeout (HZ/2);
tmp = readl (&ohci->regs->control) | OHCI_CTRL_HCFS; tmp = readl (&ohci->regs->control) | OHCI_CTRL_HCFS;
switch (tmp) { switch (tmp) {
...@@ -199,7 +201,6 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -199,7 +201,6 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int temp; int temp;
int retval = 0; int retval = 0;
unsigned long flags;
#ifdef CONFIG_PMAC_PBOOK #ifdef CONFIG_PMAC_PBOOK
{ {
...@@ -226,6 +227,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -226,6 +227,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
switch (temp) { switch (temp) {
case OHCI_USB_RESET: // lost power case OHCI_USB_RESET: // lost power
restart:
ohci_info (ohci, "USB restart\n"); ohci_info (ohci, "USB restart\n");
retval = hc_restart (ohci); retval = hc_restart (ohci);
break; break;
...@@ -235,31 +237,28 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -235,31 +237,28 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
ohci_info (ohci, "USB continue from %s wakeup\n", ohci_info (ohci, "USB continue from %s wakeup\n",
(temp == OHCI_USB_SUSPEND) (temp == OHCI_USB_SUSPEND)
? "host" : "remote"); ? "host" : "remote");
/* we "should" only need RESUME if we're SUSPENDed ... */
ohci->hc_control = OHCI_USB_RESUME; ohci->hc_control = OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control); writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
mdelay (20); /* no schedule here ! */ /* Some controllers (lucent) need extra-long delays */
/* Some controllers (lucent) need a longer delay here */ mdelay (35); /* no schedule here ! */
mdelay (15);
temp = readl (&ohci->regs->control); temp = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS; temp = ohci->hc_control & OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) { if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n"); ohci_err (ohci, "controller won't resume\n");
ohci->disabled = 1; /* maybe we can reset */
retval = -EIO; goto restart;
break;
} }
/* Some chips likes being resumed first */ /* Then re-enable operations */
writel (OHCI_USB_OPER, &ohci->regs->control); writel (OHCI_USB_OPER, &ohci->regs->control);
(void) readl (&ohci->regs->control); (void) readl (&ohci->regs->control);
mdelay (3); mdelay (3);
/* Then re-enable operations */ spin_lock_irq (&ohci->lock);
spin_lock_irqsave (&ohci->lock, flags);
ohci->disabled = 0;
ohci->sleeping = 0;
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (!ohci->ed_rm_list) { if (!ohci->ed_rm_list) {
if (ohci->ed_controltail) if (ohci->ed_controltail)
...@@ -274,25 +273,22 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -274,25 +273,22 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
writel (OHCI_INTR_SF, &ohci->regs->intrstatus); writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable); writel (OHCI_INTR_SF, &ohci->regs->intrenable);
/* Check for a pending done list */
writel (OHCI_INTR_WDH, &ohci->regs->intrdisable); writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
(void) readl (&ohci->regs->intrdisable); (void) readl (&ohci->regs->intrdisable);
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irq (&ohci->lock);
#ifdef CONFIG_PMAC_PBOOK #ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac) if (_machine == _MACH_Pmac)
enable_irq (hcd->pdev->irq); enable_irq (hcd->pdev->irq);
#endif #endif
/* Check for a pending done list */
if (ohci->hcca->done_head) if (ohci->hcca->done_head)
dl_done_list (ohci, dl_reverse_done_list (ohci), NULL); dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
writel (OHCI_INTR_WDH, &ohci->regs->intrenable); writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
/* assume there are TDs on the bulk and control lists */ /* assume there are TDs on the bulk and control lists */
writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus); writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
// ohci_dump_status (ohci);
ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
ohci->sleeping, ohci->disabled);
break; break;
default: default:
......
...@@ -449,7 +449,7 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed) ...@@ -449,7 +449,7 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_rm_list = ed; ohci->ed_rm_list = ed;
/* enable SOF interrupt */ /* enable SOF interrupt */
if (!ohci->sleeping) { if (HCD_IS_RUNNING (ohci->hcd.state)) {
writel (OHCI_INTR_SF, &ohci->regs->intrstatus); writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable); writel (OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those pci writes // flush those pci writes
...@@ -794,7 +794,16 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) ...@@ -794,7 +794,16 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
* looks odd ... that doesn't include protocol stalls * looks odd ... that doesn't include protocol stalls
* (or maybe some other things) * (or maybe some other things)
*/ */
if (cc != TD_CC_STALL || !usb_pipecontrol (urb->pipe)) switch (cc) {
case TD_DATAUNDERRUN:
if ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)
break;
/* fallthrough */
case TD_CC_STALL:
if (usb_pipecontrol (urb->pipe))
break;
/* fallthrough */
default:
ohci_dbg (ohci, ohci_dbg (ohci,
"urb %p path %s ep%d%s %08x cc %d --> status %d\n", "urb %p path %s ep%d%s %08x cc %d --> status %d\n",
urb, urb->dev->devpath, urb, urb->dev->devpath,
...@@ -802,6 +811,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) ...@@ -802,6 +811,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev)
usb_pipein (urb->pipe) ? "in" : "out", usb_pipein (urb->pipe) ? "in" : "out",
le32_to_cpu (td->hwINFO), le32_to_cpu (td->hwINFO),
cc, cc_to_error [cc]); cc, cc_to_error [cc]);
}
return rev; return rev;
} }
...@@ -871,7 +881,8 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) ...@@ -871,7 +881,8 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
/* only take off EDs that the HC isn't using, accounting for /* only take off EDs that the HC isn't using, accounting for
* frame counter wraps. * frame counter wraps.
*/ */
if (tick_before (tick, ed->tick) && !ohci->disabled) { if (tick_before (tick, ed->tick)
&& HCD_IS_RUNNING(ohci->hcd.state)) {
last = &ed->ed_next; last = &ed->ed_next;
continue; continue;
} }
...@@ -901,7 +912,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) ...@@ -901,7 +912,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
urb = td->urb; urb = td->urb;
urb_priv = td->urb->hcpriv; urb_priv = td->urb->hcpriv;
if (urb_priv->state != URB_DEL) { if (urb->status == -EINPROGRESS) {
prev = &td->hwNextTD; prev = &td->hwNextTD;
continue; continue;
} }
...@@ -938,7 +949,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) ...@@ -938,7 +949,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
/* but if there's work queued, reschedule */ /* but if there's work queued, reschedule */
if (!list_empty (&ed->td_list)) { if (!list_empty (&ed->td_list)) {
if (!ohci->disabled && !ohci->sleeping) if (HCD_IS_RUNNING(ohci->hcd.state))
ed_schedule (ohci, ed); ed_schedule (ohci, ed);
} }
...@@ -947,7 +958,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) ...@@ -947,7 +958,7 @@ finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
} }
/* maybe reenable control and bulk lists */ /* maybe reenable control and bulk lists */
if (!ohci->disabled && !ohci->ed_rm_list) { if (HCD_IS_RUNNING(ohci->hcd.state) && !ohci->ed_rm_list) {
u32 command = 0, control = 0; u32 command = 0, control = 0;
if (ohci->ed_controltail) { if (ohci->ed_controltail) {
......
...@@ -314,13 +314,10 @@ typedef struct urb_priv { ...@@ -314,13 +314,10 @@ typedef struct urb_priv {
struct ed *ed; struct ed *ed;
__u16 length; // # tds in this request __u16 length; // # tds in this request
__u16 td_cnt; // tds already serviced __u16 td_cnt; // tds already serviced
int state;
struct td *td [0]; // all TDs in this request struct td *td [0]; // all TDs in this request
} urb_priv_t; } urb_priv_t;
#define URB_DEL 1
#define TD_HASH_SIZE 64 /* power'o'two */ #define TD_HASH_SIZE 64 /* power'o'two */
// sizeof (struct td) ~= 64 == 2^6 ... // sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
...@@ -365,8 +362,6 @@ struct ohci_hcd { ...@@ -365,8 +362,6 @@ struct ohci_hcd {
/* /*
* driver state * driver state
*/ */
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
int load [NUM_INTS]; int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */ u32 hc_control; /* copy of hc control reg */
......
...@@ -28,6 +28,7 @@ comment "Input core support is needed for USB HID input layer or HIDBP support" ...@@ -28,6 +28,7 @@ comment "Input core support is needed for USB HID input layer or HIDBP support"
config USB_HIDINPUT config USB_HIDINPUT
bool "HID input layer support" bool "HID input layer support"
default y
depends on INPUT && USB_HID depends on INPUT && USB_HID
help help
Say Y here if you want to use a USB keyboard, mouse or joystick, Say Y here if you want to use a USB keyboard, mouse or joystick,
......
...@@ -182,14 +182,14 @@ struct keyspan_usa90_portStatusMessage ...@@ -182,14 +182,14 @@ struct keyspan_usa90_portStatusMessage
// MSR bits // MSR bits
#define MSR_dCTS 0x01 // CTS has changed since last report #define USA_MSR_dCTS 0x01 // CTS has changed since last report
#define MSR_dDSR 0x02 #define USA_MSR_dDSR 0x02
#define MSR_dRI 0x04 #define USA_MSR_dRI 0x04
#define MSR_dDCD 0x08 #define USA_MSR_dDCD 0x08
#define MSR_CTS 0x10 // current state of CTS #define USA_MSR_CTS 0x10 // current state of CTS
#define MSR_DSR 0x20 #define USA_MSR_DSR 0x20
#define MSR_RI 0x40 #define USA_USA_MSR_RI 0x40
#define MSR_DCD 0x80 #define MSR_DCD 0x80
// ie: the maximum length of an endpoint buffer // ie: the maximum length of an endpoint buffer
......
...@@ -778,9 +778,6 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i ...@@ -778,9 +778,6 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i
serial->dev->actconfig->desc.bConfigurationValue); serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV; return -ENODEV;
} }
dbg("%s - reset config", __FUNCTION__);
retval = usb_reset_configuration (serial->dev);
if (id->driver_info) { if (id->driver_info) {
startup = (void *)id->driver_info; startup = (void *)id->driver_info;
......
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