0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define dbg_port(hc,label,num,value) \
0018 ohci_dbg (hc, \
0019 "%s roothub.portstatus [%d] " \
0020 "= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
0021 label, num, value, \
0022 (value & RH_PS_PRSC) ? " PRSC" : "", \
0023 (value & RH_PS_OCIC) ? " OCIC" : "", \
0024 (value & RH_PS_PSSC) ? " PSSC" : "", \
0025 (value & RH_PS_PESC) ? " PESC" : "", \
0026 (value & RH_PS_CSC) ? " CSC" : "", \
0027 \
0028 (value & RH_PS_LSDA) ? " LSDA" : "", \
0029 (value & RH_PS_PPS) ? " PPS" : "", \
0030 (value & RH_PS_PRS) ? " PRS" : "", \
0031 (value & RH_PS_POCI) ? " POCI" : "", \
0032 (value & RH_PS_PSS) ? " PSS" : "", \
0033 \
0034 (value & RH_PS_PES) ? " PES" : "", \
0035 (value & RH_PS_CCS) ? " CCS" : "" \
0036 );
0037
0038
0039
0040 #define OHCI_SCHED_ENABLES \
0041 (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
0042
0043 static void update_done_list(struct ohci_hcd *);
0044 static void ohci_work(struct ohci_hcd *);
0045
0046 #ifdef CONFIG_PM
0047 static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
0048 __releases(ohci->lock)
0049 __acquires(ohci->lock)
0050 {
0051 int status = 0;
0052
0053 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
0054 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
0055 case OHCI_USB_RESUME:
0056 ohci_dbg (ohci, "resume/suspend?\n");
0057 ohci->hc_control &= ~OHCI_CTRL_HCFS;
0058 ohci->hc_control |= OHCI_USB_RESET;
0059 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
0060 (void) ohci_readl (ohci, &ohci->regs->control);
0061 fallthrough;
0062 case OHCI_USB_RESET:
0063 status = -EBUSY;
0064 ohci_dbg (ohci, "needs reinit!\n");
0065 goto done;
0066 case OHCI_USB_SUSPEND:
0067 if (!ohci->autostop) {
0068 ohci_dbg (ohci, "already suspended\n");
0069 goto done;
0070 }
0071 }
0072 ohci_dbg (ohci, "%s root hub\n",
0073 autostop ? "auto-stop" : "suspend");
0074
0075
0076 if (!autostop && (ohci->hc_control & OHCI_SCHED_ENABLES)) {
0077 ohci->hc_control &= ~OHCI_SCHED_ENABLES;
0078 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
0079 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
0080 ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrstatus);
0081
0082
0083
0084
0085 ohci_dbg (ohci, "stopping schedules ...\n");
0086 ohci->autostop = 0;
0087 spin_unlock_irq (&ohci->lock);
0088 msleep (8);
0089 spin_lock_irq (&ohci->lock);
0090 }
0091 update_done_list(ohci);
0092 ohci_work(ohci);
0093
0094
0095 ohci_writel(ohci, OHCI_INTR_SF, &ohci->regs->intrdisable);
0096
0097
0098
0099
0100
0101
0102 if (ohci->flags & OHCI_QUIRK_GLOBAL_SUSPEND) {
0103 __hc32 __iomem *portstat = ohci->regs->roothub.portstatus;
0104 int i;
0105 unsigned temp;
0106
0107 for (i = 0; i < ohci->num_ports; (++i, ++portstat)) {
0108 temp = ohci_readl(ohci, portstat);
0109 if ((temp & (RH_PS_PES | RH_PS_PSS)) ==
0110 RH_PS_PES)
0111 ohci_writel(ohci, RH_PS_PSS, portstat);
0112 }
0113 }
0114
0115
0116 if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {
0117 ohci->hc_control |= OHCI_CTRL_RWE;
0118 } else {
0119 ohci_writel(ohci, OHCI_INTR_RHSC | OHCI_INTR_RD,
0120 &ohci->regs->intrdisable);
0121 ohci->hc_control &= ~OHCI_CTRL_RWE;
0122 }
0123
0124
0125
0126
0127 ohci->hc_control &= ~OHCI_CTRL_HCFS;
0128 ohci->hc_control |= OHCI_USB_SUSPEND;
0129 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
0130 (void) ohci_readl (ohci, &ohci->regs->control);
0131
0132
0133 if (!autostop) {
0134 ohci->next_statechange = jiffies + msecs_to_jiffies (5);
0135 ohci->autostop = 0;
0136 ohci->rh_state = OHCI_RH_SUSPENDED;
0137 }
0138
0139 done:
0140 return status;
0141 }
0142
0143 static inline struct ed *find_head (struct ed *ed)
0144 {
0145
0146 while (ed->ed_prev)
0147 ed = ed->ed_prev;
0148 return ed;
0149 }
0150
0151
0152 static int ohci_rh_resume (struct ohci_hcd *ohci)
0153 __releases(ohci->lock)
0154 __acquires(ohci->lock)
0155 {
0156 struct usb_hcd *hcd = ohci_to_hcd (ohci);
0157 u32 temp, enables;
0158 int status = -EINPROGRESS;
0159 int autostopped = ohci->autostop;
0160
0161 ohci->autostop = 0;
0162 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
0163
0164 if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
0165
0166 if (ohci->rh_state != OHCI_RH_RUNNING) {
0167 ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
0168 ohci->hc_control);
0169 status = -EBUSY;
0170
0171 } else {
0172 ohci_dbg (ohci, "duplicate resume\n");
0173 status = 0;
0174 }
0175 } else switch (ohci->hc_control & OHCI_CTRL_HCFS) {
0176 case OHCI_USB_SUSPEND:
0177 ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES);
0178 ohci->hc_control |= OHCI_USB_RESUME;
0179 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
0180 (void) ohci_readl (ohci, &ohci->regs->control);
0181 ohci_dbg (ohci, "%s root hub\n",
0182 autostopped ? "auto-start" : "resume");
0183 break;
0184 case OHCI_USB_RESUME:
0185
0186 ohci_dbg(ohci, "%swakeup root hub\n",
0187 autostopped ? "auto-" : "");
0188 break;
0189 case OHCI_USB_OPER:
0190
0191 ohci_dbg (ohci, "snapshot resume? reinit\n");
0192 status = -EBUSY;
0193 break;
0194 default:
0195 ohci_dbg (ohci, "lost power\n");
0196 status = -EBUSY;
0197 }
0198 if (status == -EBUSY) {
0199 if (!autostopped) {
0200 spin_unlock_irq (&ohci->lock);
0201 status = ohci_restart (ohci);
0202
0203 usb_root_hub_lost_power(hcd->self.root_hub);
0204
0205 spin_lock_irq (&ohci->lock);
0206 }
0207 return status;
0208 }
0209 if (status != -EINPROGRESS)
0210 return status;
0211 if (autostopped)
0212 goto skip_resume;
0213 spin_unlock_irq (&ohci->lock);
0214
0215
0216 msleep (20 + 12 + 1);
0217
0218 temp = ohci_readl (ohci, &ohci->regs->control);
0219 temp &= OHCI_CTRL_HCFS;
0220 if (temp != OHCI_USB_RESUME) {
0221 ohci_err (ohci, "controller won't resume\n");
0222 spin_lock_irq(&ohci->lock);
0223 return -EBUSY;
0224 }
0225
0226
0227 ohci_writel (ohci, 0, &ohci->regs->ed_controlhead);
0228 ohci_writel (ohci, 0, &ohci->regs->ed_controlcurrent);
0229 ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead);
0230 ohci_writel (ohci, 0, &ohci->regs->ed_bulkcurrent);
0231 ohci_writel (ohci, 0, &ohci->regs->ed_periodcurrent);
0232 ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
0233
0234
0235 periodic_reinit (ohci);
0236
0237
0238
0239
0240
0241
0242 skip_resume:
0243
0244 ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
0245 if (ohci->ed_rm_list)
0246 ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
0247
0248
0249 ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
0250 (void) ohci_readl (ohci, &ohci->regs->control);
0251 if (!autostopped)
0252 msleep (3);
0253
0254 temp = ohci->hc_control;
0255 temp &= OHCI_CTRL_RWC;
0256 temp |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
0257 ohci->hc_control = temp;
0258 ohci_writel (ohci, temp, &ohci->regs->control);
0259 (void) ohci_readl (ohci, &ohci->regs->control);
0260
0261
0262 if (!autostopped) {
0263 msleep (10);
0264 spin_lock_irq (&ohci->lock);
0265 }
0266
0267
0268
0269 ohci->next_statechange = jiffies + STATECHANGE_DELAY;
0270
0271
0272 enables = 0;
0273 temp = 0;
0274 if (!ohci->ed_rm_list) {
0275 if (ohci->ed_controltail) {
0276 ohci_writel (ohci,
0277 find_head (ohci->ed_controltail)->dma,
0278 &ohci->regs->ed_controlhead);
0279 enables |= OHCI_CTRL_CLE;
0280 temp |= OHCI_CLF;
0281 }
0282 if (ohci->ed_bulktail) {
0283 ohci_writel (ohci, find_head (ohci->ed_bulktail)->dma,
0284 &ohci->regs->ed_bulkhead);
0285 enables |= OHCI_CTRL_BLE;
0286 temp |= OHCI_BLF;
0287 }
0288 }
0289 if (hcd->self.bandwidth_isoc_reqs || hcd->self.bandwidth_int_reqs)
0290 enables |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
0291 if (enables) {
0292 ohci_dbg (ohci, "restarting schedules ... %08x\n", enables);
0293 ohci->hc_control |= enables;
0294 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
0295 if (temp)
0296 ohci_writel (ohci, temp, &ohci->regs->cmdstatus);
0297 (void) ohci_readl (ohci, &ohci->regs->control);
0298 }
0299
0300 ohci->rh_state = OHCI_RH_RUNNING;
0301 return 0;
0302 }
0303
0304 static int ohci_bus_suspend (struct usb_hcd *hcd)
0305 {
0306 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
0307 int rc;
0308
0309 spin_lock_irq (&ohci->lock);
0310
0311 if (unlikely(!HCD_HW_ACCESSIBLE(hcd)))
0312 rc = -ESHUTDOWN;
0313 else
0314 rc = ohci_rh_suspend (ohci, 0);
0315 spin_unlock_irq (&ohci->lock);
0316
0317 if (rc == 0) {
0318 del_timer_sync(&ohci->io_watchdog);
0319 ohci->prev_frame_no = IO_WATCHDOG_OFF;
0320 }
0321 return rc;
0322 }
0323
0324 static int ohci_bus_resume (struct usb_hcd *hcd)
0325 {
0326 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
0327 int rc;
0328
0329 if (time_before (jiffies, ohci->next_statechange))
0330 msleep(5);
0331
0332 spin_lock_irq (&ohci->lock);
0333
0334 if (unlikely(!HCD_HW_ACCESSIBLE(hcd)))
0335 rc = -ESHUTDOWN;
0336 else
0337 rc = ohci_rh_resume (ohci);
0338 spin_unlock_irq (&ohci->lock);
0339
0340
0341 if (rc == 0)
0342 usb_hcd_poll_rh_status(hcd);
0343 return rc;
0344 }
0345
0346
0347 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
0348 int any_connected, int rhsc_status)
0349 {
0350 int poll_rh = 1;
0351 int rhsc_enable;
0352
0353
0354
0355
0356
0357 rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
0358 OHCI_INTR_RHSC;
0359
0360 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
0361 case OHCI_USB_OPER:
0362
0363 if (!rhsc_enable && !rhsc_status && !changed) {
0364 rhsc_enable = OHCI_INTR_RHSC;
0365 ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
0366 }
0367
0368
0369
0370
0371 if (!ohci->autostop) {
0372 if (any_connected ||
0373 !device_may_wakeup(&ohci_to_hcd(ohci)
0374 ->self.root_hub->dev)) {
0375 if (rhsc_enable)
0376 poll_rh = 0;
0377 } else {
0378 ohci->autostop = 1;
0379 ohci->next_statechange = jiffies + HZ;
0380 }
0381
0382
0383 } else {
0384 if (changed || any_connected) {
0385 ohci->autostop = 0;
0386 ohci->next_statechange = jiffies +
0387 STATECHANGE_DELAY;
0388 } else if (time_after_eq(jiffies,
0389 ohci->next_statechange)
0390 && !ohci->ed_rm_list
0391 && !(ohci->hc_control &
0392 OHCI_SCHED_ENABLES)) {
0393 ohci_rh_suspend(ohci, 1);
0394 if (rhsc_enable)
0395 poll_rh = 0;
0396 }
0397 }
0398 break;
0399
0400 case OHCI_USB_SUSPEND:
0401 case OHCI_USB_RESUME:
0402
0403 if (changed) {
0404 if (ohci->autostop)
0405 ohci_rh_resume(ohci);
0406 else
0407 usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
0408
0409
0410 } else if (!ohci->autostop &&
0411 !ohci_to_hcd(ohci)->self.root_hub->
0412 do_remote_wakeup) {
0413 poll_rh = 0;
0414
0415 } else {
0416
0417
0418
0419 if (!rhsc_enable && !rhsc_status) {
0420 rhsc_enable = OHCI_INTR_RHSC;
0421 ohci_writel(ohci, rhsc_enable,
0422 &ohci->regs->intrenable);
0423 }
0424
0425 if (rhsc_enable)
0426 poll_rh = 0;
0427 }
0428 break;
0429 }
0430 return poll_rh;
0431 }
0432
0433 #else
0434
0435 static inline int ohci_rh_resume(struct ohci_hcd *ohci)
0436 {
0437 return 0;
0438 }
0439
0440
0441
0442
0443 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
0444 int any_connected, int rhsc_status)
0445 {
0446
0447 if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
0448 return 0;
0449
0450
0451
0452
0453
0454 if (changed || rhsc_status)
0455 return 1;
0456
0457
0458 ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
0459 return 0;
0460 }
0461
0462 #endif
0463
0464
0465
0466
0467
0468 int ohci_hub_status_data(struct usb_hcd *hcd, char *buf)
0469 {
0470 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
0471 int i, changed = 0, length = 1;
0472 int any_connected = 0;
0473 int rhsc_status;
0474 unsigned long flags;
0475
0476 spin_lock_irqsave (&ohci->lock, flags);
0477 if (!HCD_HW_ACCESSIBLE(hcd))
0478 goto done;
0479
0480
0481 if ((ohci->flags & OHCI_QUIRK_AMD756)
0482 && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) {
0483 ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n",
0484 ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
0485
0486 goto done;
0487 }
0488
0489
0490 if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
0491 buf [0] = changed = 1;
0492 else
0493 buf [0] = 0;
0494 if (ohci->num_ports > 7) {
0495 buf [1] = 0;
0496 length++;
0497 }
0498
0499
0500 ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
0501 rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
0502 OHCI_INTR_RHSC;
0503
0504
0505 for (i = 0; i < ohci->num_ports; i++) {
0506 u32 status = roothub_portstatus (ohci, i);
0507
0508
0509 any_connected |= (status & RH_PS_CCS);
0510
0511 if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
0512 | RH_PS_OCIC | RH_PS_PRSC)) {
0513 changed = 1;
0514 if (i < 7)
0515 buf [0] |= 1 << (i + 1);
0516 else
0517 buf [1] |= 1 << (i - 7);
0518 }
0519 }
0520
0521 if (ohci_root_hub_state_changes(ohci, changed,
0522 any_connected, rhsc_status))
0523 set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
0524 else
0525 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
0526
0527
0528 done:
0529 spin_unlock_irqrestore (&ohci->lock, flags);
0530
0531 return changed ? length : 0;
0532 }
0533 EXPORT_SYMBOL_GPL(ohci_hub_status_data);
0534
0535
0536
0537 static void
0538 ohci_hub_descriptor (
0539 struct ohci_hcd *ohci,
0540 struct usb_hub_descriptor *desc
0541 ) {
0542 u32 rh = roothub_a (ohci);
0543 u16 temp;
0544
0545 desc->bDescriptorType = USB_DT_HUB;
0546 desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
0547 desc->bHubContrCurrent = 0;
0548
0549 desc->bNbrPorts = ohci->num_ports;
0550 temp = 1 + (ohci->num_ports / 8);
0551 desc->bDescLength = 7 + 2 * temp;
0552
0553 temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM;
0554 if (rh & RH_A_NPS)
0555 temp |= HUB_CHAR_NO_LPSM;
0556 if (rh & RH_A_PSM)
0557 temp |= HUB_CHAR_INDV_PORT_LPSM;
0558 if (rh & RH_A_NOCP)
0559 temp |= HUB_CHAR_NO_OCPM;
0560 else if (rh & RH_A_OCPM)
0561 temp |= HUB_CHAR_INDV_PORT_OCPM;
0562 desc->wHubCharacteristics = cpu_to_le16(temp);
0563
0564
0565 rh = roothub_b (ohci);
0566 memset(desc->u.hs.DeviceRemovable, 0xff,
0567 sizeof(desc->u.hs.DeviceRemovable));
0568 desc->u.hs.DeviceRemovable[0] = rh & RH_B_DR;
0569 if (ohci->num_ports > 7) {
0570 desc->u.hs.DeviceRemovable[1] = (rh & RH_B_DR) >> 8;
0571 desc->u.hs.DeviceRemovable[2] = 0xff;
0572 } else
0573 desc->u.hs.DeviceRemovable[1] = 0xff;
0574 }
0575
0576
0577
0578 #ifdef CONFIG_USB_OTG
0579
0580 static int ohci_start_port_reset (struct usb_hcd *hcd, unsigned port)
0581 {
0582 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
0583 u32 status;
0584
0585 if (!port)
0586 return -EINVAL;
0587 port--;
0588
0589
0590 status = ohci_readl(ohci, &ohci->regs->roothub.portstatus [port]);
0591 if (!(status & RH_PS_CCS))
0592 return -ENODEV;
0593
0594
0595 ohci_writel(ohci, RH_PS_PRS, &ohci->regs->roothub.portstatus [port]);
0596 return 0;
0597 }
0598
0599 #else
0600
0601 #define ohci_start_port_reset NULL
0602
0603 #endif
0604
0605
0606
0607
0608
0609
0610
0611 #define PORT_RESET_MSEC 50
0612
0613
0614 #define PORT_RESET_HW_MSEC 10
0615
0616
0617 #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0)
0618
0619
0620 static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)
0621 {
0622 __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
0623 u32 temp = 0;
0624 u16 now = ohci_readl(ohci, &ohci->regs->fmnumber);
0625 u16 reset_done = now + PORT_RESET_MSEC;
0626 int limit_1 = DIV_ROUND_UP(PORT_RESET_MSEC, PORT_RESET_HW_MSEC);
0627
0628
0629
0630
0631
0632 do {
0633 int limit_2;
0634
0635
0636 limit_2 = PORT_RESET_HW_MSEC * 2;
0637 while (--limit_2 >= 0) {
0638 temp = ohci_readl (ohci, portstat);
0639
0640 if (temp == ~(u32)0)
0641 return -ESHUTDOWN;
0642 if (!(temp & RH_PS_PRS))
0643 break;
0644 udelay (500);
0645 }
0646
0647
0648
0649
0650
0651 if (limit_2 < 0) {
0652 ohci_dbg(ohci,
0653 "port[%d] reset timeout, stat %08x\n",
0654 port, temp);
0655 break;
0656 }
0657
0658 if (!(temp & RH_PS_CCS))
0659 break;
0660 if (temp & RH_PS_PRSC)
0661 ohci_writel (ohci, RH_PS_PRSC, portstat);
0662
0663
0664 ohci_writel (ohci, RH_PS_PRS, portstat);
0665 msleep(PORT_RESET_HW_MSEC);
0666 now = ohci_readl(ohci, &ohci->regs->fmnumber);
0667 } while (tick_before(now, reset_done) && --limit_1 >= 0);
0668
0669
0670
0671
0672
0673 return 0;
0674 }
0675
0676 int ohci_hub_control(
0677 struct usb_hcd *hcd,
0678 u16 typeReq,
0679 u16 wValue,
0680 u16 wIndex,
0681 char *buf,
0682 u16 wLength
0683 ) {
0684 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
0685 int ports = ohci->num_ports;
0686 u32 temp;
0687 int retval = 0;
0688
0689 if (unlikely(!HCD_HW_ACCESSIBLE(hcd)))
0690 return -ESHUTDOWN;
0691
0692 switch (typeReq) {
0693 case ClearHubFeature:
0694 switch (wValue) {
0695 case C_HUB_OVER_CURRENT:
0696 ohci_writel (ohci, RH_HS_OCIC,
0697 &ohci->regs->roothub.status);
0698 break;
0699 case C_HUB_LOCAL_POWER:
0700 break;
0701 default:
0702 goto error;
0703 }
0704 break;
0705 case ClearPortFeature:
0706 if (!wIndex || wIndex > ports)
0707 goto error;
0708 wIndex--;
0709
0710 switch (wValue) {
0711 case USB_PORT_FEAT_ENABLE:
0712 temp = RH_PS_CCS;
0713 break;
0714 case USB_PORT_FEAT_C_ENABLE:
0715 temp = RH_PS_PESC;
0716 break;
0717 case USB_PORT_FEAT_SUSPEND:
0718 temp = RH_PS_POCI;
0719 break;
0720 case USB_PORT_FEAT_C_SUSPEND:
0721 temp = RH_PS_PSSC;
0722 break;
0723 case USB_PORT_FEAT_POWER:
0724 temp = RH_PS_LSDA;
0725 break;
0726 case USB_PORT_FEAT_C_CONNECTION:
0727 temp = RH_PS_CSC;
0728 break;
0729 case USB_PORT_FEAT_C_OVER_CURRENT:
0730 temp = RH_PS_OCIC;
0731 break;
0732 case USB_PORT_FEAT_C_RESET:
0733 temp = RH_PS_PRSC;
0734 break;
0735 default:
0736 goto error;
0737 }
0738 ohci_writel (ohci, temp,
0739 &ohci->regs->roothub.portstatus [wIndex]);
0740
0741 break;
0742 case GetHubDescriptor:
0743 ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
0744 break;
0745 case GetHubStatus:
0746 temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
0747 put_unaligned_le32(temp, buf);
0748 break;
0749 case GetPortStatus:
0750 if (!wIndex || wIndex > ports)
0751 goto error;
0752 wIndex--;
0753 temp = roothub_portstatus (ohci, wIndex);
0754 put_unaligned_le32(temp, buf);
0755
0756 if (*(u16*)(buf+2))
0757 dbg_port(ohci, "GetStatus", wIndex, temp);
0758 break;
0759 case SetHubFeature:
0760 switch (wValue) {
0761 case C_HUB_OVER_CURRENT:
0762
0763 case C_HUB_LOCAL_POWER:
0764 break;
0765 default:
0766 goto error;
0767 }
0768 break;
0769 case SetPortFeature:
0770 if (!wIndex || wIndex > ports)
0771 goto error;
0772 wIndex--;
0773 switch (wValue) {
0774 case USB_PORT_FEAT_SUSPEND:
0775 #ifdef CONFIG_USB_OTG
0776 if (hcd->self.otg_port == (wIndex + 1)
0777 && hcd->self.b_hnp_enable)
0778 ohci->start_hnp(ohci);
0779 else
0780 #endif
0781 ohci_writel (ohci, RH_PS_PSS,
0782 &ohci->regs->roothub.portstatus [wIndex]);
0783 break;
0784 case USB_PORT_FEAT_POWER:
0785 ohci_writel (ohci, RH_PS_PPS,
0786 &ohci->regs->roothub.portstatus [wIndex]);
0787 break;
0788 case USB_PORT_FEAT_RESET:
0789 retval = root_port_reset (ohci, wIndex);
0790 break;
0791 default:
0792 goto error;
0793 }
0794 break;
0795
0796 default:
0797 error:
0798
0799 retval = -EPIPE;
0800 }
0801 return retval;
0802 }
0803 EXPORT_SYMBOL_GPL(ohci_hub_control);