Commit 328a5259 authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB ohci: "registers" sysfs file

This is a slightly cleaned up version of Kevin's patch to
add a "registers" sysfs debug file.  Minor style and whitespace
fixups, prints the other register, resolved config/build
issues (minor).

It also has two minor tweaks: a fix for a potential assertion
violation on a "dead-hc" cleanup path (rare), and wasting less
time blocking irqs when they're already blocked.
parent 72344df4
This diff is collapsed.
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* *
* History: * History:
* *
* 2003/02/24 show registers in sysfs (Kevin Brosius)
*
* 2002/09/03 get rid of ed hashtables, rework periodic scheduling and * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
* bandwidth accounting; if debugging, show schedules in driverfs * bandwidth accounting; if debugging, show schedules in driverfs
* 2002/07/19 fixes to management of ED and schedule state. * 2002/07/19 fixes to management of ED and schedule state.
...@@ -105,11 +107,10 @@ ...@@ -105,11 +107,10 @@
* TO DO: * TO DO:
* *
* - "disabled" and "sleeping" should be in hcd->state * - "disabled" and "sleeping" should be in hcd->state
* - bandwidth alloc to generic code
* - lots more testing!! * - lots more testing!!
*/ */
#define DRIVER_VERSION "2002-Sep-17" #define DRIVER_VERSION "2003 Feb 24"
#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"
...@@ -277,6 +278,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -277,6 +278,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
urb_print (urb, "UNLINK", 1); urb_print (urb, "UNLINK", 1);
#endif #endif
spin_lock_irqsave (&ohci->lock, flags);
if (!ohci->disabled) { if (!ohci->disabled) {
urb_priv_t *urb_priv; urb_priv_t *urb_priv;
...@@ -284,21 +286,24 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ...@@ -284,21 +286,24 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
* handed to us, flag it for unlink and giveback, and force * handed to us, flag it for unlink and giveback, and force
* some upcoming INTR_SF to call finish_unlinks() * some upcoming INTR_SF to call finish_unlinks()
*/ */
spin_lock_irqsave (&ohci->lock, flags);
urb_priv = urb->hcpriv; urb_priv = urb->hcpriv;
if (urb_priv) { if (urb_priv) {
urb_priv->state = URB_DEL; 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);
} }
spin_unlock_irqrestore (&ohci->lock, flags);
} else { } else {
/* /*
* with HC dead, we won't respect hc queue pointers * with HC dead, we won't respect hc queue pointers
* any more ... just clean up every urb's memory. * any more ... just clean up every urb's memory.
*/ */
if (urb->hcpriv) {
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, NULL); finish_urb (ohci, urb, NULL);
spin_lock (&ohci->lock);
} }
}
spin_unlock_irqrestore (&ohci->lock, flags);
return 0; return 0;
} }
...@@ -598,7 +603,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) ...@@ -598,7 +603,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
*/ */
spin_lock (&ohci->lock); spin_lock (&ohci->lock);
if (ohci->ed_rm_list) if (ohci->ed_rm_list)
finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no), ptregs); finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no),
ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list) if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list)
writel (OHCI_INTR_SF, &regs->intrdisable); writel (OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock); spin_unlock (&ohci->lock);
......
...@@ -214,7 +214,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd) ...@@ -214,7 +214,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
#ifdef DEBUG #ifdef DEBUG
/* the registers may look crazy here */ /* the registers may look crazy here */
ohci_dump_status (ohci); ohci_dump_status (ohci, 0, 0);
#endif #endif
/* Re-enable bus mastering */ /* Re-enable bus mastering */
......
...@@ -30,21 +30,20 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) ...@@ -30,21 +30,20 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
/* /*
* URB goes back to driver, and isn't reissued. * URB goes back to driver, and isn't reissued.
* It's completely gone from HC data structures. * It's completely gone from HC data structures.
* PRECONDITION: no locks held (Giveback can call into HCD.) * PRECONDITION: no locks held, irqs blocked (Giveback can call into HCD.)
*/ */
static void finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) static void
finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
{ {
unsigned long flags;
// ASSERT (urb->hcpriv != 0); // ASSERT (urb->hcpriv != 0);
urb_free_priv (ohci, urb->hcpriv); urb_free_priv (ohci, urb->hcpriv);
urb->hcpriv = NULL; urb->hcpriv = NULL;
spin_lock_irqsave (&urb->lock, flags); spin_lock (&urb->lock);
if (likely (urb->status == -EINPROGRESS)) if (likely (urb->status == -EINPROGRESS))
urb->status = 0; urb->status = 0;
spin_unlock_irqrestore (&urb->lock, flags); spin_unlock (&urb->lock);
// what lock protects these? // what lock protects these?
switch (usb_pipetype (urb->pipe)) { switch (usb_pipetype (urb->pipe)) {
...@@ -850,7 +849,8 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) ...@@ -850,7 +849,8 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
#define tick_before(t1,t2) ((((s16)(t1))-((s16)(t2))) < 0) #define tick_before(t1,t2) ((((s16)(t1))-((s16)(t2))) < 0)
/* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */
static void finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) static void
finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
{ {
struct ed *ed, **last; struct ed *ed, **last;
...@@ -978,7 +978,8 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *reg ...@@ -978,7 +978,8 @@ static void finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *reg
* path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of
* scanning the (re-reversed) donelist as this does. * scanning the (re-reversed) donelist as this does.
*/ */
static void dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs) static void
dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
...@@ -995,9 +996,9 @@ static void dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs * ...@@ -995,9 +996,9 @@ static void dl_done_list (struct ohci_hcd *ohci, struct td *td, struct pt_regs *
/* If all this urb's TDs are done, call complete() */ /* If all this urb's TDs are done, call complete() */
if (urb_priv->td_cnt == urb_priv->length) { if (urb_priv->td_cnt == urb_priv->length) {
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock (&ohci->lock);
finish_urb (ohci, urb, regs); finish_urb (ohci, urb, regs);
spin_lock_irqsave (&ohci->lock, flags); spin_lock (&ohci->lock);
} }
/* clean schedule: unlink EDs that are no longer busy */ /* clean schedule: unlink EDs that are no longer busy */
......
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