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 @@
*
* History:
*
* 2003/02/24 show registers in sysfs (Kevin Brosius)
*
* 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
* bandwidth accounting; if debugging, show schedules in driverfs
* 2002/07/19 fixes to management of ED and schedule state.
......@@ -105,11 +107,10 @@
* TO DO:
*
* - "disabled" and "sleeping" should be in hcd->state
* - bandwidth alloc to generic code
* - lots more testing!!
*/
#define DRIVER_VERSION "2002-Sep-17"
#define DRIVER_VERSION "2003 Feb 24"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#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)
urb_print (urb, "UNLINK", 1);
#endif
spin_lock_irqsave (&ohci->lock, flags);
if (!ohci->disabled) {
urb_priv_t *urb_priv;
......@@ -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
* some upcoming INTR_SF to call finish_unlinks()
*/
spin_lock_irqsave (&ohci->lock, flags);
urb_priv = urb->hcpriv;
if (urb_priv) {
urb_priv->state = URB_DEL;
if (urb_priv->ed->state == ED_OPER)
start_urb_unlink (ohci, urb_priv->ed);
}
spin_unlock_irqrestore (&ohci->lock, flags);
} else {
/*
* with HC dead, we won't respect hc queue pointers
* any more ... just clean up every urb's memory.
*/
finish_urb (ohci, urb, NULL);
if (urb->hcpriv) {
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, NULL);
spin_lock (&ohci->lock);
}
}
spin_unlock_irqrestore (&ohci->lock, flags);
return 0;
}
......@@ -598,7 +603,8 @@ static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
*/
spin_lock (&ohci->lock);
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)
writel (OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock);
......
......@@ -214,7 +214,7 @@ static int ohci_pci_resume (struct usb_hcd *hcd)
#ifdef DEBUG
/* the registers may look crazy here */
ohci_dump_status (ohci);
ohci_dump_status (ohci, 0, 0);
#endif
/* Re-enable bus mastering */
......
......@@ -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.
* 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);
urb_free_priv (ohci, urb->hcpriv);
urb->hcpriv = NULL;
spin_lock_irqsave (&urb->lock, flags);
spin_lock (&urb->lock);
if (likely (urb->status == -EINPROGRESS))
urb->status = 0;
spin_unlock_irqrestore (&urb->lock, flags);
spin_unlock (&urb->lock);
// what lock protects these?
switch (usb_pipetype (urb->pipe)) {
......@@ -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)
/* 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;
......@@ -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
* 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;
......@@ -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 (urb_priv->td_cnt == urb_priv->length) {
spin_unlock_irqrestore (&ohci->lock, flags);
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, regs);
spin_lock_irqsave (&ohci->lock, flags);
spin_lock (&ohci->lock);
}
/* 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