Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * Universal Host Controller Interface driver for USB.
4 : : *
5 : : * Maintainer: Alan Stern <stern@rowland.harvard.edu>
6 : : *
7 : : * (C) Copyright 1999 Linus Torvalds
8 : : * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
9 : : * (C) Copyright 1999 Randy Dunlap
10 : : * (C) Copyright 1999 Georg Acher, acher@in.tum.de
11 : : * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
12 : : * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch
13 : : * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu
14 : : */
15 : :
16 : : static const __u8 root_hub_hub_des[] =
17 : : {
18 : : 0x09, /* __u8 bLength; */
19 : : USB_DT_HUB, /* __u8 bDescriptorType; Hub-descriptor */
20 : : 0x02, /* __u8 bNbrPorts; */
21 : : HUB_CHAR_NO_LPSM | /* __u16 wHubCharacteristics; */
22 : : HUB_CHAR_INDV_PORT_OCPM, /* (per-port OC, no power switching) */
23 : : 0x00,
24 : : 0x01, /* __u8 bPwrOn2pwrGood; 2ms */
25 : : 0x00, /* __u8 bHubContrCurrent; 0 mA */
26 : : 0x00, /* __u8 DeviceRemovable; *** 7 Ports max */
27 : : 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max */
28 : : };
29 : :
30 : : #define UHCI_RH_MAXCHILD 7
31 : :
32 : : /* must write as zeroes */
33 : : #define WZ_BITS (USBPORTSC_RES2 | USBPORTSC_RES3 | USBPORTSC_RES4)
34 : :
35 : : /* status change bits: nonzero writes will clear */
36 : : #define RWC_BITS (USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
37 : :
38 : : /* suspend/resume bits: port suspended or port resuming */
39 : : #define SUSPEND_BITS (USBPORTSC_SUSP | USBPORTSC_RD)
40 : :
41 : : /* A port that either is connected or has a changed-bit set will prevent
42 : : * us from AUTO_STOPPING.
43 : : */
44 : 0 : static int any_ports_active(struct uhci_hcd *uhci)
45 : : {
46 : 0 : int port;
47 : :
48 [ # # ]: 0 : for (port = 0; port < uhci->rh_numports; ++port) {
49 [ # # ]: 0 : if ((uhci_readw(uhci, USBPORTSC1 + port * 2) &
50 [ # # ]: 0 : (USBPORTSC_CCS | RWC_BITS)) ||
51 : 0 : test_bit(port, &uhci->port_c_suspend))
52 : 0 : return 1;
53 : : }
54 : : return 0;
55 : : }
56 : :
57 : 0 : static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
58 : : {
59 : 0 : int port;
60 : 0 : int mask = RWC_BITS;
61 : :
62 : : /* Some boards (both VIA and Intel apparently) report bogus
63 : : * overcurrent indications, causing massive log spam unless
64 : : * we completely ignore them. This doesn't seem to be a problem
65 : : * with the chipset so much as with the way it is connected on
66 : : * the motherboard; if the overcurrent input is left to float
67 : : * then it may constantly register false positives. */
68 [ # # ]: 0 : if (ignore_oc)
69 : 0 : mask &= ~USBPORTSC_OCC;
70 : :
71 : 0 : *buf = 0;
72 [ # # ]: 0 : for (port = 0; port < uhci->rh_numports; ++port) {
73 [ # # # # ]: 0 : if ((uhci_readw(uhci, USBPORTSC1 + port * 2) & mask) ||
74 : 0 : test_bit(port, &uhci->port_c_suspend))
75 : 0 : *buf |= (1 << (port + 1));
76 : : }
77 : 0 : return !!*buf;
78 : : }
79 : :
80 : : #define CLR_RH_PORTSTAT(x) \
81 : : status = uhci_readw(uhci, port_addr); \
82 : : status &= ~(RWC_BITS|WZ_BITS); \
83 : : status &= ~(x); \
84 : : status |= RWC_BITS & (x); \
85 : : uhci_writew(uhci, status, port_addr)
86 : :
87 : : #define SET_RH_PORTSTAT(x) \
88 : : status = uhci_readw(uhci, port_addr); \
89 : : status |= (x); \
90 : : status &= ~(RWC_BITS|WZ_BITS); \
91 : : uhci_writew(uhci, status, port_addr)
92 : :
93 : : /* UHCI controllers don't automatically stop resume signalling after 20 msec,
94 : : * so we have to poll and check timeouts in order to take care of it.
95 : : */
96 : 0 : static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
97 : : unsigned long port_addr)
98 : : {
99 : 0 : int status;
100 : 0 : int i;
101 : :
102 [ # # ]: 0 : if (uhci_readw(uhci, port_addr) & SUSPEND_BITS) {
103 : 0 : CLR_RH_PORTSTAT(SUSPEND_BITS);
104 [ # # ]: 0 : if (test_bit(port, &uhci->resuming_ports))
105 : 0 : set_bit(port, &uhci->port_c_suspend);
106 : :
107 : : /* The controller won't actually turn off the RD bit until
108 : : * it has had a chance to send a low-speed EOP sequence,
109 : : * which is supposed to take 3 bit times (= 2 microseconds).
110 : : * Experiments show that some controllers take longer, so
111 : : * we'll poll for completion. */
112 [ # # ]: 0 : for (i = 0; i < 10; ++i) {
113 [ # # ]: 0 : if (!(uhci_readw(uhci, port_addr) & SUSPEND_BITS))
114 : : break;
115 : 0 : udelay(1);
116 : : }
117 : : }
118 : 0 : clear_bit(port, &uhci->resuming_ports);
119 : 0 : usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);
120 : 0 : }
121 : :
122 : : /* Wait for the UHCI controller in HP's iLO2 server management chip.
123 : : * It can take up to 250 us to finish a reset and set the CSC bit.
124 : : */
125 : 0 : static void wait_for_HP(struct uhci_hcd *uhci, unsigned long port_addr)
126 : : {
127 : 0 : int i;
128 : :
129 [ # # ]: 0 : for (i = 10; i < 250; i += 10) {
130 [ # # ]: 0 : if (uhci_readw(uhci, port_addr) & USBPORTSC_CSC)
131 : : return;
132 : 0 : udelay(10);
133 : : }
134 : : /* Log a warning? */
135 : : }
136 : :
137 : 0 : static void uhci_check_ports(struct uhci_hcd *uhci)
138 : : {
139 : 0 : unsigned int port;
140 : 0 : unsigned long port_addr;
141 : 0 : int status;
142 : :
143 [ # # ]: 0 : for (port = 0; port < uhci->rh_numports; ++port) {
144 : 0 : port_addr = USBPORTSC1 + 2 * port;
145 : 0 : status = uhci_readw(uhci, port_addr);
146 [ # # ]: 0 : if (unlikely(status & USBPORTSC_PR)) {
147 [ # # ]: 0 : if (time_after_eq(jiffies, uhci->ports_timeout)) {
148 : 0 : CLR_RH_PORTSTAT(USBPORTSC_PR);
149 : 0 : udelay(10);
150 : :
151 : : /* HP's server management chip requires
152 : : * a longer delay. */
153 [ # # ]: 0 : if (uhci->wait_for_hp)
154 : 0 : wait_for_HP(uhci, port_addr);
155 : :
156 : : /* If the port was enabled before, turning
157 : : * reset on caused a port enable change.
158 : : * Turning reset off causes a port connect
159 : : * status change. Clear these changes. */
160 : 0 : CLR_RH_PORTSTAT(USBPORTSC_CSC | USBPORTSC_PEC);
161 : 0 : SET_RH_PORTSTAT(USBPORTSC_PE);
162 : : }
163 : : }
164 [ # # ]: 0 : if (unlikely(status & USBPORTSC_RD)) {
165 [ # # ]: 0 : if (!test_bit(port, &uhci->resuming_ports)) {
166 : :
167 : : /* Port received a wakeup request */
168 : 0 : set_bit(port, &uhci->resuming_ports);
169 : 0 : uhci->ports_timeout = jiffies +
170 : : msecs_to_jiffies(USB_RESUME_TIMEOUT);
171 : 0 : usb_hcd_start_port_resume(
172 : : &uhci_to_hcd(uhci)->self, port);
173 : :
174 : : /* Make sure we see the port again
175 : : * after the resuming period is over. */
176 : 0 : mod_timer(&uhci_to_hcd(uhci)->rh_timer,
177 : : uhci->ports_timeout);
178 [ # # ]: 0 : } else if (time_after_eq(jiffies,
179 : : uhci->ports_timeout)) {
180 : 0 : uhci_finish_suspend(uhci, port, port_addr);
181 : : }
182 : : }
183 : : }
184 : 0 : }
185 : :
186 : 0 : static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
187 : : {
188 : 0 : struct uhci_hcd *uhci = hcd_to_uhci(hcd);
189 : 0 : unsigned long flags;
190 : 0 : int status = 0;
191 : :
192 : 0 : spin_lock_irqsave(&uhci->lock, flags);
193 : :
194 : 0 : uhci_scan_schedule(uhci);
195 [ # # # # ]: 0 : if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
196 : 0 : goto done;
197 : 0 : uhci_check_ports(uhci);
198 : :
199 : 0 : status = get_hub_status_data(uhci, buf);
200 : :
201 [ # # # # : 0 : switch (uhci->rh_state) {
# ]
202 : 0 : case UHCI_RH_SUSPENDED:
203 : : /* if port change, ask to be resumed */
204 [ # # # # ]: 0 : if (status || uhci->resuming_ports) {
205 : 0 : status = 1;
206 : 0 : usb_hcd_resume_root_hub(hcd);
207 : : }
208 : : break;
209 : :
210 : 0 : case UHCI_RH_AUTO_STOPPED:
211 : : /* if port change, auto start */
212 [ # # ]: 0 : if (status)
213 : 0 : wakeup_rh(uhci);
214 : : break;
215 : :
216 : 0 : case UHCI_RH_RUNNING:
217 : : /* are any devices attached? */
218 [ # # ]: 0 : if (!any_ports_active(uhci)) {
219 : 0 : uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
220 : 0 : uhci->auto_stop_time = jiffies + HZ;
221 : : }
222 : : break;
223 : :
224 : 0 : case UHCI_RH_RUNNING_NODEVS:
225 : : /* auto-stop if nothing connected for 1 second */
226 [ # # ]: 0 : if (any_ports_active(uhci))
227 : 0 : uhci->rh_state = UHCI_RH_RUNNING;
228 [ # # ]: 0 : else if (time_after_eq(jiffies, uhci->auto_stop_time) &&
229 [ # # ]: 0 : !uhci->wait_for_hp)
230 : 0 : suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
231 : : break;
232 : :
233 : : default:
234 : : break;
235 : : }
236 : :
237 : 0 : done:
238 : 0 : spin_unlock_irqrestore(&uhci->lock, flags);
239 : 0 : return status;
240 : : }
241 : :
242 : : /* size of returned buffer is part of USB spec */
243 : 0 : static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
244 : : u16 wIndex, char *buf, u16 wLength)
245 : : {
246 [ # # ]: 0 : struct uhci_hcd *uhci = hcd_to_uhci(hcd);
247 : 0 : int status, lstatus, retval = 0;
248 : 0 : unsigned int port = wIndex - 1;
249 : 0 : unsigned long port_addr = USBPORTSC1 + 2 * port;
250 : 0 : u16 wPortChange, wPortStatus;
251 : 0 : unsigned long flags;
252 : :
253 [ # # # # ]: 0 : if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
254 : : return -ETIMEDOUT;
255 : :
256 : 0 : spin_lock_irqsave(&uhci->lock, flags);
257 [ # # # # : 0 : switch (typeReq) {
# # # ]
258 : :
259 : 0 : case GetHubStatus:
260 : 0 : *(__le32 *)buf = cpu_to_le32(0);
261 : 0 : retval = 4; /* hub power */
262 : 0 : break;
263 : 0 : case GetPortStatus:
264 [ # # ]: 0 : if (port >= uhci->rh_numports)
265 : 0 : goto err;
266 : :
267 : 0 : uhci_check_ports(uhci);
268 : 0 : status = uhci_readw(uhci, port_addr);
269 : :
270 : : /* Intel controllers report the OverCurrent bit active on.
271 : : * VIA controllers report it active off, so we'll adjust the
272 : : * bit value. (It's not standardized in the UHCI spec.)
273 : : */
274 [ # # ]: 0 : if (uhci->oc_low)
275 : 0 : status ^= USBPORTSC_OC;
276 : :
277 : : /* UHCI doesn't support C_RESET (always false) */
278 : 0 : wPortChange = lstatus = 0;
279 [ # # ]: 0 : if (status & USBPORTSC_CSC)
280 : 0 : wPortChange |= USB_PORT_STAT_C_CONNECTION;
281 [ # # ]: 0 : if (status & USBPORTSC_PEC)
282 : 0 : wPortChange |= USB_PORT_STAT_C_ENABLE;
283 [ # # # # ]: 0 : if ((status & USBPORTSC_OCC) && !ignore_oc)
284 : 0 : wPortChange |= USB_PORT_STAT_C_OVERCURRENT;
285 : :
286 [ # # ]: 0 : if (test_bit(port, &uhci->port_c_suspend)) {
287 : 0 : wPortChange |= USB_PORT_STAT_C_SUSPEND;
288 : 0 : lstatus |= 1;
289 : : }
290 : 0 : if (test_bit(port, &uhci->resuming_ports))
291 : : lstatus |= 4;
292 : :
293 : : /* UHCI has no power switching (always on) */
294 : 0 : wPortStatus = USB_PORT_STAT_POWER;
295 : 0 : if (status & USBPORTSC_CCS)
296 : : wPortStatus |= USB_PORT_STAT_CONNECTION;
297 [ # # ]: 0 : if (status & USBPORTSC_PE) {
298 : 0 : wPortStatus |= USB_PORT_STAT_ENABLE;
299 [ # # ]: 0 : if (status & SUSPEND_BITS)
300 : 0 : wPortStatus |= USB_PORT_STAT_SUSPEND;
301 : : }
302 [ # # ]: 0 : if (status & USBPORTSC_OC)
303 : 0 : wPortStatus |= USB_PORT_STAT_OVERCURRENT;
304 [ # # ]: 0 : if (status & USBPORTSC_PR)
305 : 0 : wPortStatus |= USB_PORT_STAT_RESET;
306 [ # # ]: 0 : if (status & USBPORTSC_LSDA)
307 : 0 : wPortStatus |= USB_PORT_STAT_LOW_SPEED;
308 : :
309 : 0 : if (wPortChange)
310 : : dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n",
311 : : wIndex, status, lstatus);
312 : :
313 : 0 : *(__le16 *)buf = cpu_to_le16(wPortStatus);
314 : 0 : *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
315 : 0 : retval = 4;
316 : 0 : break;
317 : 0 : case SetHubFeature: /* We don't implement these */
318 : : case ClearHubFeature:
319 [ # # ]: 0 : switch (wValue) {
320 : : case C_HUB_OVER_CURRENT:
321 : : case C_HUB_LOCAL_POWER:
322 : : break;
323 : 0 : default:
324 : 0 : goto err;
325 : : }
326 : : break;
327 : 0 : case SetPortFeature:
328 [ # # ]: 0 : if (port >= uhci->rh_numports)
329 : 0 : goto err;
330 : :
331 [ # # # # ]: 0 : switch (wValue) {
332 : 0 : case USB_PORT_FEAT_SUSPEND:
333 : 0 : SET_RH_PORTSTAT(USBPORTSC_SUSP);
334 : : break;
335 : 0 : case USB_PORT_FEAT_RESET:
336 : 0 : SET_RH_PORTSTAT(USBPORTSC_PR);
337 : :
338 : : /* Reset terminates Resume signalling */
339 : 0 : uhci_finish_suspend(uhci, port, port_addr);
340 : :
341 : : /* USB v2.0 7.1.7.5 */
342 : 0 : uhci->ports_timeout = jiffies +
343 : : msecs_to_jiffies(USB_RESUME_TIMEOUT);
344 : 0 : break;
345 : : case USB_PORT_FEAT_POWER:
346 : : /* UHCI has no power switching */
347 : : break;
348 : 0 : default:
349 : 0 : goto err;
350 : : }
351 : : break;
352 : 0 : case ClearPortFeature:
353 [ # # ]: 0 : if (port >= uhci->rh_numports)
354 : 0 : goto err;
355 : :
356 [ # # # # : 0 : switch (wValue) {
# # # #
# ]
357 : 0 : case USB_PORT_FEAT_ENABLE:
358 : 0 : CLR_RH_PORTSTAT(USBPORTSC_PE);
359 : :
360 : : /* Disable terminates Resume signalling */
361 : 0 : uhci_finish_suspend(uhci, port, port_addr);
362 : 0 : break;
363 : 0 : case USB_PORT_FEAT_C_ENABLE:
364 : 0 : CLR_RH_PORTSTAT(USBPORTSC_PEC);
365 : : break;
366 : 0 : case USB_PORT_FEAT_SUSPEND:
367 [ # # ]: 0 : if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) {
368 : :
369 : : /* Make certain the port isn't suspended */
370 : 0 : uhci_finish_suspend(uhci, port, port_addr);
371 [ # # ]: 0 : } else if (!test_and_set_bit(port,
372 : 0 : &uhci->resuming_ports)) {
373 : 0 : SET_RH_PORTSTAT(USBPORTSC_RD);
374 : :
375 : : /* The controller won't allow RD to be set
376 : : * if the port is disabled. When this happens
377 : : * just skip the Resume signalling.
378 : : */
379 [ # # ]: 0 : if (!(uhci_readw(uhci, port_addr) &
380 : : USBPORTSC_RD))
381 : 0 : uhci_finish_suspend(uhci, port,
382 : : port_addr);
383 : : else
384 : : /* USB v2.0 7.1.7.7 */
385 : 0 : uhci->ports_timeout = jiffies +
386 : : msecs_to_jiffies(20);
387 : : }
388 : : break;
389 : 0 : case USB_PORT_FEAT_C_SUSPEND:
390 : 0 : clear_bit(port, &uhci->port_c_suspend);
391 : 0 : break;
392 : 0 : case USB_PORT_FEAT_POWER:
393 : : /* UHCI has no power switching */
394 : 0 : goto err;
395 : 0 : case USB_PORT_FEAT_C_CONNECTION:
396 : 0 : CLR_RH_PORTSTAT(USBPORTSC_CSC);
397 : : break;
398 : 0 : case USB_PORT_FEAT_C_OVER_CURRENT:
399 : 0 : CLR_RH_PORTSTAT(USBPORTSC_OCC);
400 : : break;
401 : : case USB_PORT_FEAT_C_RESET:
402 : : /* this driver won't report these */
403 : : break;
404 : 0 : default:
405 : 0 : goto err;
406 : : }
407 : : break;
408 : 0 : case GetHubDescriptor:
409 : 0 : retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
410 : 0 : memcpy(buf, root_hub_hub_des, retval);
411 [ # # ]: 0 : if (retval > 2)
412 : 0 : buf[2] = uhci->rh_numports;
413 : : break;
414 : : default:
415 : 0 : err:
416 : : retval = -EPIPE;
417 : : }
418 : 0 : spin_unlock_irqrestore(&uhci->lock, flags);
419 : :
420 : 0 : return retval;
421 : : }
|