OHCI: remove uses of hcd->state
authorAlan Stern <stern@rowland.harvard.edu>
Thu, 17 Nov 2011 21:41:56 +0000 (16:41 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 18 Nov 2011 18:51:00 +0000 (10:51 -0800)
This patch (as1500) removes all uses of the objectionable hcd->state
variable from the ohci-hcd family of drivers.  It is replaced by a
private ohci->rh_state field, just as in uhci-hcd and ehci-hcd.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
14 files changed:
drivers/usb/host/ohci-au1xxx.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-ep93xx.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci-sh.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci-spear.c
drivers/usb/host/ohci-tmio.c
drivers/usb/host/ohci.h

index 9b66df8..40d886a 100644 (file)
@@ -173,12 +173,9 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
         * mark HW unaccessible, bail out if RH has been resumed. Use
         * the spinlock to properly synchronize with possible pending
         * RH suspend or resume activity.
-        *
-        * This is still racy as hcd->state is manipulated outside of
-        * any locks =P But that will be a different fix.
         */
        spin_lock_irqsave(&ohci->lock, flags);
-       if (hcd->state != HC_STATE_SUSPENDED) {
+       if (ohci->rh_state != OHCI_RH_SUSPENDED) {
                rc = -EINVAL;
                goto bail;
        }
index d7d3449..5179fcd 100644 (file)
@@ -127,6 +127,19 @@ static char *hcfs2string (int state)
        return "?";
 }
 
+static const char *rh_state_string(struct ohci_hcd *ohci)
+{
+       switch (ohci->rh_state) {
+       case OHCI_RH_HALTED:
+               return "halted";
+       case OHCI_RH_SUSPENDED:
+               return "suspended";
+       case OHCI_RH_RUNNING:
+               return "running";
+       }
+       return "?";
+}
+
 // dump control and status registers
 static void
 ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
@@ -136,9 +149,10 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
 
        temp = ohci_readl (controller, &regs->revision) & 0xff;
        ohci_dbg_sw (controller, next, size,
-               "OHCI %d.%d, %s legacy support registers\n",
+               "OHCI %d.%d, %s legacy support registers, rh state %s\n",
                0x03 & (temp >> 4), (temp & 0x0f),
-               (temp & 0x0100) ? "with" : "NO");
+               (temp & 0x0100) ? "with" : "NO",
+               rh_state_string(controller));
 
        temp = ohci_readl (controller, &regs->control);
        ohci_dbg_sw (controller, next, size,
index dc45d48..3d63574 100644 (file)
@@ -179,8 +179,6 @@ static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_
        ohci->next_statechange = jiffies;
 
        ep93xx_stop_hc(&pdev->dev);
-       hcd->state = HC_STATE_SUSPENDED;
-
        return 0;
 }
 
index 34efd47..03c4631 100644 (file)
@@ -209,7 +209,7 @@ static int ohci_urb_enqueue (
                retval = -ENODEV;
                goto fail;
        }
-       if (!HC_IS_RUNNING(hcd->state)) {
+       if (ohci->rh_state != OHCI_RH_RUNNING) {
                retval = -ENODEV;
                goto fail;
        }
@@ -274,7 +274,7 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        rc = usb_hcd_check_unlink_urb(hcd, urb, status);
        if (rc) {
                ;       /* Do nothing */
-       } else if (HC_IS_RUNNING(hcd->state)) {
+       } else if (ohci->rh_state == OHCI_RH_RUNNING) {
                urb_priv_t  *urb_priv;
 
                /* Unless an IRQ completed the unlink while it was being
@@ -321,7 +321,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 rescan:
        spin_lock_irqsave (&ohci->lock, flags);
 
-       if (!HC_IS_RUNNING (hcd->state)) {
+       if (ohci->rh_state != OHCI_RH_RUNNING) {
 sanitize:
                ed->state = ED_IDLE;
                if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT)
@@ -377,6 +377,7 @@ static void ohci_usb_reset (struct ohci_hcd *ohci)
        ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
        ohci->hc_control &= OHCI_CTRL_RWC;
        ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+       ohci->rh_state = OHCI_RH_HALTED;
 }
 
 /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and
@@ -503,7 +504,7 @@ static int ohci_init (struct ohci_hcd *ohci)
        if (distrust_firmware)
                ohci->flags |= OHCI_QUIRK_HUB_POWER;
 
-       disable (ohci);
+       ohci->rh_state = OHCI_RH_HALTED;
        ohci->regs = hcd->regs;
 
        /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
@@ -578,7 +579,7 @@ static int ohci_run (struct ohci_hcd *ohci)
        int                     first = ohci->fminterval == 0;
        struct usb_hcd          *hcd = ohci_to_hcd(ohci);
 
-       disable (ohci);
+       ohci->rh_state = OHCI_RH_HALTED;
 
        /* boot firmware should have set this up (5.1.1.3.1) */
        if (first) {
@@ -691,7 +692,7 @@ retry:
        ohci->hc_control &= OHCI_CTRL_RWC;
        ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
        ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-       hcd->state = HC_STATE_RUNNING;
+       ohci->rh_state = OHCI_RH_RUNNING;
 
        /* wake on ConnectStatusChange, matching external hubs */
        ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
@@ -728,7 +729,6 @@ retry:
 
        // POTPGT delay is bits 24-31, in 2 ms units.
        mdelay ((val >> 23) & 0x1fe);
-       hcd->state = HC_STATE_RUNNING;
 
        if (quirk_zfmicro(ohci)) {
                /* Create timer to watch for bad queue state on ZF Micro */
@@ -764,7 +764,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
         * of dead, unclocked, or unplugged (CardBus...) devices
         */
        if (ints == ~(u32)0) {
-               disable (ohci);
+               ohci->rh_state = OHCI_RH_HALTED;
                ohci_dbg (ohci, "device removed!\n");
                usb_hc_died(hcd);
                return IRQ_HANDLED;
@@ -774,7 +774,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
        ints &= ohci_readl(ohci, &regs->intrenable);
 
        /* interrupt for some other device? */
-       if (ints == 0 || unlikely(hcd->state == HC_STATE_HALT))
+       if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED))
                return IRQ_NOTMINE;
 
        if (ints & OHCI_INTR_UE) {
@@ -789,8 +789,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
 
                        schedule_work (&ohci->nec_work);
                } else {
-                       disable (ohci);
                        ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
+                       ohci->rh_state = OHCI_RH_HALTED;
                        usb_hc_died(hcd);
                }
 
@@ -874,11 +874,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
        if ((ints & OHCI_INTR_SF) != 0
                        && !ohci->ed_rm_list
                        && !ohci->ed_to_check
-                       && HC_IS_RUNNING(hcd->state))
+                       && ohci->rh_state == OHCI_RH_RUNNING)
                ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
        spin_unlock (&ohci->lock);
 
-       if (HC_IS_RUNNING(hcd->state)) {
+       if (ohci->rh_state == OHCI_RH_RUNNING) {
                ohci_writel (ohci, ints, &regs->intrstatus);
                ohci_writel (ohci, OHCI_INTR_MIE, &regs->intrenable);
                // flush those writes
@@ -932,7 +932,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
        struct urb_priv *priv;
 
        spin_lock_irq(&ohci->lock);
-       disable (ohci);
+       ohci->rh_state = OHCI_RH_HALTED;
 
        /* Recycle any "live" eds/tds (and urbs). */
        if (!list_empty (&ohci->pending))
index 2f00040..836772d 100644 (file)
@@ -111,6 +111,7 @@ __acquires(ohci->lock)
        if (!autostop) {
                ohci->next_statechange = jiffies + msecs_to_jiffies (5);
                ohci->autostop = 0;
+               ohci->rh_state = OHCI_RH_SUSPENDED;
        }
 
 done:
@@ -140,7 +141,7 @@ __acquires(ohci->lock)
 
        if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
                /* this can happen after resuming a swsusp snapshot */
-               if (hcd->state == HC_STATE_RESUMING) {
+               if (ohci->rh_state != OHCI_RH_RUNNING) {
                        ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
                                        ohci->hc_control);
                        status = -EBUSY;
@@ -274,6 +275,7 @@ skip_resume:
                (void) ohci_readl (ohci, &ohci->regs->control);
        }
 
+       ohci->rh_state = OHCI_RH_RUNNING;
        return 0;
 }
 
@@ -336,11 +338,8 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)
        /* If needed, reinitialize and suspend the root hub */
        if (need_reinit) {
                spin_lock_irq(&ohci->lock);
-               hcd->state = HC_STATE_RESUMING;
                ohci_rh_resume(ohci);
-               hcd->state = HC_STATE_QUIESCING;
                ohci_rh_suspend(ohci, 0);
-               hcd->state = HC_STATE_SUSPENDED;
                spin_unlock_irq(&ohci->lock);
        }
 
index e4b8782..db39686 100644 (file)
@@ -516,7 +516,6 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)
        ohci->next_statechange = jiffies;
 
        omap_ohci_clock_power(0);
-       ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
        return 0;
 }
 
index ad8166c..847187d 100644 (file)
@@ -334,12 +334,9 @@ static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
         * mark HW unaccessible, bail out if RH has been resumed. Use
         * the spinlock to properly synchronize with possible pending
         * RH suspend or resume activity.
-        *
-        * This is still racy as hcd->state is manipulated outside of
-        * any locks =P But that will be a different fix.
         */
        spin_lock_irqsave (&ohci->lock, flags);
-       if (hcd->state != HC_STATE_SUSPENDED) {
+       if (ohci->rh_state != OHCI_RH_SUSPENDED) {
                rc = -EINVAL;
                goto bail;
        }
index 29dfefe..6313e44 100644 (file)
@@ -502,8 +502,6 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
        ohci->ohci.next_statechange = jiffies;
 
        pxa27x_stop_hc(ohci, dev);
-       hcd->state = HC_STATE_SUSPENDED;
-
        return 0;
 }
 
index 15dc51d..c5a1ea9 100644 (file)
@@ -912,7 +912,7 @@ rescan_all:
                /* only take off EDs that the HC isn't using, accounting for
                 * frame counter wraps and EDs with partially retired TDs
                 */
-               if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) {
+               if (likely(ohci->rh_state == OHCI_RH_RUNNING)) {
                        if (tick_before (tick, ed->tick)) {
 skip_ed:
                                last = &ed->ed_next;
@@ -1012,7 +1012,7 @@ rescan_this:
 
                /* but if there's work queued, reschedule */
                if (!list_empty (&ed->td_list)) {
-                       if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))
+                       if (ohci->rh_state == OHCI_RH_RUNNING)
                                ed_schedule (ohci, ed);
                }
 
@@ -1021,9 +1021,7 @@ rescan_this:
        }
 
        /* maybe reenable control and bulk lists */
-       if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state)
-                       && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING
-                       && !ohci->ed_rm_list) {
+       if (ohci->rh_state == OHCI_RH_RUNNING && !ohci->ed_rm_list) {
                u32     command = 0, control = 0;
 
                if (ohci->ed_controltail) {
index afc4eb6..84686d9 100644 (file)
@@ -29,7 +29,6 @@ static int ohci_sh_start(struct usb_hcd *hcd)
        ohci_hcd_init(ohci);
        ohci_init(ohci);
        ohci_run(ohci);
-       hcd->state = HC_STATE_RUNNING;
        return 0;
 }
 
index 968cea2..5596ac2 100644 (file)
@@ -224,7 +224,6 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)
        ohci->next_statechange = jiffies;
 
        sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0);
-       ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
        return 0;
 }
 
index 6987465..95c1648 100644 (file)
@@ -203,7 +203,6 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
        ohci->next_statechange = jiffies;
 
        spear_stop_ohci(ohci_p);
-       ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
        return 0;
 }
 
index 06331d9..120bfe6 100644 (file)
@@ -318,9 +318,6 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s
                if (ret)
                        return ret;
        }
-
-       hcd->state = HC_STATE_SUSPENDED;
-
        return 0;
 }
 
index 35e5fd6..3a978a2 100644 (file)
@@ -344,6 +344,12 @@ typedef struct urb_priv {
  * a subset of what the full implementation needs. (Linus)
  */
 
+enum ohci_rh_state {
+       OHCI_RH_HALTED,
+       OHCI_RH_SUSPENDED,
+       OHCI_RH_RUNNING
+};
+
 struct ohci_hcd {
        spinlock_t              lock;
 
@@ -384,6 +390,7 @@ struct ohci_hcd {
        /*
         * driver state
         */
+       enum ohci_rh_state      rh_state;
        int                     num_ports;
        int                     load [NUM_INTS];
        u32                     hc_control;     /* copy of hc control reg */
@@ -680,11 +687,6 @@ static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci,
 
 /*-------------------------------------------------------------------------*/
 
-static inline void disable (struct ohci_hcd *ohci)
-{
-       ohci_to_hcd(ohci)->state = HC_STATE_HALT;
-}
-
 #define        FI                      0x2edf          /* 12000 bits per frame (-1) */
 #define        FSMP(fi)                (0x7fff & ((6 * ((fi) - 210)) / 7))
 #define        FIT                     (1 << 31)
@@ -708,7 +710,7 @@ static inline void periodic_reinit (struct ohci_hcd *ohci)
 #define read_roothub(hc, register, mask) ({ \
        u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \
        if (temp == -1) \
-               disable (hc); \
+               hc->rh_state = OHCI_RH_HALTED; \
        else if (hc->flags & OHCI_QUIRK_AMD756) \
                while (temp & mask) \
                        temp = ohci_readl (hc, &hc->regs->roothub.register); \