root/drivers/usb/host/ohci-hub.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ohci_rh_suspend
  2. find_head
  3. ohci_rh_resume
  4. ohci_bus_suspend
  5. ohci_bus_resume
  6. ohci_root_hub_state_changes
  7. ohci_rh_resume
  8. ohci_root_hub_state_changes
  9. ohci_hub_status_data
  10. ohci_hub_descriptor
  11. ohci_start_port_reset
  12. root_port_reset
  13. ohci_hub_control

   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 
  43 static void update_done_list(struct ohci_hcd *);
  44 static void ohci_work(struct ohci_hcd *);
  45 
  46 #ifdef  CONFIG_PM
  47 static 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 
 136 done:
 137         return status;
 138 }
 139 
 140 static 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 */
 149 static 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          */
 239 skip_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 
 301 static 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 
 321 static 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 */
 344 static 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 
 432 static 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  */
 440 static 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 
 465 int 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 
 525 done:
 526         spin_unlock_irqrestore (&ohci->lock, flags);
 527 
 528         return changed ? length : 0;
 529 }
 530 EXPORT_SYMBOL_GPL(ohci_hub_status_data);
 531 
 532 /*-------------------------------------------------------------------------*/
 533 
 534 static void
 535 ohci_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 
 577 static 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 */
 617 static 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 
 673 int 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:
 793 error:
 794                 /* "protocol stall" on error */
 795                 retval = -EPIPE;
 796         }
 797         return retval;
 798 }
 799 EXPORT_SYMBOL_GPL(ohci_hub_control);

/* [<][>][^][v][top][bottom][index][help] */