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

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001-2004 by David Brownell
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or modify it
       5             :  * under the terms of the GNU General Public License as published by the
       6             :  * Free Software Foundation; either version 2 of the License, or (at your
       7             :  * option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful, but
      10             :  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      11             :  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      12             :  * for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program; if not, write to the Free Software Foundation,
      16             :  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      17             :  */
      18             : 
      19             : /* this file is part of ehci-hcd.c */
      20             : 
      21             : /*-------------------------------------------------------------------------*/
      22             : 
      23             : /*
      24             :  * EHCI Root Hub ... the nonsharable stuff
      25             :  *
      26             :  * Registers don't need cpu_to_le32, that happens transparently
      27             :  */
      28             : 
      29             : /*-------------------------------------------------------------------------*/
      30             : 
      31             : #define PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
      32             : 
      33             : #ifdef  CONFIG_PM
      34             : 
      35             : static int ehci_hub_control(
      36             :         struct usb_hcd  *hcd,
      37             :         u16             typeReq,
      38             :         u16             wValue,
      39             :         u16             wIndex,
      40             :         char            *buf,
      41             :         u16             wLength
      42             : );
      43             : 
      44             : /* After a power loss, ports that were owned by the companion must be
      45             :  * reset so that the companion can still own them.
      46             :  */
      47             : static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
      48             : {
      49             :         u32 __iomem     *reg;
      50             :         u32             status;
      51             :         int             port;
      52             :         __le32          buf;
      53             :         struct usb_hcd  *hcd = ehci_to_hcd(ehci);
      54             : 
      55             :         if (!ehci->owned_ports)
      56             :                 return;
      57             : 
      58             :         /* Give the connections some time to appear */
      59             :         msleep(20);
      60             : 
      61             :         port = HCS_N_PORTS(ehci->hcs_params);
      62             :         while (port--) {
      63             :                 if (test_bit(port, &ehci->owned_ports)) {
      64             :                         reg = &ehci->regs->port_status[port];
      65             :                         status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
      66             : 
      67             :                         /* Port already owned by companion? */
      68             :                         if (status & PORT_OWNER)
      69             :                                 clear_bit(port, &ehci->owned_ports);
      70             :                         else if (test_bit(port, &ehci->companion_ports))
      71             :                                 ehci_writel(ehci, status & ~PORT_PE, reg);
      72             :                         else
      73             :                                 ehci_hub_control(hcd, SetPortFeature,
      74             :                                                 USB_PORT_FEAT_RESET, port + 1,
      75             :                                                 NULL, 0);
      76             :                 }
      77             :         }
      78             : 
      79             :         if (!ehci->owned_ports)
      80             :                 return;
      81             :         msleep(90);             /* Wait for resets to complete */
      82             : 
      83             :         port = HCS_N_PORTS(ehci->hcs_params);
      84             :         while (port--) {
      85             :                 if (test_bit(port, &ehci->owned_ports)) {
      86             :                         ehci_hub_control(hcd, GetPortStatus,
      87             :                                         0, port + 1,
      88             :                                         (char *) &buf, sizeof(buf));
      89             : 
      90             :                         /* The companion should now own the port,
      91             :                          * but if something went wrong the port must not
      92             :                          * remain enabled.
      93             :                          */
      94             :                         reg = &ehci->regs->port_status[port];
      95             :                         status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
      96             :                         if (status & PORT_OWNER)
      97             :                                 ehci_writel(ehci, status | PORT_CSC, reg);
      98             :                         else {
      99             :                                 ehci_dbg(ehci, "failed handover port %d: %x\n",
     100             :                                                 port + 1, status);
     101             :                                 ehci_writel(ehci, status & ~PORT_PE, reg);
     102             :                         }
     103             :                 }
     104             :         }
     105             : 
     106             :         ehci->owned_ports = 0;
     107             : }
     108             : 
     109             : static int ehci_bus_suspend (struct usb_hcd *hcd)
     110             : {
     111             :         struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
     112             :         int                     port;
     113             :         int                     mask;
     114             :         u32 __iomem             *hostpc_reg = NULL;
     115             : 
     116             :         ehci_dbg(ehci, "suspend root hub\n");
     117             : 
     118             :         if (time_before (jiffies, ehci->next_statechange))
     119             :                 msleep(5);
     120             :         del_timer_sync(&ehci->watchdog);
     121             :         del_timer_sync(&ehci->iaa_watchdog);
     122             : 
     123             :         spin_lock_irq (&ehci->lock);
     124             : 
     125             :         /* Once the controller is stopped, port resumes that are already
     126             :          * in progress won't complete.  Hence if remote wakeup is enabled
     127             :          * for the root hub and any ports are in the middle of a resume or
     128             :          * remote wakeup, we must fail the suspend.
     129             :          */
     130             :         if (hcd->self.root_hub->do_remote_wakeup) {
     131             :                 port = HCS_N_PORTS(ehci->hcs_params);
     132             :                 while (port--) {
     133             :                         if (ehci->reset_done[port] != 0) {
     134             :                                 spin_unlock_irq(&ehci->lock);
     135             :                                 ehci_dbg(ehci, "suspend failed because "
     136             :                                                 "port %d is resuming\n",
     137             :                                                 port + 1);
     138             :                                 return -EBUSY;
     139             :                         }
     140             :                 }
     141             :         }
     142             : 
     143             :         /* stop schedules, clean any completed work */
     144             :         if (HC_IS_RUNNING(hcd->state)) {
     145             :                 ehci_quiesce (ehci);
     146             :                 hcd->state = HC_STATE_QUIESCING;
     147             :         }
     148             :         ehci->command = ehci_readl(ehci, &ehci->regs->command);
     149             :         ehci_work(ehci);
     150             : 
     151             :         /* Unlike other USB host controller types, EHCI doesn't have
     152             :          * any notion of "global" or bus-wide suspend.  The driver has
     153             :          * to manually suspend all the active unsuspended ports, and
     154             :          * then manually resume them in the bus_resume() routine.
     155             :          */
     156             :         ehci->bus_suspended = 0;
     157             :         ehci->owned_ports = 0;
     158             :         port = HCS_N_PORTS(ehci->hcs_params);
     159             :         while (port--) {
     160             :                 u32 __iomem     *reg = &ehci->regs->port_status [port];
     161             :                 u32             t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
     162             :                 u32             t2 = t1;
     163             : 
     164             :                 if (ehci->has_hostpc)
     165             :                         hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
     166             :                                 + HOSTPC0 + 4 * (port & 0xff));
     167             :                 /* keep track of which ports we suspend */
     168             :                 if (t1 & PORT_OWNER)
     169             :                         set_bit(port, &ehci->owned_ports);
     170             :                 else if ((t1 & PORT_PE) && !(t1 & PORT_SUSPEND)) {
     171             :                         t2 |= PORT_SUSPEND;
     172             :                         set_bit(port, &ehci->bus_suspended);
     173             :                 }
     174             : 
     175             :                 /* enable remote wakeup on all ports */
     176             :                 if (hcd->self.root_hub->do_remote_wakeup) {
     177             :                         /* only enable appropriate wake bits, otherwise the
     178             :                          * hardware can not go phy low power mode. If a race
     179             :                          * condition happens here(connection change during bits
     180             :                          * set), the port change detection will finally fix it.
     181             :                          */
     182             :                         if (t1 & PORT_CONNECT) {
     183             :                                 t2 |= PORT_WKOC_E | PORT_WKDISC_E;
     184             :                                 t2 &= ~PORT_WKCONN_E;
     185             :                         } else {
     186             :                                 t2 |= PORT_WKOC_E | PORT_WKCONN_E;
     187             :                                 t2 &= ~PORT_WKDISC_E;
     188             :                         }
     189             :                 } else
     190             :                         t2 &= ~PORT_WAKE_BITS;
     191             : 
     192             :                 if (t1 != t2) {
     193             :                         ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
     194             :                                 port + 1, t1, t2);
     195             :                         ehci_writel(ehci, t2, reg);
     196             :                         if (hostpc_reg) {
     197             :                                 u32     t3;
     198             : 
     199             :                                 spin_unlock_irq(&ehci->lock);
     200             :                                 msleep(5);/* 5ms for HCD enter low pwr mode */
     201             :                                 spin_lock_irq(&ehci->lock);
     202             :                                 t3 = ehci_readl(ehci, hostpc_reg);
     203             :                                 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
     204             :                                 t3 = ehci_readl(ehci, hostpc_reg);
     205             :                                 ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
     206             :                                         port, (t3 & HOSTPC_PHCD) ?
     207             :                                         "succeeded" : "failed");
     208             :                         }
     209             :                 }
     210             :         }
     211             : 
     212             :         /* Apparently some devices need a >= 1-uframe delay here */
     213             :         if (ehci->bus_suspended)
     214             :                 udelay(150);
     215             : 
     216             :         /* turn off now-idle HC */
     217             :         ehci_halt (ehci);
     218             :         hcd->state = HC_STATE_SUSPENDED;
     219             : 
     220             :         if (ehci->reclaim)
     221             :                 end_unlink_async(ehci);
     222             : 
     223             :         /* allow remote wakeup */
     224             :         mask = INTR_MASK;
     225             :         if (!hcd->self.root_hub->do_remote_wakeup)
     226             :                 mask &= ~STS_PCD;
     227             :         ehci_writel(ehci, mask, &ehci->regs->intr_enable);
     228             :         ehci_readl(ehci, &ehci->regs->intr_enable);
     229             : 
     230             :         ehci->next_statechange = jiffies + msecs_to_jiffies(10);
     231             :         spin_unlock_irq (&ehci->lock);
     232             : 
     233             :         /* ehci_work() may have re-enabled the watchdog timer, which we do not
     234             :          * want, and so we must delete any pending watchdog timer events.
     235             :          */
     236             :         del_timer_sync(&ehci->watchdog);
     237             :         return 0;
     238             : }
     239             : 
     240             : 
     241             : /* caller has locked the root hub, and should reset/reinit on error */
     242             : static int ehci_bus_resume (struct usb_hcd *hcd)
     243             : {
     244             :         struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
     245             :         u32                     temp;
     246             :         u32                     power_okay;
     247             :         int                     i;
     248             :         unsigned long           resume_needed = 0;
     249             : 
     250             :         if (time_before (jiffies, ehci->next_statechange))
     251             :                 msleep(5);
     252             :         spin_lock_irq (&ehci->lock);
     253             :         if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
     254             :                 spin_unlock_irq(&ehci->lock);
     255             :                 return -ESHUTDOWN;
     256             :         }
     257             : 
     258             :         if (unlikely(ehci->debug)) {
     259             :                 if (!dbgp_reset_prep())
     260             :                         ehci->debug = NULL;
     261             :                 else
     262             :                         dbgp_external_startup();
     263             :         }
     264             : 
     265             :         /* Ideally and we've got a real resume here, and no port's power
     266             :          * was lost.  (For PCI, that means Vaux was maintained.)  But we
     267             :          * could instead be restoring a swsusp snapshot -- so that BIOS was
     268             :          * the last user of the controller, not reset/pm hardware keeping
     269             :          * state we gave to it.
     270             :          */
     271             :         power_okay = ehci_readl(ehci, &ehci->regs->intr_enable);
     272             :         ehci_dbg(ehci, "resume root hub%s\n",
     273             :                         power_okay ? "" : " after power loss");
     274             : 
     275             :         /* at least some APM implementations will try to deliver
     276             :          * IRQs right away, so delay them until we're ready.
     277             :          */
     278             :         ehci_writel(ehci, 0, &ehci->regs->intr_enable);
     279             : 
     280             :         /* re-init operational registers */
     281             :         ehci_writel(ehci, 0, &ehci->regs->segment);
     282             :         ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
     283             :         ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
     284             : 
     285             :         /* restore CMD_RUN, framelist size, and irq threshold */
     286             :         ehci_writel(ehci, ehci->command, &ehci->regs->command);
     287             : 
     288             :         /* Some controller/firmware combinations need a delay during which
     289             :          * they set up the port statuses.  See Bugzilla #8190. */
     290             :         spin_unlock_irq(&ehci->lock);
     291             :         msleep(8);
     292             :         spin_lock_irq(&ehci->lock);
     293             : 
     294             :         /* manually resume the ports we suspended during bus_suspend() */
     295             :         i = HCS_N_PORTS (ehci->hcs_params);
     296             :         while (i--) {
     297             :                 /* clear phy low power mode before resume */
     298             :                 if (ehci->has_hostpc) {
     299             :                         u32 __iomem     *hostpc_reg =
     300             :                                 (u32 __iomem *)((u8 *)ehci->regs
     301             :                                 + HOSTPC0 + 4 * (i & 0xff));
     302             :                         temp = ehci_readl(ehci, hostpc_reg);
     303             :                         ehci_writel(ehci, temp & ~HOSTPC_PHCD,
     304             :                                 hostpc_reg);
     305             :                         mdelay(5);
     306             :                 }
     307             :                 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
     308             :                 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
     309             :                 if (test_bit(i, &ehci->bus_suspended) &&
     310             :                                 (temp & PORT_SUSPEND)) {
     311             :                         temp |= PORT_RESUME;
     312             :                         set_bit(i, &resume_needed);
     313             :                 }
     314             :                 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
     315             :         }
     316             : 
     317             :         /* msleep for 20ms only if code is trying to resume port */
     318             :         if (resume_needed) {
     319             :                 spin_unlock_irq(&ehci->lock);
     320             :                 msleep(20);
     321             :                 spin_lock_irq(&ehci->lock);
     322             :         }
     323             : 
     324             :         i = HCS_N_PORTS (ehci->hcs_params);
     325             :         while (i--) {
     326             :                 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
     327             :                 if (test_bit(i, &resume_needed)) {
     328             :                         temp &= ~(PORT_RWC_BITS | PORT_RESUME);
     329             :                         ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
     330             :                         ehci_vdbg (ehci, "resumed port %d\n", i + 1);
     331             :                 }
     332             :         }
     333             :         (void) ehci_readl(ehci, &ehci->regs->command);
     334             : 
     335             :         /* maybe re-activate the schedule(s) */
     336             :         temp = 0;
     337             :         if (ehci->async->qh_next.qh)
     338             :                 temp |= CMD_ASE;
     339             :         if (ehci->periodic_sched)
     340             :                 temp |= CMD_PSE;
     341             :         if (temp) {
     342             :                 ehci->command |= temp;
     343             :                 ehci_writel(ehci, ehci->command, &ehci->regs->command);
     344             :         }
     345             : 
     346             :         ehci->next_statechange = jiffies + msecs_to_jiffies(5);
     347             :         hcd->state = HC_STATE_RUNNING;
     348             : 
     349             :         /* Now we can safely re-enable irqs */
     350             :         ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
     351             : 
     352             :         spin_unlock_irq (&ehci->lock);
     353             :         ehci_handover_companion_ports(ehci);
     354             :         return 0;
     355             : }
     356             : 
     357             : #else
     358             : 
     359             : #define ehci_bus_suspend        NULL
     360             : #define ehci_bus_resume         NULL
     361             : 
     362             : #endif  /* CONFIG_PM */
     363             : 
     364             : /*-------------------------------------------------------------------------*/
     365             : 
     366             : /* Display the ports dedicated to the companion controller */
     367             : static ssize_t show_companion(struct device *dev,
     368             :                               struct device_attribute *attr,
     369             :                               char *buf)
     370           1 : {
     371           1 :         struct ehci_hcd         *ehci;
     372           1 :         int                     nports, index, n;
     373           2 :         int                     count = PAGE_SIZE;
     374           2 :         char                    *ptr = buf;
     375           1 : 
     376           7 :         ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
     377           3 :         nports = HCS_N_PORTS(ehci->hcs_params);
     378           1 : 
     379           5 :         for (index = 0; index < nports; ++index) {
     380           6 :                 if (test_bit(index, &ehci->companion_ports)) {
     381           2 :                         n = scnprintf(ptr, count, "%d\n", index + 1);
     382           1 :                         ptr += n;
     383           1 :                         count -= n;
     384             :                 }
     385             :         }
     386           1 :         return ptr - buf;
     387             : }
     388             : 
     389             : /*
     390             :  * Sets the owner of a port
     391             :  */
     392             : static void set_owner(struct ehci_hcd *ehci, int portnum, int new_owner)
     393             : {
     394           3 :         u32 __iomem             *status_reg;
     395           3 :         u32                     port_status;
     396           3 :         int                     try;
     397             : 
     398           3 :         status_reg = &ehci->regs->port_status[portnum];
     399             : 
     400             :         /*
     401             :          * The controller won't set the OWNER bit if the port is
     402             :          * enabled, so this loop will sometimes require at least two
     403             :          * iterations: one to disable the port and one to set OWNER.
     404             :          */
     405          15 :         for (try = 4; try > 0; --try) {
     406          12 :                 spin_lock_irq(&ehci->lock);
     407           9 :                 port_status = ehci_readl(ehci, status_reg);
     408          12 :                 if ((port_status & PORT_OWNER) == new_owner
     409             :                                 || (port_status & (PORT_OWNER | PORT_CONNECT))
     410             :                                         == 0)
     411           3 :                         try = 0;
     412           3 :                 else {
     413           3 :                         port_status ^= PORT_OWNER;
     414           3 :                         port_status &= ~(PORT_PE | PORT_RWC_BITS);
     415           6 :                         ehci_writel(ehci, port_status, status_reg);
     416             :                 }
     417          12 :                 spin_unlock_irq(&ehci->lock);
     418           6 :                 if (try > 1)
     419           3 :                         msleep(5);
     420             :         }
     421             : }
     422             : 
     423             : /*
     424             :  * Dedicate or undedicate a port to the companion controller.
     425             :  * Syntax is "[-]portnum", where a leading '-' sign means
     426             :  * return control of the port to the EHCI controller.
     427             :  */
     428             : static ssize_t store_companion(struct device *dev,
     429             :                                struct device_attribute *attr,
     430             :                                const char *buf, size_t count)
     431           1 : {
     432           1 :         struct ehci_hcd         *ehci;
     433           1 :         int                     portnum, new_owner;
     434           1 : 
     435           7 :         ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
     436           2 :         new_owner = PORT_OWNER;         /* Owned by companion */
     437           3 :         if (sscanf(buf, "%d", &portnum) != 1)
     438           1 :                 return -EINVAL;
     439           2 :         if (portnum < 0) {
     440           1 :                 portnum = - portnum;
     441           1 :                 new_owner = 0;          /* Owned by EHCI */
     442             :         }
     443           4 :         if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
     444           1 :                 return -ENOENT;
     445           1 :         portnum--;
     446           2 :         if (new_owner)
     447           2 :                 set_bit(portnum, &ehci->companion_ports);
     448             :         else
     449           2 :                 clear_bit(portnum, &ehci->companion_ports);
     450           4 :         set_owner(ehci, portnum, new_owner);
     451           1 :         return count;
     452             : }
     453           1 : static DEVICE_ATTR(companion, 0644, show_companion, store_companion);
     454             : 
     455             : static inline void create_companion_file(struct ehci_hcd *ehci)
     456             : {
     457           1 :         int     i;
     458           1 : 
     459           1 :         /* with integrated TT there is no companion! */
     460           4 :         if (!ehci_is_TDI(ehci))
     461           3 :                 i = device_create_file(ehci_to_hcd(ehci)->self.controller,
     462             :                                        &dev_attr_companion);
     463           2 : }
     464             : 
     465             : static inline void remove_companion_file(struct ehci_hcd *ehci)
     466             : {
     467           1 :         /* with integrated TT there is no companion! */
     468           5 :         if (!ehci_is_TDI(ehci))
     469           3 :                 device_remove_file(ehci_to_hcd(ehci)->self.controller,
     470             :                                    &dev_attr_companion);
     471           2 : }
     472             : 
     473             : 
     474             : /*-------------------------------------------------------------------------*/
     475             : 
     476             : static int check_reset_complete (
     477             :         struct ehci_hcd *ehci,
     478             :         int             index,
     479           4 :         u32 __iomem     *status_reg,
     480             :         int             port_status
     481             : ) {
     482           8 :         if (!(port_status & PORT_CONNECT))
     483           4 :                 return port_status;
     484             : 
     485             :         /* if reset finished and it's still not enabled -- handoff */
     486           8 :         if (!(port_status & PORT_PE)) {
     487             : 
     488             :                 /* with integrated TT, there's nobody to hand it to! */
     489          16 :                 if (ehci_is_TDI(ehci)) {
     490             :                         ehci_dbg (ehci,
     491             :                                 "Failed to enable port %d on root hub TT\n",
     492             :                                 index+1);
     493           4 :                         return port_status;
     494             :                 }
     495             : 
     496             :                 ehci_dbg (ehci, "port %d full speed --> companion\n",
     497             :                         index + 1);
     498             : 
     499             :                 // what happens if HCS_N_CC(params) == 0 ?
     500           4 :                 port_status |= PORT_OWNER;
     501           4 :                 port_status &= ~PORT_RWC_BITS;
     502           8 :                 ehci_writel(ehci, port_status, status_reg);
     503             : 
     504             :                 /* ensure 440EPX ohci controller state is operational */
     505           8 :                 if (ehci->has_amcc_usb23)
     506           8 :                         set_ohci_hcfs(ehci, 1);
     507             :         } else {
     508             :                 ehci_dbg (ehci, "port %d high speed\n", index + 1);
     509             :                 /* ensure 440EPx ohci controller state is suspended */
     510           8 :                 if (ehci->has_amcc_usb23)
     511           8 :                         set_ohci_hcfs(ehci, 0);
     512             :         }
     513             : 
     514          16 :         return port_status;
     515             : }
     516             : 
     517             : /*-------------------------------------------------------------------------*/
     518             : 
     519             : 
     520             : /* build "status change" packet (one or two bytes) from HC registers */
     521             : 
     522             : static int
     523             : ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
     524             : {
     525           4 :         struct ehci_hcd *ehci = hcd_to_ehci (hcd);
     526           2 :         u32             temp, status = 0;
     527           1 :         u32             mask;
     528           2 :         int             ports, i, retval = 1;
     529           1 :         unsigned long   flags;
     530           1 : 
     531           1 :         /* if !USB_SUSPEND, root hub timers won't get shut down ... */
     532           3 :         if (!HC_IS_RUNNING(hcd->state))
     533           2 :                 return 0;
     534           1 : 
     535           1 :         /* init status to no-changes */
     536           1 :         buf [0] = 0;
     537           2 :         ports = HCS_N_PORTS (ehci->hcs_params);
     538           2 :         if (ports > 7) {
     539           1 :                 buf [1] = 0;
     540           1 :                 retval++;
     541             :         }
     542             : 
     543             :         /* Some boards (mostly VIA?) report bogus overcurrent indications,
     544             :          * causing massive log spam unless we completely ignore them.  It
     545             :          * may be relevant that VIA VT8235 controllers, where PORT_POWER is
     546             :          * always set, seem to clear PORT_OCC and PORT_CSC when writing to
     547             :          * PORT_POWER; that's surprising, but maybe within-spec.
     548             :          */
     549           2 :         if (!ignore_oc)
     550           1 :                 mask = PORT_CSC | PORT_PEC | PORT_OCC;
     551             :         else
     552           1 :                 mask = PORT_CSC | PORT_PEC;
     553             :         // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
     554             : 
     555             :         /* no hub change reports (bit 0) for now (power, ...) */
     556             : 
     557             :         /* port N changes (bit N)? */
     558           3 :         spin_lock_irqsave (&ehci->lock, flags);
     559           6 :         for (i = 0; i < ports; i++) {
     560           5 :                 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
     561           1 : 
     562             :                 /*
     563             :                  * Return status information even for ports with OWNER set.
     564             :                  * Otherwise khubd wouldn't see the disconnect event when a
     565             :                  * high-speed device is switched over to the companion
     566             :                  * controller by the user.
     567             :                  */
     568             : 
     569           2 :                 if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
     570          10 :                                 || (ehci->reset_done[i] && time_after_eq(
     571           1 :                                         jiffies, ehci->reset_done[i]))) {
     572           4 :                         if (i < 7)
     573           2 :                             buf [0] |= 1 << (i + 1);
     574             :                         else
     575           2 :                             buf [1] |= 1 << (i - 7);
     576           2 :                         status = STS_PCD;
     577             :                 }
     578             :         }
     579             :         /* FIXME autosuspend idle root hubs */
     580           2 :         spin_unlock_irqrestore (&ehci->lock, flags);
     581           6 :         return status ? retval : 0;
     582             : }
     583             : 
     584             : /*-------------------------------------------------------------------------*/
     585             : 
     586             : static void
     587             : ehci_hub_descriptor (
     588             :         struct ehci_hcd                 *ehci,
     589           4 :         struct usb_hub_descriptor       *desc
     590           4 : ) {
     591           8 :         int             ports = HCS_N_PORTS (ehci->hcs_params);
     592             :         u16             temp;
     593             : 
     594           4 :         desc->bDescriptorType = 0x29;
     595           4 :         desc->bPwrOn2PwrGood = 10;   /* ehci 1.0, 2.3.9 says 20ms max */
     596           4 :         desc->bHubContrCurrent = 0;
     597             : 
     598           4 :         desc->bNbrPorts = ports;
     599           4 :         temp = 1 + (ports / 8);
     600           4 :         desc->bDescLength = 7 + 2 * temp;
     601             : 
     602             :         /* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
     603           4 :         memset (&desc->bitmap [0], 0, temp);
     604           4 :         memset (&desc->bitmap [temp], 0xff, temp);
     605             : 
     606           4 :         temp = 0x0008;                  /* per-port overcurrent reporting */
     607           8 :         if (HCS_PPC (ehci->hcs_params))
     608           4 :                 temp |= 0x0001;         /* per-port power control */
     609             :         else
     610           4 :                 temp |= 0x0002;         /* no power switching */
     611             : #if 0
     612             : // re-enable when we support USB_PORT_FEAT_INDICATOR below.
     613             :         if (HCS_INDICATOR (ehci->hcs_params))
     614             :                 temp |= 0x0080;         /* per-port indicators (LEDs) */
     615             : #endif
     616           4 :         desc->wHubCharacteristics = cpu_to_le16(temp);
     617           4 : }
     618             : 
     619             : /*-------------------------------------------------------------------------*/
     620             : 
     621             : static int ehci_hub_control (
     622             :         struct usb_hcd  *hcd,
     623             :         u16             typeReq,
     624           4 :         u16             wValue,
     625           4 :         u16             wIndex,
     626           4 :         char            *buf,
     627           4 :         u16             wLength
     628           4 : ) {
     629          16 :         struct ehci_hcd *ehci = hcd_to_ehci (hcd);
     630          12 :         int             ports = HCS_N_PORTS (ehci->hcs_params);
     631           8 :         u32 __iomem     *status_reg = &ehci->regs->port_status[
     632           4 :                                 (wIndex & 0xff) - 1];
     633           8 :         u32 __iomem     *hostpc_reg = NULL;
     634           4 :         u32             temp, temp1, status;
     635           4 :         unsigned long   flags;
     636           8 :         int             retval = 0;
     637           4 :         unsigned        selector;
     638           4 : 
     639           4 :         /*
     640           4 :          * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
     641           4 :          * HCS_INDICATOR may say we can change LEDs to off/amber/green.
     642           4 :          * (track current state ourselves) ... blink for diagnostics,
     643           4 :          * power, "this is the one", etc.  EHCI spec supports this.
     644           4 :          */
     645           4 : 
     646          12 :         if (ehci->has_hostpc)
     647           8 :                 hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
     648           4 :                                 + HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
     649          16 :         spin_lock_irqsave (&ehci->lock, flags);
     650           4 :         switch (typeReq) {
     651          16 :         case ClearHubFeature:
     652           4 :                 switch (wValue) {
     653          16 :                 case C_HUB_LOCAL_POWER:
     654          16 :                 case C_HUB_OVER_CURRENT:
     655           4 :                         /* no hub-wide feature/status flags */
     656           8 :                         break;
     657          12 :                 default:
     658          12 :                         goto error;
     659           8 :                 }
     660           8 :                 break;
     661          20 :         case ClearPortFeature:
     662          16 :                 if (!wIndex || wIndex > ports)
     663           4 :                         goto error;
     664           4 :                 wIndex--;
     665           8 :                 temp = ehci_readl(ehci, status_reg);
     666             : 
     667             :                 /*
     668             :                  * Even if OWNER is set, so the port is owned by the
     669             :                  * companion controller, khubd needs to be able to clear
     670             :                  * the port-change status bits (especially
     671             :                  * USB_PORT_FEAT_C_CONNECTION).
     672             :                  */
     673             : 
     674             :                 switch (wValue) {
     675          12 :                 case USB_PORT_FEAT_ENABLE:
     676           8 :                         ehci_writel(ehci, temp & ~PORT_PE, status_reg);
     677           4 :                         break;
     678          16 :                 case USB_PORT_FEAT_C_ENABLE:
     679           8 :                         ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
     680             :                                         status_reg);
     681           4 :                         break;
     682          16 :                 case USB_PORT_FEAT_SUSPEND:
     683           8 :                         if (temp & PORT_RESET)
     684           4 :                                 goto error;
     685           8 :                         if (ehci->no_selective_suspend)
     686           4 :                                 break;
     687           8 :                         if (temp & PORT_SUSPEND) {
     688           8 :                                 if ((temp & PORT_PE) == 0)
     689           4 :                                         goto error;
     690             :                                 /* clear phy low power mode before resume */
     691           8 :                                 if (hostpc_reg) {
     692           8 :                                         temp1 = ehci_readl(ehci, hostpc_reg);
     693           8 :                                         ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
     694             :                                                 hostpc_reg);
     695           8 :                                         mdelay(5);
     696             :                                 }
     697             :                                 /* resume signaling for 20 msec */
     698           8 :                                 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
     699          16 :                                 ehci_writel(ehci, temp | PORT_RESUME,
     700             :                                                 status_reg);
     701           8 :                                 ehci->reset_done [wIndex] = jiffies
     702             :                                                 + msecs_to_jiffies (20);
     703             :                         }
     704           8 :                         break;
     705          16 :                 case USB_PORT_FEAT_C_SUSPEND:
     706           8 :                         clear_bit(wIndex, &ehci->port_c_suspend);
     707           4 :                         break;
     708          16 :                 case USB_PORT_FEAT_POWER:
     709           8 :                         if (HCS_PPC (ehci->hcs_params))
     710           8 :                                 ehci_writel(ehci,
     711             :                                           temp & ~(PORT_RWC_BITS | PORT_POWER),
     712             :                                           status_reg);
     713           8 :                         break;
     714          16 :                 case USB_PORT_FEAT_C_CONNECTION:
     715           8 :                         ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
     716             :                                         status_reg);
     717           4 :                         break;
     718          16 :                 case USB_PORT_FEAT_C_OVER_CURRENT:
     719           8 :                         ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
     720             :                                         status_reg);
     721           4 :                         break;
     722          16 :                 case USB_PORT_FEAT_C_RESET:
     723             :                         /* GetPortStatus clears reset */
     724           4 :                         break;
     725           8 :                 default:
     726           8 :                         goto error;
     727             :                 }
     728          64 :                 ehci_readl(ehci, &ehci->regs->command);       /* unblock posted write */
     729           4 :                 break;
     730          16 :         case GetHubDescriptor:
     731           8 :                 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
     732             :                         buf);
     733           4 :                 break;
     734          16 :         case GetHubStatus:
     735             :                 /* no hub-wide feature/status flags */
     736           4 :                 memset (buf, 0, 4);
     737             :                 //cpu_to_le32s ((u32 *) buf);
     738           4 :                 break;
     739          16 :         case GetPortStatus:
     740          16 :                 if (!wIndex || wIndex > ports)
     741           4 :                         goto error;
     742           4 :                 wIndex--;
     743           4 :                 status = 0;
     744           8 :                 temp = ehci_readl(ehci, status_reg);
     745             : 
     746             :                 // wPortChange bits
     747           8 :                 if (temp & PORT_CSC)
     748           4 :                         status |= 1 << USB_PORT_FEAT_C_CONNECTION;
     749           8 :                 if (temp & PORT_PEC)
     750           4 :                         status |= 1 << USB_PORT_FEAT_C_ENABLE;
     751             : 
     752          16 :                 if ((temp & PORT_OCC) && !ignore_oc){
     753           4 :                         status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
     754             : 
     755             :                         /*
     756             :                          * Hubs should disable port power on over-current.
     757             :                          * However, not all EHCI implementations do this
     758             :                          * automatically, even if they _do_ support per-port
     759             :                          * power switching; they're allowed to just limit the
     760             :                          * current.  khubd will turn the power back on.
     761             :                          */
     762          16 :                         if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) {
     763           8 :                                 ehci_writel(ehci,
     764             :                                         temp & ~(PORT_RWC_BITS | PORT_POWER),
     765             :                                         status_reg);
     766           8 :                                 temp = ehci_readl(ehci, status_reg);
     767             :                         }
     768             :                 }
     769             : 
     770             :                 /* whoever resumes must GetPortStatus to complete it!! */
     771          16 :                 if (temp & PORT_RESUME) {
     772             : 
     773             :                         /* Remote Wakeup received? */
     774          16 :                         if (!ehci->reset_done[wIndex]) {
     775             :                                 /* resume signaling for 20 msec */
     776          16 :                                 ehci->reset_done[wIndex] = jiffies
     777             :                                                 + msecs_to_jiffies(20);
     778             :                                 /* check the port again */
     779          24 :                                 mod_timer(&ehci_to_hcd(ehci)->rh_timer,
     780             :                                                 ehci->reset_done[wIndex]);
     781             :                         }
     782             : 
     783             :                         /* resume completed? */
     784          16 :                         else if (time_after_eq(jiffies,
     785             :                                         ehci->reset_done[wIndex])) {
     786          16 :                                 clear_bit(wIndex, &ehci->suspended_ports);
     787           8 :                                 set_bit(wIndex, &ehci->port_c_suspend);
     788           4 :                                 ehci->reset_done[wIndex] = 0;
     789             : 
     790             :                                 /* stop resume signaling */
     791           8 :                                 temp = ehci_readl(ehci, status_reg);
     792           8 :                                 ehci_writel(ehci,
     793             :                                         temp & ~(PORT_RWC_BITS | PORT_RESUME),
     794             :                                         status_reg);
     795           8 :                                 retval = handshake(ehci, status_reg,
     796             :                                            PORT_RESUME, 0, 2000 /* 2msec */);
     797           8 :                                 if (retval != 0) {
     798          32 :                                         ehci_err(ehci,
     799             :                                                 "port %d resume error %d\n",
     800             :                                                 wIndex + 1, retval);
     801           4 :                                         goto error;
     802             :                                 }
     803           4 :                                 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
     804             :                         }
     805             :                 }
     806             : 
     807             :                 /* whoever resets must GetPortStatus to complete it!! */
     808             :                 if ((temp & PORT_RESET)
     809          64 :                                 && time_after_eq(jiffies,
     810             :                                         ehci->reset_done[wIndex])) {
     811          16 :                         status |= 1 << USB_PORT_FEAT_C_RESET;
     812          16 :                         ehci->reset_done [wIndex] = 0;
     813             : 
     814             :                         /* force reset to complete */
     815          32 :                         ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
     816             :                                         status_reg);
     817             :                         /* REVISIT:  some hardware needs 550+ usec to clear
     818             :                          * this bit; seems too long to spin routinely...
     819             :                          */
     820           8 :                         retval = handshake(ehci, status_reg,
     821             :                                         PORT_RESET, 0, 750);
     822           8 :                         if (retval != 0) {
     823          32 :                                 ehci_err (ehci, "port %d reset error %d\n",
     824             :                                         wIndex + 1, retval);
     825           4 :                                 goto error;
     826             :                         }
     827             : 
     828             :                         /* see what we found out */
     829          36 :                         temp = check_reset_complete (ehci, wIndex, status_reg,
     830             :                                         ehci_readl(ehci, status_reg));
     831             :                 }
     832             : 
     833          40 :                 if (!(temp & (PORT_RESUME|PORT_RESET)))
     834          20 :                         ehci->reset_done[wIndex] = 0;
     835             : 
     836             :                 /* transfer dedicated ports to the companion hc */
     837          88 :                 if ((temp & PORT_CONNECT) &&
     838             :                                 test_bit(wIndex, &ehci->companion_ports)) {
     839           4 :                         temp &= ~PORT_RWC_BITS;
     840           4 :                         temp |= PORT_OWNER;
     841           8 :                         ehci_writel(ehci, temp, status_reg);
     842             :                         ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1);
     843           8 :                         temp = ehci_readl(ehci, status_reg);
     844             :                 }
     845             : 
     846             :                 /*
     847             :                  * Even if OWNER is set, there's no harm letting khubd
     848             :                  * see the wPortStatus values (they should all be 0 except
     849             :                  * for PORT_POWER anyway).
     850             :                  */
     851             : 
     852          56 :                 if (temp & PORT_CONNECT) {
     853          28 :                         status |= 1 << USB_PORT_FEAT_CONNECTION;
     854             :                         // status may be from integrated TT
     855          56 :                         if (ehci->has_hostpc) {
     856          56 :                                 temp1 = ehci_readl(ehci, hostpc_reg);
     857          12 :                                 status |= ehci_port_speed(ehci, temp1);
     858             :                         } else
     859          60 :                                 status |= ehci_port_speed(ehci, temp);
     860             :                 }
     861          72 :                 if (temp & PORT_PE)
     862          36 :                         status |= 1 << USB_PORT_FEAT_ENABLE;
     863             : 
     864             :                 /* maybe the port was unsuspended without our knowledge */
     865          72 :                 if (temp & (PORT_SUSPEND|PORT_RESUME)) {
     866          36 :                         status |= 1 << USB_PORT_FEAT_SUSPEND;
     867          80 :                 } else if (test_bit(wIndex, &ehci->suspended_ports)) {
     868           8 :                         clear_bit(wIndex, &ehci->suspended_ports);
     869           4 :                         ehci->reset_done[wIndex] = 0;
     870           8 :                         if (temp & PORT_PE)
     871           8 :                                 set_bit(wIndex, &ehci->port_c_suspend);
     872             :                 }
     873             : 
     874          96 :                 if (temp & PORT_OC)
     875          48 :                         status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
     876          96 :                 if (temp & PORT_RESET)
     877          48 :                         status |= 1 << USB_PORT_FEAT_RESET;
     878          96 :                 if (temp & PORT_POWER)
     879          48 :                         status |= 1 << USB_PORT_FEAT_POWER;
     880         104 :                 if (test_bit(wIndex, &ehci->port_c_suspend))
     881           4 :                         status |= 1 << USB_PORT_FEAT_C_SUSPEND;
     882             : 
     883             : #ifndef VERBOSE_DEBUG
     884           8 :         if (status & ~0xffff)       /* only if wPortChange is interesting */
     885             : #endif
     886           8 :                 dbg_port (ehci, "GetStatus", wIndex + 1, temp);
     887          16 :                 put_unaligned_le32(status, buf);
     888           4 :                 break;
     889          16 :         case SetHubFeature:
     890             :                 switch (wValue) {
     891          12 :                 case C_HUB_LOCAL_POWER:
     892          12 :                 case C_HUB_OVER_CURRENT:
     893             :                         /* no hub-wide feature/status flags */
     894           4 :                         break;
     895           8 :                 default:
     896           8 :                         goto error;
     897           4 :                 }
     898           4 :                 break;
     899          16 :         case SetPortFeature:
     900           4 :                 selector = wIndex >> 8;
     901           4 :                 wIndex &= 0xff;
     902          20 :                 if (unlikely(ehci->debug)) {
     903             :                         /* If the debug port is active any port
     904             :                          * feature requests should get denied */
     905          24 :                         if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
     906             :                             (readl(&ehci->debug->control) & DBGP_ENABLED)) {
     907           4 :                                 retval = -ENODEV;
     908           4 :                                 goto error_exit;
     909             :                         }
     910             :                 }
     911          32 :                 if (!wIndex || wIndex > ports)
     912           8 :                         goto error;
     913           8 :                 wIndex--;
     914          16 :                 temp = ehci_readl(ehci, status_reg);
     915           8 :                 if (temp & PORT_OWNER)
     916           4 :                         break;
     917             : 
     918           4 :                 temp &= ~PORT_RWC_BITS;
     919             :                 switch (wValue) {
     920          12 :                 case USB_PORT_FEAT_SUSPEND:
     921           8 :                         if (ehci->no_selective_suspend)
     922           4 :                                 break;
     923           8 :                         if ((temp & PORT_PE) == 0
     924             :                                         || (temp & PORT_RESET) != 0)
     925           4 :                                 goto error;
     926             : 
     927             :                         /* After above check the port must be connected.
     928             :                          * Set appropriate bit thus could put phy into low power
     929             :                          * mode if we have hostpc feature
     930             :                          */
     931           4 :                         temp &= ~PORT_WKCONN_E;
     932           4 :                         temp |= PORT_WKDISC_E | PORT_WKOC_E;
     933           8 :                         ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
     934           8 :                         if (hostpc_reg) {
     935           8 :                                 spin_unlock_irqrestore(&ehci->lock, flags);
     936           4 :                                 msleep(5);/* 5ms for HCD enter low pwr mode */
     937          12 :                                 spin_lock_irqsave(&ehci->lock, flags);
     938           8 :                                 temp1 = ehci_readl(ehci, hostpc_reg);
     939           8 :                                 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
     940             :                                         hostpc_reg);
     941           8 :                                 temp1 = ehci_readl(ehci, hostpc_reg);
     942             :                                 ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
     943             :                                         wIndex, (temp1 & HOSTPC_PHCD) ?
     944             :                                         "succeeded" : "failed");
     945             :                         }
     946          16 :                         set_bit(wIndex, &ehci->suspended_ports);
     947           4 :                         break;
     948          16 :                 case USB_PORT_FEAT_POWER:
     949           8 :                         if (HCS_PPC (ehci->hcs_params))
     950           8 :                                 ehci_writel(ehci, temp | PORT_POWER,
     951             :                                                 status_reg);
     952           8 :                         break;
     953          16 :                 case USB_PORT_FEAT_RESET:
     954           8 :                         if (temp & PORT_RESUME)
     955           4 :                                 goto error;
     956             :                         /* line status bits may report this as low speed,
     957             :                          * which can be fine if this root hub has a
     958             :                          * transaction translator built in.
     959             :                          */
     960          32 :                         if ((temp & (PORT_PE|PORT_CONNECT)) == PORT_CONNECT
     961             :                                         && !ehci_is_TDI(ehci)
     962             :                                         && PORT_USB11 (temp)) {
     963             :                                 ehci_dbg (ehci,
     964             :                                         "port %d low speed --> companion\n",
     965             :                                         wIndex + 1);
     966           4 :                                 temp |= PORT_OWNER;
     967             :                         } else {
     968             :                                 ehci_vdbg (ehci, "port %d reset\n", wIndex + 1);
     969          12 :                                 temp |= PORT_RESET;
     970          12 :                                 temp &= ~PORT_PE;
     971             : 
     972             :                                 /*
     973             :                                  * caller must wait, then call GetPortStatus
     974             :                                  * usb 2.0 spec says 50 ms resets on root
     975             :                                  */
     976          24 :                                 ehci->reset_done [wIndex] = jiffies
     977             :                                                 + msecs_to_jiffies (50);
     978             :                         }
     979          16 :                         ehci_writel(ehci, temp, status_reg);
     980           4 :                         break;
     981           4 : 
     982             :                 /* For downstream facing ports (these):  one hub port is put
     983             :                  * into test mode according to USB2 11.24.2.13, then the hub
     984             :                  * must be reset (which for root hub now means rmmod+modprobe,
     985             :                  * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
     986             :                  * about the EHCI-specific stuff.
     987             :                  */
     988          12 :                 case USB_PORT_FEAT_TEST:
     989           8 :                         if (!selector || selector > 5)
     990           4 :                                 goto error;
     991          12 :                         ehci_quiesce(ehci);
     992          12 :                         ehci_halt(ehci);
     993           4 :                         temp |= selector << 16;
     994           8 :                         ehci_writel(ehci, temp, status_reg);
     995           4 :                         break;
     996           4 : 
     997           4 :                 default:
     998           8 :                         goto error;
     999             :                 }
    1000          40 :                 ehci_readl(ehci, &ehci->regs->command);       /* unblock posted writes */
    1001           4 :                 break;
    1002           4 : 
    1003           8 :         default:
    1004           4 : error:
    1005             :                 /* "stall" on error */
    1006          28 :                 retval = -EPIPE;
    1007          28 :         }
    1008             : error_exit:
    1009         116 :         spin_unlock_irqrestore (&ehci->lock, flags);
    1010          48 :         return retval;
    1011             : }
    1012             : 
    1013             : static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
    1014             : {
    1015           4 :         struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
    1016           1 : 
    1017           5 :         if (ehci_is_TDI(ehci))
    1018           1 :                 return;
    1019           3 :         set_owner(ehci, --portnum, PORT_OWNER);
    1020           1 : }
    1021             : 
    1022             : static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
    1023             : {
    1024           4 :         struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
    1025           1 :         u32 __iomem             *reg;
    1026           1 : 
    1027           5 :         if (ehci_is_TDI(ehci))
    1028           2 :                 return 0;
    1029           1 :         reg = &ehci->regs->port_status[portnum - 1];
    1030           3 :         return ehci_readl(ehci, reg) & PORT_OWNER;
    1031             : }

Generated by: LCOV version 1.10