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