LCOV - code coverage report
Current view: top level - drivers/usb/host - ohci-hub.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 204 204 100.0 %
Date: 2017-01-25 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * OHCI HCD (Host Controller Driver) for USB.
       3             :  *
       4             :  * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
       5             :  * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
       6             :  *
       7             :  * This file is licenced under GPL
       8             :  */
       9             : 
      10             : /*-------------------------------------------------------------------------*/
      11             : 
      12             : /*
      13             :  * OHCI Root Hub ... the nonsharable stuff
      14             :  */
      15             : 
      16             : #define dbg_port(hc,label,num,value) \
      17             :         ohci_dbg (hc, \
      18             :                 "%s roothub.portstatus [%d] " \
      19             :                 "= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
      20             :                 label, num, temp, \
      21             :                 (temp & RH_PS_PRSC) ? " PRSC" : "", \
      22             :                 (temp & RH_PS_OCIC) ? " OCIC" : "", \
      23             :                 (temp & RH_PS_PSSC) ? " PSSC" : "", \
      24             :                 (temp & RH_PS_PESC) ? " PESC" : "", \
      25             :                 (temp & RH_PS_CSC) ? " CSC" : "", \
      26             :                 \
      27             :                 (temp & RH_PS_LSDA) ? " LSDA" : "", \
      28             :                 (temp & RH_PS_PPS) ? " PPS" : "", \
      29             :                 (temp & RH_PS_PRS) ? " PRS" : "", \
      30             :                 (temp & RH_PS_POCI) ? " POCI" : "", \
      31             :                 (temp & RH_PS_PSS) ? " PSS" : "", \
      32             :                 \
      33             :                 (temp & RH_PS_PES) ? " PES" : "", \
      34             :                 (temp & RH_PS_CCS) ? " CCS" : "" \
      35             :                 );
      36             : 
      37             : /*-------------------------------------------------------------------------*/
      38             : 
      39             : #define OHCI_SCHED_ENABLES \
      40             :         (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
      41             : 
      42             : static void dl_done_list (struct ohci_hcd *);
      43             : static void finish_unlinks (struct ohci_hcd *, u16);
      44             : 
      45             : #ifdef  CONFIG_PM
      46             : static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
      47             : __releases(ohci->lock)
      48             : __acquires(ohci->lock)
      49             : {
      50             :         int                     status = 0;
      51             : 
      52             :         ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
      53             :         switch (ohci->hc_control & OHCI_CTRL_HCFS) {
      54             :         case OHCI_USB_RESUME:
      55             :                 ohci_dbg (ohci, "resume/suspend?\n");
      56             :                 ohci->hc_control &= ~OHCI_CTRL_HCFS;
      57             :                 ohci->hc_control |= OHCI_USB_RESET;
      58             :                 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
      59             :                 (void) ohci_readl (ohci, &ohci->regs->control);
      60             :                 /* FALL THROUGH */
      61             :         case OHCI_USB_RESET:
      62             :                 status = -EBUSY;
      63             :                 ohci_dbg (ohci, "needs reinit!\n");
      64             :                 goto done;
      65             :         case OHCI_USB_SUSPEND:
      66             :                 if (!ohci->autostop) {
      67             :                         ohci_dbg (ohci, "already suspended\n");
      68             :                         goto done;
      69             :                 }
      70             :         }
      71             :         ohci_dbg (ohci, "%s root hub\n",
      72             :                         autostop ? "auto-stop" : "suspend");
      73             : 
      74             :         /* First stop any processing */
      75             :         if (!autostop && (ohci->hc_control & OHCI_SCHED_ENABLES)) {
      76             :                 ohci->hc_control &= ~OHCI_SCHED_ENABLES;
      77             :                 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
      78             :                 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
      79             :                 ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrstatus);
      80             : 
      81             :                 /* sched disables take effect on the next frame,
      82             :                  * then the last WDH could take 6+ msec
      83             :                  */
      84             :                 ohci_dbg (ohci, "stopping schedules ...\n");
      85             :                 ohci->autostop = 0;
      86             :                 spin_unlock_irq (&ohci->lock);
      87             :                 msleep (8);
      88             :                 spin_lock_irq (&ohci->lock);
      89             :         }
      90             :         dl_done_list (ohci);
      91             :         finish_unlinks (ohci, ohci_frame_no(ohci));
      92             : 
      93             :         /* maybe resume can wake root hub */
      94             :         if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {
      95             :                 ohci->hc_control |= OHCI_CTRL_RWE;
      96             :         } else {
      97             :                 ohci_writel(ohci, OHCI_INTR_RHSC | OHCI_INTR_RD,
      98             :                                 &ohci->regs->intrdisable);
      99             :                 ohci->hc_control &= ~OHCI_CTRL_RWE;
     100             :         }
     101             : 
     102             :         /* Suspend hub ... this is the "global (to this bus) suspend" mode,
     103             :          * which doesn't imply ports will first be individually suspended.
     104             :          */
     105             :         ohci->hc_control &= ~OHCI_CTRL_HCFS;
     106             :         ohci->hc_control |= OHCI_USB_SUSPEND;
     107             :         ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
     108             :         (void) ohci_readl (ohci, &ohci->regs->control);
     109             : 
     110             :         /* no resumes until devices finish suspending */
     111             :         if (!autostop) {
     112             :                 ohci->next_statechange = jiffies + msecs_to_jiffies (5);
     113             :                 ohci->autostop = 0;
     114             :         }
     115             : 
     116             : done:
     117             :         return status;
     118             : }
     119             : 
     120             : static inline struct ed *find_head (struct ed *ed)
     121             : {
     122             :         /* for bulk and control lists */
     123             :         while (ed->ed_prev)
     124             :                 ed = ed->ed_prev;
     125             :         return ed;
     126             : }
     127             : 
     128             : /* caller has locked the root hub */
     129             : static int ohci_rh_resume (struct ohci_hcd *ohci)
     130             : __releases(ohci->lock)
     131             : __acquires(ohci->lock)
     132             : {
     133             :         struct usb_hcd          *hcd = ohci_to_hcd (ohci);
     134             :         u32                     temp, enables;
     135             :         int                     status = -EINPROGRESS;
     136             :         int                     autostopped = ohci->autostop;
     137             : 
     138             :         ohci->autostop = 0;
     139             :         ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
     140             : 
     141             :         if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
     142             :                 /* this can happen after resuming a swsusp snapshot */
     143             :                 if (hcd->state == HC_STATE_RESUMING) {
     144             :                         ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
     145             :                                         ohci->hc_control);
     146             :                         status = -EBUSY;
     147             :                 /* this happens when pmcore resumes HC then root */
     148             :                 } else {
     149             :                         ohci_dbg (ohci, "duplicate resume\n");
     150             :                         status = 0;
     151             :                 }
     152             :         } else switch (ohci->hc_control & OHCI_CTRL_HCFS) {
     153             :         case OHCI_USB_SUSPEND:
     154             :                 ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES);
     155             :                 ohci->hc_control |= OHCI_USB_RESUME;
     156             :                 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
     157             :                 (void) ohci_readl (ohci, &ohci->regs->control);
     158             :                 ohci_dbg (ohci, "%s root hub\n",
     159             :                                 autostopped ? "auto-start" : "resume");
     160             :                 break;
     161             :         case OHCI_USB_RESUME:
     162             :                 /* HCFS changes sometime after INTR_RD */
     163             :                 ohci_dbg(ohci, "%swakeup root hub\n",
     164             :                                 autostopped ? "auto-" : "");
     165             :                 break;
     166             :         case OHCI_USB_OPER:
     167             :                 /* this can happen after resuming a swsusp snapshot */
     168             :                 ohci_dbg (ohci, "snapshot resume? reinit\n");
     169             :                 status = -EBUSY;
     170             :                 break;
     171             :         default:                /* RESET, we lost power */
     172             :                 ohci_dbg (ohci, "lost power\n");
     173             :                 status = -EBUSY;
     174             :         }
     175             :         if (status == -EBUSY) {
     176             :                 if (!autostopped) {
     177             :                         spin_unlock_irq (&ohci->lock);
     178             :                         (void) ohci_init (ohci);
     179             :                         status = ohci_restart (ohci);
     180             : 
     181             :                         usb_root_hub_lost_power(hcd->self.root_hub);
     182             : 
     183             :                         spin_lock_irq (&ohci->lock);
     184             :                 }
     185             :                 return status;
     186             :         }
     187             :         if (status != -EINPROGRESS)
     188             :                 return status;
     189             :         if (autostopped)
     190             :                 goto skip_resume;
     191             :         spin_unlock_irq (&ohci->lock);
     192             : 
     193             :         /* Some controllers (lucent erratum) need extra-long delays */
     194             :         msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1);
     195             : 
     196             :         temp = ohci_readl (ohci, &ohci->regs->control);
     197             :         temp &= OHCI_CTRL_HCFS;
     198             :         if (temp != OHCI_USB_RESUME) {
     199             :                 ohci_err (ohci, "controller won't resume\n");
     200             :                 spin_lock_irq(&ohci->lock);
     201             :                 return -EBUSY;
     202             :         }
     203             : 
     204             :         /* disable old schedule state, reinit from scratch */
     205             :         ohci_writel (ohci, 0, &ohci->regs->ed_controlhead);
     206             :         ohci_writel (ohci, 0, &ohci->regs->ed_controlcurrent);
     207             :         ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead);
     208             :         ohci_writel (ohci, 0, &ohci->regs->ed_bulkcurrent);
     209             :         ohci_writel (ohci, 0, &ohci->regs->ed_periodcurrent);
     210             :         ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
     211             : 
     212             :         /* Sometimes PCI D3 suspend trashes frame timings ... */
     213             :         periodic_reinit (ohci);
     214             : 
     215             :         /* the following code is executed with ohci->lock held and
     216             :          * irqs disabled if and only if autostopped is true
     217             :          */
     218             : 
     219             : skip_resume:
     220             :         /* interrupts might have been disabled */
     221             :         ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
     222             :         if (ohci->ed_rm_list)
     223             :                 ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
     224             : 
     225             :         /* Then re-enable operations */
     226             :         ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
     227             :         (void) ohci_readl (ohci, &ohci->regs->control);
     228             :         if (!autostopped)
     229             :                 msleep (3);
     230             : 
     231             :         temp = ohci->hc_control;
     232             :         temp &= OHCI_CTRL_RWC;
     233             :         temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
     234             :         ohci->hc_control = temp;
     235             :         ohci_writel (ohci, temp, &ohci->regs->control);
     236             :         (void) ohci_readl (ohci, &ohci->regs->control);
     237             : 
     238             :         /* TRSMRCY */
     239             :         if (!autostopped) {
     240             :                 msleep (10);
     241             :                 spin_lock_irq (&ohci->lock);
     242             :         }
     243             :         /* now ohci->lock is always held and irqs are always disabled */
     244             : 
     245             :         /* keep it alive for more than ~5x suspend + resume costs */
     246             :         ohci->next_statechange = jiffies + STATECHANGE_DELAY;
     247             : 
     248             :         /* maybe turn schedules back on */
     249             :         enables = 0;
     250             :         temp = 0;
     251             :         if (!ohci->ed_rm_list) {
     252             :                 if (ohci->ed_controltail) {
     253             :                         ohci_writel (ohci,
     254             :                                         find_head (ohci->ed_controltail)->dma,
     255             :                                         &ohci->regs->ed_controlhead);
     256             :                         enables |= OHCI_CTRL_CLE;
     257             :                         temp |= OHCI_CLF;
     258             :                 }
     259             :                 if (ohci->ed_bulktail) {
     260             :                         ohci_writel (ohci, find_head (ohci->ed_bulktail)->dma,
     261             :                                 &ohci->regs->ed_bulkhead);
     262             :                         enables |= OHCI_CTRL_BLE;
     263             :                         temp |= OHCI_BLF;
     264             :                 }
     265             :         }
     266             :         if (hcd->self.bandwidth_isoc_reqs || hcd->self.bandwidth_int_reqs)
     267             :                 enables |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
     268             :         if (enables) {
     269             :                 ohci_dbg (ohci, "restarting schedules ... %08x\n", enables);
     270             :                 ohci->hc_control |= enables;
     271             :                 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
     272             :                 if (temp)
     273             :                         ohci_writel (ohci, temp, &ohci->regs->cmdstatus);
     274             :                 (void) ohci_readl (ohci, &ohci->regs->control);
     275             :         }
     276             : 
     277             :         return 0;
     278             : }
     279             : 
     280             : static int ohci_bus_suspend (struct usb_hcd *hcd)
     281             : {
     282             :         struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
     283             :         int                     rc;
     284             : 
     285             :         spin_lock_irq (&ohci->lock);
     286             : 
     287             :         if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
     288             :                 rc = -ESHUTDOWN;
     289             :         else
     290             :                 rc = ohci_rh_suspend (ohci, 0);
     291             :         spin_unlock_irq (&ohci->lock);
     292             :         return rc;
     293             : }
     294             : 
     295             : static int ohci_bus_resume (struct usb_hcd *hcd)
     296             : {
     297             :         struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
     298             :         int                     rc;
     299             : 
     300             :         if (time_before (jiffies, ohci->next_statechange))
     301             :                 msleep(5);
     302             : 
     303             :         spin_lock_irq (&ohci->lock);
     304             : 
     305             :         if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
     306             :                 rc = -ESHUTDOWN;
     307             :         else
     308             :                 rc = ohci_rh_resume (ohci);
     309             :         spin_unlock_irq (&ohci->lock);
     310             : 
     311             :         /* poll until we know a device is connected or we autostop */
     312             :         if (rc == 0)
     313             :                 usb_hcd_poll_rh_status(hcd);
     314             :         return rc;
     315             : }
     316             : 
     317             : /* Carry out the final steps of resuming the controller device */
     318             : static void ohci_finish_controller_resume(struct usb_hcd *hcd)
     319             : {
     320             :         struct ohci_hcd         *ohci = hcd_to_ohci(hcd);
     321             :         int                     port;
     322             :         bool                    need_reinit = false;
     323             : 
     324             :         /* See if the controller is already running or has been reset */
     325             :         ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
     326             :         if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
     327             :                 need_reinit = true;
     328             :         } else {
     329             :                 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
     330             :                 case OHCI_USB_OPER:
     331             :                 case OHCI_USB_RESET:
     332             :                         need_reinit = true;
     333             :                 }
     334             :         }
     335             : 
     336             :         /* If needed, reinitialize and suspend the root hub */
     337             :         if (need_reinit) {
     338             :                 spin_lock_irq(&ohci->lock);
     339             :                 hcd->state = HC_STATE_RESUMING;
     340             :                 ohci_rh_resume(ohci);
     341             :                 hcd->state = HC_STATE_QUIESCING;
     342             :                 ohci_rh_suspend(ohci, 0);
     343             :                 hcd->state = HC_STATE_SUSPENDED;
     344             :                 spin_unlock_irq(&ohci->lock);
     345             :         }
     346             : 
     347             :         /* Normally just turn on port power and enable interrupts */
     348             :         else {
     349             :                 ohci_dbg(ohci, "powerup ports\n");
     350             :                 for (port = 0; port < ohci->num_ports; port++)
     351             :                         ohci_writel(ohci, RH_PS_PPS,
     352             :                                         &ohci->regs->roothub.portstatus[port]);
     353             : 
     354             :                 ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
     355             :                 ohci_readl(ohci, &ohci->regs->intrenable);
     356             :                 msleep(20);
     357             :         }
     358             : }
     359             : 
     360             : /* Carry out polling-, autostop-, and autoresume-related state changes */
     361             : static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
     362             :                 int any_connected, int rhsc_status)
     363             : {
     364             :         int     poll_rh = 1;
     365             :         int     rhsc_enable;
     366             : 
     367             :         /* Some broken controllers never turn off RHCS in the interrupt
     368             :          * status register.  For their sake we won't re-enable RHSC
     369             :          * interrupts if the interrupt bit is already active.
     370             :          */
     371             :         rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
     372             :                         OHCI_INTR_RHSC;
     373             : 
     374             :         switch (ohci->hc_control & OHCI_CTRL_HCFS) {
     375             :         case OHCI_USB_OPER:
     376             :                 /* If no status changes are pending, enable RHSC interrupts. */
     377             :                 if (!rhsc_enable && !rhsc_status && !changed) {
     378             :                         rhsc_enable = OHCI_INTR_RHSC;
     379             :                         ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
     380             :                 }
     381             : 
     382             :                 /* Keep on polling until we know a device is connected
     383             :                  * and RHSC is enabled, or until we autostop.
     384             :                  */
     385             :                 if (!ohci->autostop) {
     386             :                         if (any_connected ||
     387             :                                         !device_may_wakeup(&ohci_to_hcd(ohci)
     388             :                                                 ->self.root_hub->dev)) {
     389             :                                 if (rhsc_enable)
     390             :                                         poll_rh = 0;
     391             :                         } else {
     392             :                                 ohci->autostop = 1;
     393             :                                 ohci->next_statechange = jiffies + HZ;
     394             :                         }
     395             : 
     396             :                 /* if no devices have been attached for one second, autostop */
     397             :                 } else {
     398             :                         if (changed || any_connected) {
     399             :                                 ohci->autostop = 0;
     400             :                                 ohci->next_statechange = jiffies +
     401             :                                                 STATECHANGE_DELAY;
     402             :                         } else if (time_after_eq(jiffies,
     403             :                                                 ohci->next_statechange)
     404             :                                         && !ohci->ed_rm_list
     405             :                                         && !(ohci->hc_control &
     406             :                                                 OHCI_SCHED_ENABLES)) {
     407             :                                 ohci_rh_suspend(ohci, 1);
     408             :                                 if (rhsc_enable)
     409             :                                         poll_rh = 0;
     410             :                         }
     411             :                 }
     412             :                 break;
     413             : 
     414             :         case OHCI_USB_SUSPEND:
     415             :         case OHCI_USB_RESUME:
     416             :                 /* if there is a port change, autostart or ask to be resumed */
     417             :                 if (changed) {
     418             :                         if (ohci->autostop)
     419             :                                 ohci_rh_resume(ohci);
     420             :                         else
     421             :                                 usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
     422             : 
     423             :                 /* If remote wakeup is disabled, stop polling */
     424             :                 } else if (!ohci->autostop &&
     425             :                                 !ohci_to_hcd(ohci)->self.root_hub->
     426             :                                         do_remote_wakeup) {
     427             :                         poll_rh = 0;
     428             : 
     429             :                 } else {
     430             :                         /* If no status changes are pending,
     431             :                          * enable RHSC interrupts
     432             :                          */
     433             :                         if (!rhsc_enable && !rhsc_status) {
     434             :                                 rhsc_enable = OHCI_INTR_RHSC;
     435             :                                 ohci_writel(ohci, rhsc_enable,
     436             :                                                 &ohci->regs->intrenable);
     437             :                         }
     438             :                         /* Keep polling until RHSC is enabled */
     439             :                         if (rhsc_enable)
     440             :                                 poll_rh = 0;
     441             :                 }
     442             :                 break;
     443             :         }
     444             :         return poll_rh;
     445             : }
     446             : 
     447             : #else   /* CONFIG_PM */
     448             : 
     449             : static inline int ohci_rh_resume(struct ohci_hcd *ohci)
     450             : {
     451           1 :         return 0;
     452             : }
     453             : 
     454             : /* Carry out polling-related state changes.
     455             :  * autostop isn't used when CONFIG_PM is turned off.
     456             :  */
     457             : static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
     458             :                 int any_connected, int rhsc_status)
     459             : {
     460           1 :         /* If RHSC is enabled, don't poll */
     461           4 :         if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
     462           1 :                 return 0;
     463             : 
     464             :         /* If status changes are pending, continue polling.
     465             :          * Conversely, if no status changes are pending but the RHSC
     466             :          * status bit was set, then RHSC may be broken so continue polling.
     467             :          */
     468           2 :         if (changed || rhsc_status)
     469           1 :                 return 1;
     470             : 
     471             :         /* It's safe to re-enable RHSC interrupts */
     472           2 :         ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
     473           1 :         return 0;
     474             : }
     475             : 
     476             : #endif  /* CONFIG_PM */
     477             : 
     478             : /*-------------------------------------------------------------------------*/
     479             : 
     480             : /* build "status change" packet (one or two bytes) from HC registers */
     481             : 
     482             : static int
     483             : ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
     484             : {
     485           4 :         struct ohci_hcd *ohci = hcd_to_ohci (hcd);
     486           3 :         int             i, changed = 0, length = 1;
     487           2 :         int             any_connected = 0;
     488           1 :         int             rhsc_status;
     489           1 :         unsigned long   flags;
     490           1 : 
     491           4 :         spin_lock_irqsave (&ohci->lock, flags);
     492           5 :         if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
     493           2 :                 goto done;
     494           1 : 
     495           1 :         /* undocumented erratum seen on at least rev D */
     496          10 :         if ((ohci->flags & OHCI_QUIRK_AMD756)
     497           1 :                         && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) {
     498          11 :                 ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n",
     499           1 :                           ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
     500           1 :                 /* retry later; "should not happen" */
     501           2 :                 goto done;
     502           1 :         }
     503           1 : 
     504           1 :         /* init status */
     505           7 :         if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
     506           2 :                 buf [0] = changed = 1;
     507             :         else
     508           1 :                 buf [0] = 0;
     509           2 :         if (ohci->num_ports > 7) {
     510           1 :                 buf [1] = 0;
     511           1 :                 length++;
     512             :         }
     513             : 
     514             :         /* Clear the RHSC status flag before reading the port statuses */
     515           2 :         ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
     516           3 :         rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
     517             :                         OHCI_INTR_RHSC;
     518             : 
     519             :         /* look at each port */
     520           5 :         for (i = 0; i < ohci->num_ports; i++) {
     521           7 :                 u32     status = roothub_portstatus (ohci, i);
     522           1 : 
     523             :                 /* can't autostop if ports are connected */
     524           1 :                 any_connected |= (status & RH_PS_CCS);
     525             : 
     526           2 :                 if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
     527             :                                 | RH_PS_OCIC | RH_PS_PRSC)) {
     528           1 :                         changed = 1;
     529           2 :                         if (i < 7)
     530           1 :                             buf [0] |= 1 << (i + 1);
     531             :                         else
     532           1 :                             buf [1] |= 1 << (i - 7);
     533             :                 }
     534             :         }
     535             : 
     536           4 :         hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
     537             :                         any_connected, rhsc_status);
     538           1 : 
     539             : done:
     540           6 :         spin_unlock_irqrestore (&ohci->lock, flags);
     541             : 
     542           6 :         return changed ? length : 0;
     543             : }
     544             : 
     545             : /*-------------------------------------------------------------------------*/
     546             : 
     547             : static void
     548             : ohci_hub_descriptor (
     549             :         struct ohci_hcd                 *ohci,
     550           1 :         struct usb_hub_descriptor       *desc
     551           1 : ) {
     552           6 :         u32             rh = roothub_a (ohci);
     553             :         u16             temp;
     554             : 
     555           1 :         desc->bDescriptorType = 0x29;
     556           1 :         desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
     557           1 :         desc->bHubContrCurrent = 0;
     558             : 
     559           2 :         desc->bNbrPorts = ohci->num_ports;
     560           1 :         temp = 1 + (ohci->num_ports / 8);
     561           1 :         desc->bDescLength = 7 + 2 * temp;
     562             : 
     563           1 :         temp = 0;
     564           2 :         if (rh & RH_A_NPS)          /* no power switching? */
     565           1 :             temp |= 0x0002;
     566           2 :         if (rh & RH_A_PSM)          /* per-port power switching? */
     567           1 :             temp |= 0x0001;
     568           2 :         if (rh & RH_A_NOCP)         /* no overcurrent reporting? */
     569           1 :             temp |= 0x0010;
     570           2 :         else if (rh & RH_A_OCPM)    /* per-port overcurrent reporting? */
     571           1 :             temp |= 0x0008;
     572           2 :         desc->wHubCharacteristics = (__force __u16)cpu_to_hc16(ohci, temp);
     573             : 
     574             :         /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
     575           2 :         rh = roothub_b (ohci);
     576           1 :         memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
     577           1 :         desc->bitmap [0] = rh & RH_B_DR;
     578           2 :         if (ohci->num_ports > 7) {
     579           1 :                 desc->bitmap [1] = (rh & RH_B_DR) >> 8;
     580           1 :                 desc->bitmap [2] = 0xff;
     581             :         } else
     582           1 :                 desc->bitmap [1] = 0xff;
     583           1 : }
     584             : 
     585             : /*-------------------------------------------------------------------------*/
     586             : 
     587             : #ifdef  CONFIG_USB_OTG
     588             : 
     589             : static int ohci_start_port_reset (struct usb_hcd *hcd, unsigned port)
     590             : {
     591             :         struct ohci_hcd *ohci = hcd_to_ohci (hcd);
     592             :         u32                     status;
     593             : 
     594             :         if (!port)
     595             :                 return -EINVAL;
     596             :         port--;
     597             : 
     598             :         /* start port reset before HNP protocol times out */
     599             :         status = ohci_readl(ohci, &ohci->regs->roothub.portstatus [port]);
     600             :         if (!(status & RH_PS_CCS))
     601             :                 return -ENODEV;
     602             : 
     603             :         /* khubd will finish the reset later */
     604             :         ohci_writel(ohci, RH_PS_PRS, &ohci->regs->roothub.portstatus [port]);
     605             :         return 0;
     606             : }
     607             : 
     608             : #else
     609             : 
     610             : #define ohci_start_port_reset           NULL
     611             : 
     612             : #endif
     613             : 
     614             : /*-------------------------------------------------------------------------*/
     615             : 
     616             : 
     617             : /* See usb 7.1.7.5:  root hubs must issue at least 50 msec reset signaling,
     618             :  * not necessarily continuous ... to guard against resume signaling.
     619             :  * The short timeout is safe for non-root hubs, and is backward-compatible
     620             :  * with earlier Linux hosts.
     621             :  */
     622             : #ifdef  CONFIG_USB_SUSPEND
     623             : #define PORT_RESET_MSEC         50
     624             : #else
     625             : #define PORT_RESET_MSEC         10
     626             : #endif
     627             : 
     628             : /* this timer value might be vendor-specific ... */
     629             : #define PORT_RESET_HW_MSEC      10
     630             : 
     631             : /* wrap-aware logic morphed from <linux/jiffies.h> */
     632             : #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0)
     633             : 
     634             : /* called from some task, normally khubd */
     635             : static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
     636             : {
     637           2 :         __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
     638           2 :         u32     temp = 0;
     639           4 :         u16     now = ohci_readl(ohci, &ohci->regs->fmnumber);
     640           2 :         u16     reset_done = now + PORT_RESET_MSEC;
     641           2 :         int     limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC);
     642           1 : 
     643           2 :         /* build a "continuous enough" reset signal, with up to
     644           1 :          * 3msec gap between pulses.  scheduler HZ==100 must work;
     645             :          * this might need to be deadline-scheduled.
     646             :          */
     647             :         do {
     648             :                 int limit_2;
     649             : 
     650             :                 /* spin until any current reset finishes */
     651           1 :                 limit_2 = PORT_RESET_HW_MSEC * 2;
     652           4 :                 while (--limit_2 >= 0) {
     653           3 :                         temp = ohci_readl (ohci, portstat);
     654           1 :                         /* handle e.g. CardBus eject */
     655           2 :                         if (temp == ~(u32)0)
     656           1 :                                 return -ESHUTDOWN;
     657           2 :                         if (!(temp & RH_PS_PRS))
     658           2 :                                 break;
     659           1 :                         udelay (500);
     660             :                 }
     661           1 : 
     662             :                 /* timeout (a hardware error) has been observed when
     663             :                  * EHCI sets CF while this driver is resetting a port;
     664             :                  * presumably other disconnect paths might do it too.
     665             :                  */
     666           4 :                 if (limit_2 < 0) {
     667             :                         ohci_dbg(ohci,
     668             :                                 "port[%d] reset timeout, stat %08x\n",
     669             :                                 port, temp);
     670           2 :                         break;
     671             :                 }
     672             : 
     673           4 :                 if (!(temp & RH_PS_CCS))
     674           2 :                         break;
     675           4 :                 if (temp & RH_PS_PRSC)
     676           4 :                         ohci_writel (ohci, RH_PS_PRSC, portstat);
     677             : 
     678             :                 /* start the next reset, sleep till it's probably done */
     679           6 :                 ohci_writel (ohci, RH_PS_PRS, portstat);
     680           1 :                 msleep(PORT_RESET_HW_MSEC);
     681           3 :                 now = ohci_readl(ohci, &ohci->regs->fmnumber);
     682           5 :         } while (tick_before(now, reset_done) && --limit_1 >= 0);
     683             : 
     684           1 :         /* caller synchronizes using PRSC ... and handles PRS
     685             :          * still being set when this returns.
     686             :          */
     687           1 : 
     688           3 :         return 0;
     689             : }
     690             : 
     691             : static int ohci_hub_control (
     692           1 :         struct usb_hcd  *hcd,
     693             :         u16             typeReq,
     694           1 :         u16             wValue,
     695           1 :         u16             wIndex,
     696           1 :         char            *buf,
     697           1 :         u16             wLength
     698           1 : ) {
     699           4 :         struct ohci_hcd *ohci = hcd_to_ohci (hcd);
     700           2 :         int             ports = ohci->num_ports;
     701           1 :         u32             temp;
     702           1 :         int             retval = 0;
     703             : 
     704           6 :         if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
     705           1 :                 return -ESHUTDOWN;
     706             : 
     707             :         switch (typeReq) {
     708           3 :         case ClearHubFeature:
     709             :                 switch (wValue) {
     710           3 :                 case C_HUB_OVER_CURRENT:
     711           2 :                         ohci_writel (ohci, RH_HS_OCIC,
     712             :                                         &ohci->regs->roothub.status);
     713           4 :                 case C_HUB_LOCAL_POWER:
     714           2 :                         break;
     715           2 :                 default:
     716           2 :                         goto error;
     717             :                 }
     718           2 :                 break;
     719           4 :         case ClearPortFeature:
     720           4 :                 if (!wIndex || wIndex > ports)
     721           1 :                         goto error;
     722           1 :                 wIndex--;
     723             : 
     724             :                 switch (wValue) {
     725           3 :                 case USB_PORT_FEAT_ENABLE:
     726           1 :                         temp = RH_PS_CCS;
     727           1 :                         break;
     728           4 :                 case USB_PORT_FEAT_C_ENABLE:
     729           1 :                         temp = RH_PS_PESC;
     730           1 :                         break;
     731           4 :                 case USB_PORT_FEAT_SUSPEND:
     732           1 :                         temp = RH_PS_POCI;
     733           1 :                         break;
     734           4 :                 case USB_PORT_FEAT_C_SUSPEND:
     735           1 :                         temp = RH_PS_PSSC;
     736           1 :                         break;
     737           4 :                 case USB_PORT_FEAT_POWER:
     738           1 :                         temp = RH_PS_LSDA;
     739           1 :                         break;
     740           4 :                 case USB_PORT_FEAT_C_CONNECTION:
     741           1 :                         temp = RH_PS_CSC;
     742           1 :                         break;
     743           4 :                 case USB_PORT_FEAT_C_OVER_CURRENT:
     744           1 :                         temp = RH_PS_OCIC;
     745           1 :                         break;
     746           4 :                 case USB_PORT_FEAT_C_RESET:
     747           1 :                         temp = RH_PS_PRSC;
     748           1 :                         break;
     749           2 :                 default:
     750           2 :                         goto error;
     751             :                 }
     752           2 :                 ohci_writel (ohci, temp,
     753             :                                 &ohci->regs->roothub.portstatus [wIndex]);
     754             :                 // ohci_readl (ohci, &ohci->regs->roothub.portstatus [wIndex]);
     755           1 :                 break;
     756           4 :         case GetHubDescriptor:
     757           2 :                 ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
     758           1 :                 break;
     759           4 :         case GetHubStatus:
     760           3 :                 temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
     761           2 :                 put_unaligned_le32(temp, buf);
     762           1 :                 break;
     763           4 :         case GetPortStatus:
     764           4 :                 if (!wIndex || wIndex > ports)
     765           1 :                         goto error;
     766           1 :                 wIndex--;
     767           4 :                 temp = roothub_portstatus (ohci, wIndex);
     768           2 :                 put_unaligned_le32(temp, buf);
     769             : 
     770             : #ifndef OHCI_VERBOSE_DEBUG
     771             :         if (*(u16*)(buf+2))     /* only if wPortChange is interesting */
     772             : #endif
     773             :                 dbg_port (ohci, "GetStatus", wIndex, temp);
     774           1 :                 break;
     775           4 :         case SetHubFeature:
     776             :                 switch (wValue) {
     777           3 :                 case C_HUB_OVER_CURRENT:
     778             :                         // FIXME:  this can be cleared, yes?
     779           3 :                 case C_HUB_LOCAL_POWER:
     780           1 :                         break;
     781           2 :                 default:
     782           2 :                         goto error;
     783           1 :                 }
     784           1 :                 break;
     785           4 :         case SetPortFeature:
     786           4 :                 if (!wIndex || wIndex > ports)
     787           1 :                         goto error;
     788           1 :                 wIndex--;
     789             :                 switch (wValue) {
     790           3 :                 case USB_PORT_FEAT_SUSPEND:
     791             : #ifdef  CONFIG_USB_OTG
     792             :                         if (hcd->self.otg_port == (wIndex + 1)
     793             :                                         && hcd->self.b_hnp_enable)
     794             :                                 ohci->start_hnp(ohci);
     795             :                         else
     796             : #endif
     797           2 :                         ohci_writel (ohci, RH_PS_PSS,
     798             :                                 &ohci->regs->roothub.portstatus [wIndex]);
     799           1 :                         break;
     800           4 :                 case USB_PORT_FEAT_POWER:
     801           2 :                         ohci_writel (ohci, RH_PS_PPS,
     802             :                                 &ohci->regs->roothub.portstatus [wIndex]);
     803           1 :                         break;
     804           4 :                 case USB_PORT_FEAT_RESET:
     805           4 :                         retval = root_port_reset (ohci, wIndex);
     806           1 :                         break;
     807           2 :                 default:
     808           2 :                         goto error;
     809             :                 }
     810           3 :                 break;
     811           1 : 
     812           2 :         default:
     813           1 : error:
     814             :                 /* "protocol stall" on error */
     815           1 :                 retval = -EPIPE;
     816           1 :         }
     817           9 :         return retval;
     818           1 : }
     819             : 

Generated by: LCOV version 1.10