1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Joyent, Inc.
14 */
15
16 /*
17 * xHCI Root Hub
18 *
19 * Please see the big theory statement in xhci.c for more information.
20 */
21
22 #include <sys/usb/hcd/xhci/xhci.h>
23
24 /*
25 * The following structure and global define the default configuration that we
26 * 'deliver' to USBA on behalf of our hub. However, it's worth noting that it's
27 * going to take this in as an array of bytes off of the wire, whereas we're
28 * declaring this as a packed C structure to make our life much, much easier.
29 * It is critical that we pay attention to the endianness of anything that is
30 * more than a single byte wide and write the value in the appropriate
31 * endian-aware form.
32 *
33 * Note, we don't use the system structures for these values because they are
34 * not packed, and we must be. Even though we define all members, we still use
35 * C99 structure initialization to make it easier for folks to see what values
36 * are what in a long array of numbers.
37 *
38 * The structure is laid out first with members that make up a usb_cfg_descr_t.
39 * Then it has a usb_if_descr_t. After that, it has a usb_ep_descr_t and finally
40 * a usb_ep_ss_comp_descr_t. Please see the original structure definitions for
41 * the meaning of each member.
42 *
43 * Many of the values used below were derived from the USB 3.1/10.15.1 'Standard
44 * Descriptors for Hub Class'.
45 */
46 #pragma pack(1)
47 typedef struct xhci_dev_conf {
48 /* usb_cfg_descr_t */
49 uint8_t xdc_cfg_bLength;
50 uint8_t xdc_cfg_bDescriptorType;
51 uint16_t xdc_cfg_wTotalLength;
52 uint8_t xdc_cfg_bNumInterfaces;
53 uint8_t xdc_cfg_bConfigurationValue;
54 uint8_t xdc_cfg_iConfiguration;
55 uint8_t xdc_cfg_bmAttributes;
56 uint8_t xdc_cfg_bMaxPower;
57 /* usb_if_descr_t */
58 uint8_t xdc_if_bLength;
59 uint8_t xdc_if_bDescriptorType;
60 uint8_t xdc_if_bInterfaceNumber;
61 uint8_t xdc_if_bAlternateSetting;
62 uint8_t xdc_if_bNumEndpoints;
63 uint8_t xdc_if_bInterfaceClass;
64 uint8_t xdc_if_bInterfaceSubClass;
65 uint8_t xdc_if_bInterfaceProtocol;
66 uint8_t xdc_if_iInterface;
67 /* usb_ep_descr_t */
68 uint8_t xdc_ep_bLength;
69 uint8_t xdc_ep_bDescriptorType;
70 uint8_t xdc_ep_bEndpointAddress;
71 uint8_t xdc_ep_bmAttributes;
72 uint16_t xdc_ep_wMaxPacketSize;
73 uint8_t xdc_ep_bInterval;
74 /* usb_ep_ss_comp_descr_t */
75 uint8_t xdc_epssc_bLength;
76 uint8_t xdc_epssc_bDescriptorType;
77 uint8_t xdc_epssc_bMaxBurst;
78 uint8_t xdc_epssc_bmAttributes;
79 uint16_t xdc_epssc_wBytesPerInterval;
80 } xhci_dev_conf_t;
81 #pragma pack()
82
83 #if MAX_PORTS != 31
84 #error "MAX_PORTS has changed, update xdc_ep_wMaxPacketSize"
85 #endif
86
87 xhci_dev_conf_t xhci_hcdi_conf = {
88 .xdc_cfg_bLength = 0x9,
89 .xdc_cfg_bDescriptorType = USB_DESCR_TYPE_CFG,
90 #if defined(_BIG_ENDIAN)
91 .xdc_cfg_wTotalLength = 0x1f00,
92 #elif defined(_LITTLE_ENDIAN)
93 .xdc_cfg_wTotalLength = 0x001f,
94 #else /* !_BIG_ENDIAN && !_LITTLE_ENDIAN */
95 #error "Unknown endianness"
96 #endif /* _BIG_ENDIAN */
97 .xdc_cfg_bNumInterfaces = 0x1,
98 .xdc_cfg_bConfigurationValue = 0x1,
99 .xdc_cfg_iConfiguration = 0x0,
100 .xdc_cfg_bmAttributes = 0x40,
101 .xdc_cfg_bMaxPower = 0x0,
102
103 .xdc_if_bLength = 0x9,
104 .xdc_if_bDescriptorType = USB_DESCR_TYPE_IF,
105 .xdc_if_bInterfaceNumber = 0x0,
106 .xdc_if_bAlternateSetting = 0x0,
107 .xdc_if_bNumEndpoints = 0x1,
108 .xdc_if_bInterfaceClass = USB_CLASS_HUB,
109 .xdc_if_bInterfaceSubClass = 0x0,
110 .xdc_if_bInterfaceProtocol = 0x0,
111 .xdc_if_iInterface = 0x0,
112
113 .xdc_ep_bLength = 0x7,
114 .xdc_ep_bDescriptorType = USB_DESCR_TYPE_EP,
115 .xdc_ep_bEndpointAddress = USB_EP_DIR_IN | ROOT_HUB_ADDR,
116 .xdc_ep_bmAttributes = USB_EP_ATTR_INTR,
117
118 /*
119 * We size the endpoint's maximum packet size based on the total number
120 * of ports that exist. This allows us to ensure that we can always
121 * deliver a status bit for every port, even if we're not strictly
122 * playing by the rules and have more than 16 ports. The system defines
123 * MAX_PORTS to be 31, therefore we set this to four, so we cover it
124 * all.
125 */
126 #if defined(_BIG_ENDIAN)
127 .xdc_ep_wMaxPacketSize = 0x0400,
128 #elif defined(_LITTLE_ENDIAN)
129 .xdc_ep_wMaxPacketSize = 0x0004,
130 #else /* !_BIG_ENDIAN && !_LITTLE_ENDIAN */
131 #error "Unknown endianness"
132 #endif /* _BIG_ENDIAN */
133 .xdc_ep_bInterval = 0x8,
134
135 .xdc_epssc_bLength = 0x06,
136 .xdc_epssc_bDescriptorType = USB_DESCR_TYPE_SS_EP_COMP,
137 .xdc_epssc_bMaxBurst = 0,
138 .xdc_epssc_bmAttributes = 0,
139 #if defined(_BIG_ENDIAN)
140 .xdc_epssc_wBytesPerInterval = 0x0200
141 #elif defined(_LITTLE_ENDIAN)
142 .xdc_epssc_wBytesPerInterval = 0x0002
143 #else /* !_BIG_ENDIAN && !_LITTLE_ENDIAN */
144 #error "Unknown endianness"
145 #endif /* _BIG_ENDIAN */
146 };
147
148 /*
149 * This is a standard device request as defined in USB 3.1 / 9.4.5.
150 */
151 static int
xhci_root_hub_get_device_status(xhci_t * xhcip,usb_ctrl_req_t * ucrp)152 xhci_root_hub_get_device_status(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
153 {
154 uint16_t stand;
155 uint32_t psm;
156 uint8_t len;
157 mblk_t *mp;
158
159 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
160
161 mp = ucrp->ctrl_data;
162
163 /*
164 * In the case where the request write length doesn't match what we
165 * expect, we still return that this is 'OK'; however, we don't
166 * increment the length, allowing the caller to basically see that we
167 * have no data / failed it. The behavior in this case is defined to be
168 * undefined and unfortuantely there's no great return value here for
169 * EINVAL.
170 */
171 switch (ucrp->ctrl_wValue) {
172 case USB_GET_STATUS_STANDARD:
173 if (ucrp->ctrl_wLength != USB_GET_STATUS_LEN)
174 return (USB_CR_UNSPECIFIED_ERR);
175 len = USB_GET_STATUS_LEN;
176 stand = LE_16(USB_DEV_SLF_PWRD_STATUS);
177 bcopy(&stand, mp->b_wptr, sizeof (stand));
178 break;
179 case USB_GET_STATUS_PTM:
180 if (ucrp->ctrl_wLength != USB_GET_STATUS_PTM_LEN)
181 return (USB_CR_UNSPECIFIED_ERR);
182 /*
183 * We don't support the root hub, so we always return zero.
184 */
185 len = USB_GET_STATUS_PTM_LEN;
186 psm = 0;
187 bcopy(&psm, mp->b_wptr, sizeof (psm));
188 break;
189 default:
190 return (USB_CR_NOT_SUPPORTED);
191 }
192
193 mp->b_wptr += len;
194
195 return (USB_CR_OK);
196 }
197
198 /*
199 * This is a hub class specific device request as defined in USB 3.1 /
200 * 11.24.2.6.
201 */
202 static int
xhci_root_hub_get_status(xhci_t * xhcip,usb_ctrl_req_t * ucrp)203 xhci_root_hub_get_status(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
204 {
205 const uint32_t status = 0;
206 mblk_t *mp;
207
208 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
209
210 if (ucrp->ctrl_wLength != HUB_GET_STATUS_LEN)
211 return (USB_CR_UNSPECIFIED_ERR);
212 mp = ucrp->ctrl_data;
213
214 bcopy(&status, mp->b_wptr, sizeof (status));
215 mp->b_wptr += sizeof (status);
216
217 return (USB_CR_OK);
218 }
219
220 /*
221 * We've been asked to get the root hub's descriptor. According to USB 3.1 /
222 * 10.16.2.3 we return up to a maximum number of bytes based on the actual size
223 * of the request. It's not an error for it to request more or less. e.g. we
224 * only return MIN(req, sizeof (desc)).
225 */
226 static void
xhci_root_hub_get_descriptor(xhci_t * xhcip,usb_ctrl_req_t * ucrp)227 xhci_root_hub_get_descriptor(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
228 {
229 int len = MIN(sizeof (usb_ss_hub_descr_t), ucrp->ctrl_wLength);
230
231 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
232
233 /*
234 * We maintain the root hub's description in a little-endian data format
235 * regardless of the platform. This means that we don't have to try to
236 * transform any of the data that we have inside of it when we deliver
237 * it to USBA.
238 */
239 bcopy(&xhcip->xhci_usba.xa_hub_descr, ucrp->ctrl_data->b_wptr, len);
240 ucrp->ctrl_data->b_wptr += len;
241 }
242
243 static int
xhci_root_hub_handle_port_clear_feature(xhci_t * xhcip,usb_ctrl_req_t * ucrp)244 xhci_root_hub_handle_port_clear_feature(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
245 {
246 int feat = ucrp->ctrl_wValue;
247 int port = XHCI_PS_INDPORT(ucrp->ctrl_wIndex);
248 uint32_t reg;
249
250 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
251
252 if (port < 1 || port > xhcip->xhci_caps.xcap_max_ports)
253 return (USB_CR_UNSPECIFIED_ERR);
254 if (ucrp->ctrl_wLength != 0)
255 return (USB_CR_UNSPECIFIED_ERR);
256
257 reg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_PORTSC(port));
258 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
259 xhci_error(xhcip, "failed to read port status register for "
260 "port %d: encountered fatal FM error, resetting device",
261 port);
262 xhci_fm_runtime_reset(xhcip);
263 return (USB_CR_HC_HARDWARE_ERR);
264 }
265
266 /*
267 * The port status and command register has many bits that we must
268 * preserve across writes, however, it also has bits that will be
269 * cleared when a bitwise one is written to them. As some of these
270 * write-one-to-clear bits may be set, we make sure to mask them off.
271 */
272 reg &= ~XHCI_PS_CLEAR;
273
274 switch (feat) {
275 case CFS_PORT_ENABLE:
276 reg |= XHCI_PS_PED;
277 break;
278 case CFS_PORT_POWER:
279 reg &= ~XHCI_PS_PP;
280 break;
281 case CFS_C_PORT_CONNECTION:
282 reg |= XHCI_PS_CSC;
283 break;
284 case CFS_C_PORT_RESET:
285 reg |= XHCI_PS_PRC;
286 break;
287 case CFS_C_PORT_OVER_CURRENT:
288 reg |= XHCI_PS_OCC;
289 break;
290 case CFS_C_PORT_SUSPEND:
291 case CFS_C_PORT_LINK_STATE:
292 reg |= XHCI_PS_PLC;
293 break;
294 case CFS_C_PORT_ENABLE:
295 reg |= XHCI_PS_PEC;
296 break;
297 case CFS_C_PORT_CONFIG_ERROR:
298 reg |= XHCI_PS_CEC;
299 break;
300 case CFS_C_BH_PORT_RESET:
301 reg |= XHCI_PS_WRC;
302 break;
303 case CFS_PORT_SUSPEND:
304 default:
305 xhci_log(xhcip, "!asked to clear unsupported root hub "
306 "feature %d on port %d", feat, port);
307 return (USB_CR_NOT_SUPPORTED);
308 }
309
310 xhci_put32(xhcip, XHCI_R_OPER, XHCI_PORTSC(port), reg);
311 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
312 xhci_error(xhcip, "failed to write port status register for "
313 "port %d: encountered fatal FM error, resetting device",
314 port);
315 xhci_fm_runtime_reset(xhcip);
316 return (USB_CR_HC_HARDWARE_ERR);
317 }
318
319 return (USB_CR_OK);
320 }
321
322 static int
xhci_root_hub_handle_port_set_feature(xhci_t * xhcip,usb_ctrl_req_t * ucrp)323 xhci_root_hub_handle_port_set_feature(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
324 {
325 int feat = ucrp->ctrl_wValue;
326 int port = XHCI_PS_INDPORT(ucrp->ctrl_wIndex);
327 uint32_t val = XHCI_PS_INDVAL(ucrp->ctrl_wIndex);
328 uint32_t reg;
329 uintptr_t index;
330
331 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
332
333 if (port < 1 || port > xhcip->xhci_caps.xcap_max_ports)
334 return (USB_CR_UNSPECIFIED_ERR);
335 if (ucrp->ctrl_wLength != 0)
336 return (USB_CR_UNSPECIFIED_ERR);
337
338 index = XHCI_PORTSC(port);
339 reg = xhci_get32(xhcip, XHCI_R_OPER, index);
340 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
341 xhci_error(xhcip, "failed to read port status register for "
342 "port %d: encountered fatal FM error, resetting device",
343 port);
344 xhci_fm_runtime_reset(xhcip);
345 return (USB_CR_HC_HARDWARE_ERR);
346 }
347
348 /*
349 * The port status and command register has many bits that we must
350 * preserve across writes, however, it also has bits that will be
351 * cleared when a bitwise one is written to them. As some of these
352 * write-one-to-clear bits may be set, we make sure to mask them off.
353 */
354 reg &= ~XHCI_PS_CLEAR;
355
356 switch (feat) {
357 case CFS_PORT_U1_TIMEOUT:
358 index = XHCI_PORTPMSC(port);
359 reg = xhci_get32(xhcip, XHCI_R_OPER, index);
360 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
361 xhci_error(xhcip, "failed to read port power "
362 "management register for port %d: encountered "
363 "fatal FM error, resetting device", port);
364 xhci_fm_runtime_reset(xhcip);
365 return (USB_CR_HC_HARDWARE_ERR);
366 }
367 reg &= ~XHCI_PM3_U1TO_SET(0xff);
368 reg |= XHCI_PM3_U1TO_SET(val);
369 break;
370 case CFS_PORT_U2_TIMEOUT:
371 index = XHCI_PORTPMSC(port);
372 reg = xhci_get32(xhcip, XHCI_R_OPER, index);
373 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
374 xhci_error(xhcip, "failed to read port power "
375 "management register for port %d: encountered "
376 "fatal FM error, resetting device", port);
377 xhci_fm_runtime_reset(xhcip);
378 return (USB_CR_HC_HARDWARE_ERR);
379 }
380 reg &= ~XHCI_PM3_U1TO_SET(0xff);
381 reg |= XHCI_PM3_U1TO_SET(val);
382 break;
383 case CFS_PORT_LINK_STATE:
384 reg |= XHCI_PS_PLS_SET(val);
385 reg |= XHCI_PS_LWS;
386 break;
387 case CFS_PORT_REMOTE_WAKE_MASK:
388 if (val & CFS_PRWM_CONN_ENABLE)
389 reg |= XHCI_PS_WCE;
390 else
391 reg &= ~XHCI_PS_WCE;
392
393 if (val & CFS_PRWM_DISCONN_ENABLE)
394 reg |= XHCI_PS_WDE;
395 else
396 reg &= ~XHCI_PS_WDE;
397
398 if (val & CFS_PRWM_OC_ENABLE)
399 reg |= XHCI_PS_WOE;
400 else
401 reg &= ~XHCI_PS_WOE;
402 break;
403 case CFS_BH_PORT_RESET:
404 reg |= XHCI_PS_WPR;
405 break;
406 case CFS_PORT_RESET:
407 reg |= XHCI_PS_PR;
408 break;
409 case CFS_PORT_POWER:
410 reg |= XHCI_PS_PP;
411 break;
412 case CFS_PORT_ENABLE:
413 /*
414 * Enabling happens automatically for both USB 2 and USB 3. So
415 * there's nothing specific to set here.
416 */
417 return (USB_CR_OK);
418 case CFS_PORT_SUSPEND:
419 default:
420 xhci_log(xhcip, "!asked to set unsupported root hub "
421 "feature %d on port %d", feat, port);
422 return (USB_CR_NOT_SUPPORTED);
423 }
424
425 xhci_put32(xhcip, XHCI_R_OPER, index, reg);
426 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
427 xhci_error(xhcip, "failed to write port status register for "
428 "port %d: encountered fatal FM error, resetting device",
429 port);
430 xhci_fm_runtime_reset(xhcip);
431 return (USB_CR_HC_HARDWARE_ERR);
432 }
433
434 return (USB_CR_OK);
435 }
436
437 /*
438 * We've been asked to get the port's status. While there are multiple forms
439 * that the port status request can take, we only support the primary one. The
440 * enhanced version is only in USB 3.1.
441 *
442 * Note that we don't end up explicitly adding a speed value for the port,
443 * because the only valid values are zero.
444 */
445 static int
xhci_root_hub_handle_port_get_status(xhci_t * xhcip,usb_ctrl_req_t * ucrp)446 xhci_root_hub_handle_port_get_status(xhci_t *xhcip, usb_ctrl_req_t *ucrp)
447 {
448 uint32_t reg;
449 uint16_t ps, cs;
450 mblk_t *mp = ucrp->ctrl_data;
451 int port = XHCI_PS_INDPORT(ucrp->ctrl_wIndex);
452
453 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
454
455 if (port < 1 || port > xhcip->xhci_caps.xcap_max_ports)
456 return (USB_CR_UNSPECIFIED_ERR);
457
458 if (ucrp->ctrl_wValue != PORT_GET_STATUS_PORT)
459 return (USB_CR_NOT_SUPPORTED);
460
461 if (ucrp->ctrl_wLength != PORT_GET_STATUS_PORT_LEN)
462 return (USB_CR_UNSPECIFIED_ERR);
463
464 reg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_PORTSC(port));
465 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
466 xhci_error(xhcip, "failed to read port status register for "
467 "port %d: encountered fatal FM error, resetting device",
468 port);
469 xhci_fm_runtime_reset(xhcip);
470 return (USB_CR_HC_HARDWARE_ERR);
471 }
472
473 ps = cs = 0;
474 if (reg & XHCI_PS_CCS)
475 ps |= PORT_STATUS_CCS;
476 if (reg & XHCI_PS_PED)
477 ps |= PORT_STATUS_PES;
478 if (reg & XHCI_PS_OCA)
479 ps |= PORT_STATUS_POCI;
480 if (reg & XHCI_PS_PR)
481 ps |= PORT_STATUS_PRS;
482
483 ps |= XHCI_PS_PLS_SET(XHCI_PS_PLS_GET(reg));
484
485 if (reg & XHCI_PS_PP)
486 ps |= PORT_STATUS_PPS;
487
488 /*
489 * While this isn't a defined part of the status, because we're not a
490 * true USB 3 hub, this is the only primary way that we can tell USBA
491 * what the actual speed of the device is. It's a bit dirty, but there's
492 * not really a great alternative at the moment.
493 */
494 switch (XHCI_PS_SPEED_GET(reg)) {
495 case XHCI_SPEED_FULL:
496 ps |= USBA_FULL_SPEED_DEV << PORT_STATUS_SPSHIFT_SS;
497 break;
498 case XHCI_SPEED_LOW:
499 ps |= USBA_LOW_SPEED_DEV << PORT_STATUS_SPSHIFT_SS;
500 break;
501 case XHCI_SPEED_HIGH:
502 ps |= USBA_HIGH_SPEED_DEV << PORT_STATUS_SPSHIFT_SS;
503 break;
504 case XHCI_SPEED_SUPER:
505 default:
506 /*
507 * If we encounter something we don't know, we're going to start
508 * by assuming it is SuperSpeed, as so far all additions have
509 * been purely faster than SuperSpeed and have the same external
510 * behavior.
511 */
512 ps |= USBA_SUPER_SPEED_DEV << PORT_STATUS_SPSHIFT_SS;
513 break;
514 }
515
516 if (reg & XHCI_PS_CSC)
517 cs |= PORT_CHANGE_CSC;
518 if (reg & XHCI_PS_PEC)
519 cs |= PORT_CHANGE_PESC;
520 if (reg & XHCI_PS_OCC)
521 cs |= PORT_CHANGE_OCIC;
522 if (reg & XHCI_PS_PRC)
523 cs |= PORT_CHANGE_PRSC;
524 if (reg & XHCI_PS_WRC)
525 cs |= PORT_CHANGE_BHPR;
526 if (reg & XHCI_PS_PLC)
527 cs |= PORT_CHANGE_PLSC;
528 if (reg & XHCI_PS_CEC)
529 cs |= PORT_CHANGE_PCE;
530
531 cs = LE_16(cs);
532 ps = LE_16(ps);
533 bcopy(&ps, mp->b_wptr, sizeof (uint16_t));
534 mp->b_wptr += sizeof (uint16_t);
535 bcopy(&cs, mp->b_wptr, sizeof (uint16_t));
536 mp->b_wptr += sizeof (uint16_t);
537
538 return (USB_CR_OK);
539 }
540
541 /*
542 * USBA has issued a request for the root hub. We need to determine what it's
543 * asking about and then figure out how to handle it and how to respond.
544 */
545 int
xhci_root_hub_ctrl_req(xhci_t * xhcip,usba_pipe_handle_data_t * ph,usb_ctrl_req_t * ucrp)546 xhci_root_hub_ctrl_req(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
547 usb_ctrl_req_t *ucrp)
548 {
549 int ret = USB_CR_OK;
550
551 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
552
553 switch (ucrp->ctrl_bmRequestType) {
554 case HUB_GET_DEVICE_STATUS_TYPE:
555 ret = xhci_root_hub_get_device_status(xhcip, ucrp);
556 break;
557 case HUB_HANDLE_PORT_FEATURE_TYPE:
558 switch (ucrp->ctrl_bRequest) {
559 case USB_REQ_CLEAR_FEATURE:
560 ret = xhci_root_hub_handle_port_clear_feature(xhcip,
561 ucrp);
562 break;
563 case USB_REQ_SET_FEATURE:
564 ret = xhci_root_hub_handle_port_set_feature(xhcip,
565 ucrp);
566 break;
567 default:
568 ret = USB_CR_NOT_SUPPORTED;
569 break;
570 }
571 break;
572 case HUB_GET_PORT_STATUS_TYPE:
573 ret = xhci_root_hub_handle_port_get_status(xhcip, ucrp);
574 break;
575 case HUB_CLASS_REQ_TYPE:
576 switch (ucrp->ctrl_bRequest) {
577 case USB_REQ_GET_STATUS:
578 ret = xhci_root_hub_get_status(xhcip, ucrp);
579 break;
580 case USB_REQ_GET_DESCR:
581 xhci_root_hub_get_descriptor(xhcip, ucrp);
582 break;
583 default:
584 xhci_error(xhcip, "Unhandled hub request: 0x%x\n",
585 ucrp->ctrl_bRequest);
586 ret = USB_CR_NOT_SUPPORTED;
587 break;
588 }
589 break;
590 default:
591 xhci_error(xhcip, "Unhandled hub request type: %x\n",
592 ucrp->ctrl_bmRequestType);
593 ret = USB_CR_NOT_SUPPORTED;
594 break;
595 }
596
597 mutex_exit(&xhcip->xhci_lock);
598 usba_hcdi_cb(ph, (usb_opaque_t)ucrp, ret);
599 mutex_enter(&xhcip->xhci_lock);
600
601 return (USB_SUCCESS);
602 }
603
604 /*
605 * This function is invoked whenever the root HUBs interrupt endpoint is opened
606 * or we receive an port change event notification from the hardware on the
607 * event ring from an interrupt.
608 *
609 * If we have a registered interrupt callback requested, then we have to
610 * duplicate the request so we can send it back to usba and then we generate the
611 * actual status message and send it.
612 */
613 void
xhci_root_hub_psc_callback(xhci_t * xhcip)614 xhci_root_hub_psc_callback(xhci_t *xhcip)
615 {
616 usb_intr_req_t *req, *new;
617 usba_pipe_handle_data_t *ph;
618 mblk_t *mp;
619 uint32_t mask;
620 unsigned i;
621
622 mask = 0;
623 for (i = 0; i <= xhcip->xhci_caps.xcap_max_ports; i++) {
624 uint32_t reg;
625
626 reg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_PORTSC(i));
627 if ((reg & XHCI_HUB_INTR_CHANGE_MASK) != 0)
628 mask |= 1UL << i;
629 }
630
631 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
632 xhci_error(xhcip, "failed to read port status registers: "
633 "encountered fatal FM error, resetting device");
634 xhci_fm_runtime_reset(xhcip);
635 return;
636 }
637 if (mask == 0)
638 return;
639
640 mask = LE_32(mask);
641
642 mutex_enter(&xhcip->xhci_lock);
643 if (xhcip->xhci_usba.xa_intr_cb_req == NULL) {
644 mutex_exit(&xhcip->xhci_lock);
645 return;
646 }
647
648 ASSERT(xhcip->xhci_usba.xa_intr_cb_ph != NULL);
649 req = xhcip->xhci_usba.xa_intr_cb_req;
650 ph = xhcip->xhci_usba.xa_intr_cb_ph;
651
652 new = usba_hcdi_dup_intr_req(ph->p_dip, req, req->intr_len, 0);
653 if (new == NULL) {
654 new = xhcip->xhci_usba.xa_intr_cb_req;
655 xhcip->xhci_usba.xa_intr_cb_req = NULL;
656 mutex_exit(&xhcip->xhci_lock);
657 usba_hcdi_cb(ph, (usb_opaque_t)new, USB_CR_NO_RESOURCES);
658 return;
659 }
660
661 /*
662 * Why yes, we do have to manually increment this for the given pipe
663 * before we deliver it. If we don't, it has no way of knowing that
664 * there's another request inbound and we'll simply blow our assertions
665 * on requests.
666 */
667 mutex_enter(&ph->p_mutex);
668 ph->p_req_count++;
669 mutex_exit(&ph->p_mutex);
670
671 mp = new->intr_data;
672 bcopy(&mask, mp->b_wptr, sizeof (mask));
673 mp->b_wptr += sizeof (mask);
674
675 mutex_exit(&xhcip->xhci_lock);
676
677 usba_hcdi_cb(ph, (usb_opaque_t)new, USB_CR_OK);
678 }
679
680 void
xhci_root_hub_intr_root_disable(xhci_t * xhcip)681 xhci_root_hub_intr_root_disable(xhci_t *xhcip)
682 {
683 usba_pipe_handle_data_t *ph;
684 usb_intr_req_t *uirp;
685
686 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
687
688 ph = xhcip->xhci_usba.xa_intr_cb_ph;
689 xhcip->xhci_usba.xa_intr_cb_ph = NULL;
690 ASSERT(ph != NULL);
691
692 /*
693 * If the uirp here is NULL, it's because we ran out of resources at
694 * some point in xhci_hcdi_psc_callback().
695 */
696 uirp = xhcip->xhci_usba.xa_intr_cb_req;
697 xhcip->xhci_usba.xa_intr_cb_req = NULL;
698 if (uirp == NULL) {
699 return;
700 }
701
702 mutex_exit(&xhcip->xhci_lock);
703 usba_hcdi_cb(ph, (usb_opaque_t)uirp, USB_CR_STOPPED_POLLING);
704 mutex_enter(&xhcip->xhci_lock);
705
706 }
707
708 int
xhci_root_hub_intr_root_enable(xhci_t * xhcip,usba_pipe_handle_data_t * ph,usb_intr_req_t * uirp)709 xhci_root_hub_intr_root_enable(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
710 usb_intr_req_t *uirp)
711 {
712 ASSERT((ph->p_ep.bEndpointAddress & USB_EP_NUM_MASK) == 1);
713 ASSERT((uirp->intr_attributes & USB_ATTRS_ONE_XFER) == 0);
714
715 mutex_enter(&xhcip->xhci_lock);
716 if (xhcip->xhci_state & XHCI_S_ERROR) {
717 mutex_exit(&xhcip->xhci_lock);
718 return (USB_HC_HARDWARE_ERROR);
719 }
720
721 if (xhcip->xhci_usba.xa_intr_cb_ph != NULL) {
722 mutex_exit(&xhcip->xhci_lock);
723 return (USB_BUSY);
724 }
725
726 xhcip->xhci_usba.xa_intr_cb_ph = ph;
727 xhcip->xhci_usba.xa_intr_cb_req = uirp;
728
729 /*
730 * USBA is expecting us to act like a hub and therefore whenever we open
731 * up the interrupt endpoint, we need to generate an event with
732 * information about all the currently outstanding ports with changes.
733 */
734 mutex_exit(&xhcip->xhci_lock);
735 xhci_root_hub_psc_callback(xhcip);
736
737 return (USB_SUCCESS);
738 }
739
740 int
xhci_root_hub_fini(xhci_t * xhcip)741 xhci_root_hub_fini(xhci_t *xhcip)
742 {
743 if (usba_hubdi_unbind_root_hub(xhcip->xhci_dip) != USB_SUCCESS)
744 return (DDI_FAILURE);
745
746 return (DDI_SUCCESS);
747 }
748
749 static int
xhci_root_hub_fill_hub_desc(xhci_t * xhcip)750 xhci_root_hub_fill_hub_desc(xhci_t *xhcip)
751 {
752 int i;
753 uint16_t chars;
754 usb_ss_hub_descr_t *hdp = &xhcip->xhci_usba.xa_hub_descr;
755
756 bzero(hdp, sizeof (usb_ss_hub_descr_t));
757
758 hdp->bDescLength = sizeof (usb_ss_hub_descr_t);
759 hdp->bDescriptorType = ROOT_HUB_SS_DESCRIPTOR_TYPE;
760 hdp->bNbrPorts = xhcip->xhci_caps.xcap_max_ports;
761
762 chars = 0;
763 if (xhcip->xhci_caps.xcap_flags & XCAP_PPC)
764 chars |= HUB_CHARS_INDIVIDUAL_PORT_POWER;
765 chars |= HUB_CHARS_INDIV_OVER_CURRENT;
766 hdp->wHubCharacteristics = LE_16(chars);
767 hdp->bPwrOn2PwrGood = XHCI_POWER_GOOD;
768 hdp->bHubContrCurrent = 0;
769
770 /*
771 * There doesn't appear to be a good way to determine what the impact of
772 * the root hub on the link should be. However, one way to view it is
773 * because everything must transfer through here the impact doesn't
774 * really matter, as everyone is subject to it.
775 */
776 hdp->bHubHdrDecLat = 0;
777 hdp->wHubDelay = 0;
778
779 for (i = 1; i < xhcip->xhci_caps.xcap_max_ports; i++) {
780 uint32_t reg;
781
782 reg = xhci_get32(xhcip, XHCI_R_OPER, XHCI_PORTSC(i));
783 if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
784 xhci_error(xhcip, "encountered fatal FM error while "
785 "reading port status register %d", i);
786 ddi_fm_service_impact(xhcip->xhci_dip,
787 DDI_SERVICE_LOST);
788 return (EIO);
789 }
790
791 if (reg & XHCI_PS_DR)
792 hdp->DeviceRemovable[i / 8] |= 1U << (i % 8);
793 }
794
795 return (0);
796 }
797
798
799 /*
800 * Convert the USB PCI revision which is a uint8_t with 4-bit major and 4-bit
801 * minor into a uint16_t with a 8-bit major and 8-bit minor.
802 */
803 static uint16_t
xhci_root_vers_to_bcd(uint8_t vers)804 xhci_root_vers_to_bcd(uint8_t vers)
805 {
806 uint8_t major, minor;
807
808 major = (vers & 0xf0) >> 4;
809 minor = (vers & 0x0f);
810 return ((major << 8) | minor);
811 }
812
813 static void
xhci_root_hub_fill_dev_desc(xhci_t * xhcip,usb_dev_descr_t * hub)814 xhci_root_hub_fill_dev_desc(xhci_t *xhcip, usb_dev_descr_t *hub)
815 {
816 hub->bLength = sizeof (usb_dev_descr_t);
817
818 /*
819 * The descriptor type is that for a device, which is 0x1.
820 */
821 hub->bDescriptorType = 0x01;
822 hub->bcdUSB = xhci_root_vers_to_bcd(xhcip->xhci_caps.xcap_usb_vers);
823
824 /*
825 * As we're trying to pretend we're a hub, we have a fixed device id of
826 * 0x09. Note, that the device protocol for a super-speed hub
827 * technically isn't registered as 0x3; however, a vast majority of
828 * systems out there fake this up to indicate that it's a USB 3.x era
829 * device. This is presumably due to the suggestions as made in USB 3.1
830 * / 10.5.1.
831 */
832 hub->bDeviceClass = USB_CLASS_HUB;
833 hub->bDeviceSubClass = 0x00;
834 hub->bDeviceProtocol = 0x03;
835
836 /*
837 * The only valid value for a USB 3 device is 09h as indicated in USB
838 * 3.1 / 9.6.6.
839 */
840 hub->bMaxPacketSize0 = 9;
841
842 /*
843 * We have no real identification information, so we set it all to
844 * zero.
845 */
846 hub->idVendor = 0x00;
847 hub->idProduct = 0x00;
848 hub->bcdDevice = 0x00;
849 hub->iManufacturer = 0x00;
850 hub->iProduct = 0x00;
851 hub->iSerialNumber = 0x00;
852
853 /*
854 * To keep our lives simple, we only have a single piece of
855 * configuration for this device.
856 */
857 hub->bNumConfigurations = 0x01;
858 }
859
860 /*
861 * To register a root hub with the framework, we need to fake up a bunch of
862 * information for usba, particularly we need to basically feed it the device
863 * configuration in the form that USB expects. See section 10.15.1 for more
864 * information.
865 */
866 int
xhci_root_hub_init(xhci_t * xhcip)867 xhci_root_hub_init(xhci_t *xhcip)
868 {
869 usb_dev_descr_t *hub = &xhcip->xhci_usba.xa_dev_descr;
870 uchar_t *conf = (uchar_t *)&xhci_hcdi_conf;
871
872 xhci_root_hub_fill_dev_desc(xhcip, hub);
873 if (xhci_root_hub_fill_hub_desc(xhcip) != 0)
874 return (DDI_FAILURE);
875
876 if (usba_hubdi_bind_root_hub(xhcip->xhci_dip, conf,
877 sizeof (xhci_hcdi_conf), hub) != USB_SUCCESS)
878 return (DDI_FAILURE);
879
880 return (DDI_SUCCESS);
881 }
882