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