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