0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 static const __u8 root_hub_hub_des[] =
0017 {
0018 0x09,
0019 USB_DT_HUB,
0020 0x02,
0021 HUB_CHAR_NO_LPSM |
0022 HUB_CHAR_INDV_PORT_OCPM,
0023 0x00,
0024 0x01,
0025 0x00,
0026 0x00,
0027 0xff
0028 };
0029
0030 #define UHCI_RH_MAXCHILD 7
0031
0032
0033 #define WZ_BITS (USBPORTSC_RES2 | USBPORTSC_RES3 | USBPORTSC_RES4)
0034
0035
0036 #define RWC_BITS (USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
0037
0038
0039 #define SUSPEND_BITS (USBPORTSC_SUSP | USBPORTSC_RD)
0040
0041
0042
0043
0044 static int any_ports_active(struct uhci_hcd *uhci)
0045 {
0046 int port;
0047
0048 for (port = 0; port < uhci->rh_numports; ++port) {
0049 if ((uhci_readw(uhci, USBPORTSC1 + port * 2) &
0050 (USBPORTSC_CCS | RWC_BITS)) ||
0051 test_bit(port, &uhci->port_c_suspend))
0052 return 1;
0053 }
0054 return 0;
0055 }
0056
0057 static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
0058 {
0059 int port;
0060 int mask = RWC_BITS;
0061
0062
0063
0064
0065
0066
0067
0068 if (ignore_oc)
0069 mask &= ~USBPORTSC_OCC;
0070
0071 *buf = 0;
0072 for (port = 0; port < uhci->rh_numports; ++port) {
0073 if ((uhci_readw(uhci, USBPORTSC1 + port * 2) & mask) ||
0074 test_bit(port, &uhci->port_c_suspend))
0075 *buf |= (1 << (port + 1));
0076 }
0077 return !!*buf;
0078 }
0079
0080 #define CLR_RH_PORTSTAT(x) \
0081 status = uhci_readw(uhci, port_addr); \
0082 status &= ~(RWC_BITS|WZ_BITS); \
0083 status &= ~(x); \
0084 status |= RWC_BITS & (x); \
0085 uhci_writew(uhci, status, port_addr)
0086
0087 #define SET_RH_PORTSTAT(x) \
0088 status = uhci_readw(uhci, port_addr); \
0089 status |= (x); \
0090 status &= ~(RWC_BITS|WZ_BITS); \
0091 uhci_writew(uhci, status, port_addr)
0092
0093
0094
0095
0096 static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
0097 unsigned long port_addr)
0098 {
0099 int status;
0100 int i;
0101
0102 if (uhci_readw(uhci, port_addr) & SUSPEND_BITS) {
0103 CLR_RH_PORTSTAT(SUSPEND_BITS);
0104 if (test_bit(port, &uhci->resuming_ports))
0105 set_bit(port, &uhci->port_c_suspend);
0106
0107
0108
0109
0110
0111
0112 for (i = 0; i < 10; ++i) {
0113 if (!(uhci_readw(uhci, port_addr) & SUSPEND_BITS))
0114 break;
0115 udelay(1);
0116 }
0117 }
0118 clear_bit(port, &uhci->resuming_ports);
0119 usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);
0120 }
0121
0122
0123
0124
0125 static void wait_for_HP(struct uhci_hcd *uhci, unsigned long port_addr)
0126 {
0127 int i;
0128
0129 for (i = 10; i < 250; i += 10) {
0130 if (uhci_readw(uhci, port_addr) & USBPORTSC_CSC)
0131 return;
0132 udelay(10);
0133 }
0134
0135 }
0136
0137 static void uhci_check_ports(struct uhci_hcd *uhci)
0138 {
0139 unsigned int port;
0140 unsigned long port_addr;
0141 int status;
0142
0143 for (port = 0; port < uhci->rh_numports; ++port) {
0144 port_addr = USBPORTSC1 + 2 * port;
0145 status = uhci_readw(uhci, port_addr);
0146 if (unlikely(status & USBPORTSC_PR)) {
0147 if (time_after_eq(jiffies, uhci->ports_timeout)) {
0148 CLR_RH_PORTSTAT(USBPORTSC_PR);
0149 udelay(10);
0150
0151
0152
0153 if (uhci->wait_for_hp)
0154 wait_for_HP(uhci, port_addr);
0155
0156
0157
0158
0159
0160 CLR_RH_PORTSTAT(USBPORTSC_CSC | USBPORTSC_PEC);
0161 SET_RH_PORTSTAT(USBPORTSC_PE);
0162 }
0163 }
0164 if (unlikely(status & USBPORTSC_RD)) {
0165 if (!test_bit(port, &uhci->resuming_ports)) {
0166
0167
0168 set_bit(port, &uhci->resuming_ports);
0169 uhci->ports_timeout = jiffies +
0170 msecs_to_jiffies(USB_RESUME_TIMEOUT);
0171 usb_hcd_start_port_resume(
0172 &uhci_to_hcd(uhci)->self, port);
0173
0174
0175
0176 mod_timer(&uhci_to_hcd(uhci)->rh_timer,
0177 uhci->ports_timeout);
0178 } else if (time_after_eq(jiffies,
0179 uhci->ports_timeout)) {
0180 uhci_finish_suspend(uhci, port, port_addr);
0181 }
0182 }
0183 }
0184 }
0185
0186 static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
0187 {
0188 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0189 unsigned long flags;
0190 int status = 0;
0191
0192 spin_lock_irqsave(&uhci->lock, flags);
0193
0194 uhci_scan_schedule(uhci);
0195 if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
0196 goto done;
0197 uhci_check_ports(uhci);
0198
0199 status = get_hub_status_data(uhci, buf);
0200
0201 switch (uhci->rh_state) {
0202 case UHCI_RH_SUSPENDED:
0203
0204 if (status || uhci->resuming_ports) {
0205 status = 1;
0206 usb_hcd_resume_root_hub(hcd);
0207 }
0208 break;
0209
0210 case UHCI_RH_AUTO_STOPPED:
0211
0212 if (status)
0213 wakeup_rh(uhci);
0214 break;
0215
0216 case UHCI_RH_RUNNING:
0217
0218 if (!any_ports_active(uhci)) {
0219 uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
0220 uhci->auto_stop_time = jiffies + HZ;
0221 }
0222 break;
0223
0224 case UHCI_RH_RUNNING_NODEVS:
0225
0226 if (any_ports_active(uhci))
0227 uhci->rh_state = UHCI_RH_RUNNING;
0228 else if (time_after_eq(jiffies, uhci->auto_stop_time) &&
0229 !uhci->wait_for_hp)
0230 suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
0231 break;
0232
0233 default:
0234 break;
0235 }
0236
0237 done:
0238 spin_unlock_irqrestore(&uhci->lock, flags);
0239 return status;
0240 }
0241
0242
0243 static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
0244 u16 wIndex, char *buf, u16 wLength)
0245 {
0246 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0247 int status, lstatus, retval = 0;
0248 unsigned int port = wIndex - 1;
0249 unsigned long port_addr = USBPORTSC1 + 2 * port;
0250 u16 wPortChange, wPortStatus;
0251 unsigned long flags;
0252
0253 if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
0254 return -ETIMEDOUT;
0255
0256 spin_lock_irqsave(&uhci->lock, flags);
0257 switch (typeReq) {
0258
0259 case GetHubStatus:
0260 *(__le32 *)buf = cpu_to_le32(0);
0261 retval = 4;
0262 break;
0263 case GetPortStatus:
0264 if (port >= uhci->rh_numports)
0265 goto err;
0266
0267 uhci_check_ports(uhci);
0268 status = uhci_readw(uhci, port_addr);
0269
0270
0271
0272
0273
0274 if (uhci->oc_low)
0275 status ^= USBPORTSC_OC;
0276
0277
0278 wPortChange = lstatus = 0;
0279 if (status & USBPORTSC_CSC)
0280 wPortChange |= USB_PORT_STAT_C_CONNECTION;
0281 if (status & USBPORTSC_PEC)
0282 wPortChange |= USB_PORT_STAT_C_ENABLE;
0283 if ((status & USBPORTSC_OCC) && !ignore_oc)
0284 wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
0285
0286 if (test_bit(port, &uhci->port_c_suspend)) {
0287 wPortChange |= USB_PORT_STAT_C_SUSPEND;
0288 lstatus |= 1;
0289 }
0290 if (test_bit(port, &uhci->resuming_ports))
0291 lstatus |= 4;
0292
0293
0294 wPortStatus = USB_PORT_STAT_POWER;
0295 if (status & USBPORTSC_CCS)
0296 wPortStatus |= USB_PORT_STAT_CONNECTION;
0297 if (status & USBPORTSC_PE) {
0298 wPortStatus |= USB_PORT_STAT_ENABLE;
0299 if (status & SUSPEND_BITS)
0300 wPortStatus |= USB_PORT_STAT_SUSPEND;
0301 }
0302 if (status & USBPORTSC_OC)
0303 wPortStatus |= USB_PORT_STAT_OVERCURRENT;
0304 if (status & USBPORTSC_PR)
0305 wPortStatus |= USB_PORT_STAT_RESET;
0306 if (status & USBPORTSC_LSDA)
0307 wPortStatus |= USB_PORT_STAT_LOW_SPEED;
0308
0309 if (wPortChange)
0310 dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n",
0311 wIndex, status, lstatus);
0312
0313 *(__le16 *)buf = cpu_to_le16(wPortStatus);
0314 *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
0315 retval = 4;
0316 break;
0317 case SetHubFeature:
0318 case ClearHubFeature:
0319 switch (wValue) {
0320 case C_HUB_OVER_CURRENT:
0321 case C_HUB_LOCAL_POWER:
0322 break;
0323 default:
0324 goto err;
0325 }
0326 break;
0327 case SetPortFeature:
0328 if (port >= uhci->rh_numports)
0329 goto err;
0330
0331 switch (wValue) {
0332 case USB_PORT_FEAT_SUSPEND:
0333 SET_RH_PORTSTAT(USBPORTSC_SUSP);
0334 break;
0335 case USB_PORT_FEAT_RESET:
0336 SET_RH_PORTSTAT(USBPORTSC_PR);
0337
0338
0339 uhci_finish_suspend(uhci, port, port_addr);
0340
0341
0342 uhci->ports_timeout = jiffies +
0343 msecs_to_jiffies(USB_RESUME_TIMEOUT);
0344 break;
0345 case USB_PORT_FEAT_POWER:
0346
0347 break;
0348 default:
0349 goto err;
0350 }
0351 break;
0352 case ClearPortFeature:
0353 if (port >= uhci->rh_numports)
0354 goto err;
0355
0356 switch (wValue) {
0357 case USB_PORT_FEAT_ENABLE:
0358 CLR_RH_PORTSTAT(USBPORTSC_PE);
0359
0360
0361 uhci_finish_suspend(uhci, port, port_addr);
0362 break;
0363 case USB_PORT_FEAT_C_ENABLE:
0364 CLR_RH_PORTSTAT(USBPORTSC_PEC);
0365 break;
0366 case USB_PORT_FEAT_SUSPEND:
0367 if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) {
0368
0369
0370 uhci_finish_suspend(uhci, port, port_addr);
0371 } else if (!test_and_set_bit(port,
0372 &uhci->resuming_ports)) {
0373 SET_RH_PORTSTAT(USBPORTSC_RD);
0374
0375
0376
0377
0378
0379 if (!(uhci_readw(uhci, port_addr) &
0380 USBPORTSC_RD))
0381 uhci_finish_suspend(uhci, port,
0382 port_addr);
0383 else
0384
0385 uhci->ports_timeout = jiffies +
0386 msecs_to_jiffies(20);
0387 }
0388 break;
0389 case USB_PORT_FEAT_C_SUSPEND:
0390 clear_bit(port, &uhci->port_c_suspend);
0391 break;
0392 case USB_PORT_FEAT_POWER:
0393
0394 goto err;
0395 case USB_PORT_FEAT_C_CONNECTION:
0396 CLR_RH_PORTSTAT(USBPORTSC_CSC);
0397 break;
0398 case USB_PORT_FEAT_C_OVER_CURRENT:
0399 CLR_RH_PORTSTAT(USBPORTSC_OCC);
0400 break;
0401 case USB_PORT_FEAT_C_RESET:
0402
0403 break;
0404 default:
0405 goto err;
0406 }
0407 break;
0408 case GetHubDescriptor:
0409 retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
0410 memcpy(buf, root_hub_hub_des, retval);
0411 if (retval > 2)
0412 buf[2] = uhci->rh_numports;
0413 break;
0414 default:
0415 err:
0416 retval = -EPIPE;
0417 }
0418 spin_unlock_irqrestore(&uhci->lock, flags);
0419
0420 return retval;
0421 }