xref: /illumos-gate/usr/src/uts/common/io/usb/hcd/xhci/xhci_command.c (revision c14e87c2f106d7a104ce6ddb17d9298a29a0c6e5)
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  * Copyright 2024 Oxide Computer Company
15  */
16 
17 /*
18  * -----------------------
19  * Command Ring Management
20  * -----------------------
21  *
22  * The command ring is the primary means by which the xHCI controller is
23  * managed. Events may be placed on the ring, at which point they will be
24  * processed in order. When commands are finished they generate event
25  * completions and we are notified via an interrupt.
26  *
27  * Every command is formatted in a transfer request block (TRB). These TRBs are
28  * queued on the command ring. To start the command ring, a doorbell register is
29  * written to. The current state of the command ring is maintained in the
30  * command ring control register (XHCI_CRCR).
31  *
32  * Every command has a condition variable. When the driver submits a command, it
33  * blocks on the command's CV waiting for a change in the commands status. This
34  * CV will be signaled after the command completes or is aborted, allowing the
35  * caller to treat this as a synchronous, blocking operation.
36  *
37  * The command ring itself consists of three primary states:
38  *
39  * 	XHCI_COMMAND_RING_IDLE		The command ring is not currently
40  * 					processing any events. No timeout events
41  * 					are active.
42  *
43  * 	XHCI_COMMAND_RING_RUNNING	The command ring currently has one or
44  * 					more events enqueued and the hardware
45  * 					has been signalled to process commands.
46  *
47  * 	XHCI_COMMAND_RING_ABORTING	A command has timed out and we are
48  * 					attempting to abort the current command,
49  * 					which will stop the ring.
50  *
51  * 	XHCI_COMMAND_RING_ABORT_DONE	We have successfully received a
52  * 					notification that the abort worked and
53  * 					that the command ring has stopped. This
54  * 					allows us to clean up state and
55  * 					transition back to either idle or
56  * 					running, depending on if we have queued
57  * 					commands.
58  *
59  * The state transition can be summarized as:
60  *
61  *    +------+                        +---------+
62  *    | Idle |--------*-------------->| Running |<----------------------+
63  *    +------+        . Command       +---------+                       |
64  *       ^              TRB queued      |    |                          |
65  *       |              on ring         |    |                          |
66  *       |                              |    * . . Command not          |
67  *       +-------*----------------------+    |     acknowledged         |
68  *       |       . . No more                 |     within timeout       |
69  *       |           commands                |     xhci_command_wait    |
70  *       |           queued                  |                          |
71  *       |                                   v       . abort request    |
72  *       * . No commands              +----------+   . times out        |
73  *       |   queued after             | Aborting |---*--+               |
74  *       |   successful               +----------+      v               |
75  *       |   abort                         |      +----------+          |
76  *       |                       abort . . *      | HW Reset |          |
77  *       |                acknowledged     |      +----------+          |
78  *       |                                 v                            |
79  *       |                           +------------+                     |
80  *       +---------------------------| Abort Done |----*----------------+
81  *                                   +------------+    . Commands queued
82  *                                                       after successful
83  *                                                       abort
84  *
85  * ---------------------------
86  * Timeouts and Command Aborts
87  * ---------------------------
88  *
89  * Commands may time out either due to issues with the host controller or with
90  * the devices connected to it. For example, the ADDRESS DEVICE command may
91  * issue commands to the device. As such, we need to be prepared for commands to
92  * time out.
93  *
94  * To deal with a stalled command, we write to the XHCI_CRCR register to abort
95  * the currently running command. This is discussed in xHCI 1.1 / 4.6.1.2. When
96  * a command is aborted, we should eventually receive a TRB completion for that
97  * command. However, this is no guarantee that an abort will be successful. The
98  * specification recommends waiting about 5 seconds for that to finish. After
99  * which we terminate the device.
100  *
101  * For an abort to be successful, we expect two different notifications. First
102  * we should receive a TRB for the actual command itself indicating that it's
103  * terminated. Next, we should receive a TRB indicating that the command ring
104  * has stopped. Only when we receive this second one, do we consider re-enabling
105  * the command ring.
106  *
107  * -------
108  * Locking
109  * -------
110  *
111  * The command ring's lock, xhci_command_ring_t`xcr_lock, should not be accessed
112  * outside of this file. If a caller needs to take the xhci_t`xhci_lock, it must
113  * be taken before the xcr_lock is taken. It is illegal for to hold
114  * xhci_t`xhci_lock across any command functions. Doing so would lead to
115  * deadlock.
116  */
117 
118 #include <sys/usb/hcd/xhci/xhci.h>
119 #include <sys/sysmacros.h>
120 
121 /*
122  * Recommended time to wait for an abort in from the Implementation Note
123  * in XHCI 1.1 / 4.6.1.2. The time is kept in microseconds.
124  */
125 clock_t xhci_command_abort_wait = 5 * MICROSEC;
126 
127 /*
128  * Default to waiting for one second for a command to time out. Time stored in
129  * microseconds.
130  */
131 clock_t xhci_command_wait = MICROSEC;
132 
133 /*
134  * Required forwards.
135  */
136 static void xhci_command_settimeout(xhci_t *, clock_t);
137 
138 void
xhci_command_ring_fini(xhci_t * xhcip)139 xhci_command_ring_fini(xhci_t *xhcip)
140 {
141 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
142 
143 	/*
144 	 * If the ring is not allocated, then nothing else is here.
145 	 */
146 	if (xcr->xcr_ring.xr_trb == NULL)
147 		return;
148 	VERIFY(xcr->xcr_timeout == 0);
149 	xhci_ring_free(&xcr->xcr_ring);
150 	mutex_destroy(&xcr->xcr_lock);
151 	cv_destroy(&xcr->xcr_cv);
152 	list_destroy(&xcr->xcr_commands);
153 }
154 
155 /*
156  * Initialize or re-initialize the command ring. This will be called whenever we
157  * reset the xHCI commandler, so we may actually have already allocated DMA
158  * memory for the ring.
159  */
160 int
xhci_command_ring_init(xhci_t * xhcip)161 xhci_command_ring_init(xhci_t *xhcip)
162 {
163 	int ret;
164 	uint64_t addr;
165 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
166 
167 	if (xcr->xcr_ring.xr_trb == NULL) {
168 		if ((ret = xhci_ring_alloc(xhcip, &xcr->xcr_ring)) != 0)
169 			return (ret);
170 	}
171 
172 	if ((ret = xhci_ring_reset(xhcip, &xcr->xcr_ring)) != 0)
173 		return (ret);
174 
175 #ifdef	DEBUG
176 	addr = xhci_get64(xhcip, XHCI_R_OPER, XHCI_CRCR);
177 	VERIFY0(addr & XHCI_CRCR_CRR);
178 #endif
179 	addr = LE_64(xhci_dma_pa(&xcr->xcr_ring.xr_dma) | XHCI_CRCR_RCS);
180 	xhci_put64(xhcip, XHCI_R_OPER, XHCI_CRCR, addr);
181 	if (xhci_check_regs_acc(xhcip) != DDI_FM_OK)
182 		return (EIO);
183 
184 	mutex_init(&xcr->xcr_lock, NULL, MUTEX_DRIVER,
185 	    DDI_INTR_PRI(xhcip->xhci_intr_pri));
186 	cv_init(&xcr->xcr_cv, NULL, CV_DRIVER, NULL);
187 	list_create(&xcr->xcr_commands, sizeof (xhci_command_t),
188 	    offsetof(xhci_command_t, xco_link));
189 	return (0);
190 }
191 
192 static void
xhci_command_timeout(void * arg)193 xhci_command_timeout(void *arg)
194 {
195 	uint64_t reg;
196 	clock_t delay;
197 	xhci_t *xhcip = arg;
198 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
199 	xhci_command_t *xco;
200 
201 	mutex_enter(&xcr->xcr_lock);
202 
203 	xco = list_head(&xcr->xcr_commands);
204 	if (xco == NULL || xco->xco_state != XHCI_COMMAND_S_QUEUED) {
205 		xcr->xcr_timeout = 0;
206 		mutex_exit(&xcr->xcr_lock);
207 		return;
208 	}
209 
210 	xcr->xcr_state = XHCI_COMMAND_RING_ABORTING;
211 	reg = xhci_get64(xhcip, XHCI_R_OPER, XHCI_CRCR);
212 	if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
213 		xcr->xcr_timeout = 0;
214 		mutex_exit(&xcr->xcr_lock);
215 		xhci_error(xhcip, "encountered fatal FM error reading command "
216 		    "ring control register: resetting device");
217 		xhci_fm_runtime_reset(xhcip);
218 		return;
219 	}
220 
221 	/*
222 	 * While all the other bits should be ignored because we're running, if
223 	 * for some reason we're not running, then this will make sure that we
224 	 * don't screw things up.
225 	 */
226 	reg |= XHCI_CRCR_CA;
227 	xhci_put64(xhcip, XHCI_R_OPER, XHCI_CRCR, reg);
228 	if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
229 		xcr->xcr_timeout = 0;
230 		mutex_exit(&xcr->xcr_lock);
231 		xhci_error(xhcip, "encountered fatal FM error writing command "
232 		    "ring control register: resetting device");
233 		xhci_fm_runtime_reset(xhcip);
234 		return;
235 	}
236 
237 	delay = drv_usectohz(xhci_command_abort_wait);
238 	while (xcr->xcr_state != XHCI_COMMAND_RING_ABORT_DONE) {
239 		int ret;
240 
241 		ret = cv_reltimedwait(&xcr->xcr_cv, &xcr->xcr_lock, delay,
242 		    TR_CLOCK_TICK);
243 		if (ret == -1) {
244 			/* Time out waiting for the abort */
245 			xcr->xcr_timeout = 0;
246 			mutex_exit(&xcr->xcr_lock);
247 			xhci_error(xhcip, "abort command timed out: resetting "
248 			    "device");
249 			xhci_fm_runtime_reset(xhcip);
250 			return;
251 		}
252 	}
253 
254 	/*
255 	 * Successful abort, transition the ring as needed.
256 	 */
257 	if (list_is_empty(&xcr->xcr_commands) != 0) {
258 		xcr->xcr_state = XHCI_COMMAND_RING_IDLE;
259 		xcr->xcr_timeout = 0;
260 	} else {
261 		xhci_put32(xhcip, XHCI_R_DOOR, XHCI_DOORBELL(0), 0);
262 		if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
263 			xcr->xcr_timeout = 0;
264 			mutex_exit(&xcr->xcr_lock);
265 			xhci_error(xhcip, "encountered fatal FM error writing "
266 			    "command ring control register: resetting device");
267 			xhci_fm_runtime_reset(xhcip);
268 			return;
269 		}
270 
271 		/*
272 		 * Reset our timeout id before we create a new timeout
273 		 */
274 		xcr->xcr_timeout = 0;
275 		xhci_command_settimeout(xhcip, xhci_command_wait);
276 		xcr->xcr_state = XHCI_COMMAND_RING_RUNNING;
277 	}
278 	mutex_exit(&xcr->xcr_lock);
279 }
280 
281 static void
xhci_command_settimeout(xhci_t * xhcip,clock_t microsecs)282 xhci_command_settimeout(xhci_t *xhcip, clock_t microsecs)
283 {
284 	clock_t delay;
285 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
286 
287 	ASSERT(MUTEX_HELD(&xcr->xcr_lock));
288 	ASSERT(xcr->xcr_timeout == 0);
289 
290 	delay = drv_usectohz(microsecs);
291 	xcr->xcr_timeout = timeout(xhci_command_timeout, xhcip, delay);
292 }
293 
294 void
xhci_command_init(xhci_command_t * xcp)295 xhci_command_init(xhci_command_t *xcp)
296 {
297 	bzero(xcp, sizeof (xhci_command_t));
298 	cv_init(&xcp->xco_cv, NULL, CV_DRIVER, NULL);
299 }
300 
301 void
xhci_command_fini(xhci_command_t * xcp)302 xhci_command_fini(xhci_command_t *xcp)
303 {
304 	cv_destroy(&xcp->xco_cv);
305 }
306 
307 boolean_t
xhci_command_event_callback(xhci_t * xhcip,xhci_trb_t * trb)308 xhci_command_event_callback(xhci_t *xhcip, xhci_trb_t *trb)
309 {
310 	int cstat;
311 	timeout_id_t to;
312 	xhci_command_t *xco, *rem;
313 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
314 	xhci_ring_t *xrp = &xcr->xcr_ring;
315 
316 	mutex_enter(&xcr->xcr_lock);
317 
318 	/*
319 	 * If we got an event that indicates that the command ring was stopped,
320 	 * then we have successfully finished an abort. While a command ring
321 	 * stop can also be done by writing to the XHCI_CRCR register, the
322 	 * driver does not do so at this time; however, we guard the state
323 	 * transition just in case.
324 	 */
325 	cstat = XHCI_TRB_GET_CODE(LE_32(trb->trb_status));
326 	if (cstat == XHCI_CODE_CMD_RING_STOP) {
327 		if (xcr->xcr_state == XHCI_COMMAND_RING_ABORTING)
328 			xcr->xcr_state = XHCI_COMMAND_RING_ABORT_DONE;
329 		cv_broadcast(&xcr->xcr_cv);
330 		mutex_exit(&xcr->xcr_lock);
331 		return (B_TRUE);
332 	}
333 
334 	xco = list_head(&xcr->xcr_commands);
335 	VERIFY(xco != NULL);
336 
337 	/*
338 	 * The current event should be pointed to by the ring's tail pointer.
339 	 * We need to check if this DMA address that we've been given matches
340 	 * the address that we'd expect for the tail.
341 	 */
342 	if (xhci_ring_trb_tail_valid(xrp, LE_64(trb->trb_addr)) == B_FALSE) {
343 		mutex_exit(&xcr->xcr_lock);
344 		return (B_TRUE);
345 	}
346 
347 	xco->xco_state = XHCI_COMMAND_S_RECEIVED;
348 	to = xcr->xcr_timeout;
349 	xcr->xcr_timeout = 0;
350 	if (xcr->xcr_state != XHCI_COMMAND_RING_ABORTING) {
351 		mutex_exit(&xcr->xcr_lock);
352 		(void) untimeout(to);
353 		mutex_enter(&xcr->xcr_lock);
354 	}
355 	rem = list_remove_head(&xcr->xcr_commands);
356 
357 	VERIFY3P(rem, ==, xco);
358 
359 	xco->xco_res.trb_addr = LE_64(trb->trb_addr);
360 	xco->xco_res.trb_status = LE_32(trb->trb_status);
361 	xco->xco_res.trb_flags = LE_32(trb->trb_flags);
362 	xco->xco_state = XHCI_COMMAND_S_DONE;
363 
364 	/*
365 	 * Advance the ring and wake up anyone who was waiting for a slot.
366 	 */
367 	if (xhci_ring_trb_consumed(xrp, LE_64(trb->trb_addr)) == B_FALSE) {
368 		/*
369 		 * Indicate that we need to do a runtime reset to the interrupt
370 		 * handler.
371 		 */
372 		mutex_exit(&xcr->xcr_lock);
373 		xhci_error(xhcip, "encountered invalid TRB head while "
374 		    "processing command ring: TRB with addr 0x%"PRIx64 " could "
375 		    "not be consumed", LE_64(trb->trb_addr));
376 		xhci_fm_runtime_reset(xhcip);
377 		return (B_FALSE);
378 	}
379 	cv_broadcast(&xcr->xcr_cv);
380 
381 	if (xcr->xcr_state < XHCI_COMMAND_RING_ABORTING) {
382 		if (list_is_empty(&xcr->xcr_commands) != 0) {
383 			xcr->xcr_state = XHCI_COMMAND_RING_IDLE;
384 		} else {
385 			xhci_command_settimeout(xhcip, xhci_command_wait);
386 		}
387 	}
388 	mutex_exit(&xcr->xcr_lock);
389 
390 	/*
391 	 * Now, let anyone waiting for this command to finish know it's done.
392 	 */
393 	cv_signal(&xco->xco_cv);
394 
395 	return (B_TRUE);
396 }
397 
398 static int
xhci_command_submit(xhci_t * xhcip,xhci_command_t * xco)399 xhci_command_submit(xhci_t *xhcip, xhci_command_t *xco)
400 {
401 	int ret;
402 	xhci_command_ring_t *xcr = &xhcip->xhci_command;
403 	xhci_ring_t *xrp = &xcr->xcr_ring;
404 
405 	mutex_enter(&xcr->xcr_lock);
406 
407 	while (xhci_ring_trb_space(xrp, 1U) == B_FALSE ||
408 	    xcr->xcr_state >= XHCI_COMMAND_RING_ABORTING) {
409 		cv_wait(&xcr->xcr_cv, &xcr->xcr_lock);
410 	}
411 
412 	xhci_ring_trb_put(xrp, &xco->xco_req);
413 	xco->xco_state = XHCI_COMMAND_S_QUEUED;
414 	list_insert_tail(&xcr->xcr_commands, xco);
415 
416 	/*
417 	 * Now, make sure the ring is synched up before we might ring the door
418 	 * bell and wake up the processor, if they're not currently doing so.
419 	 */
420 	XHCI_DMA_SYNC(xrp->xr_dma, DDI_DMA_SYNC_FORDEV);
421 	if (xhci_check_dma_handle(xhcip, &xrp->xr_dma) != DDI_FM_OK) {
422 		mutex_exit(&xcr->xcr_lock);
423 		xhci_error(xhcip, "encountered fatal FM error syncing command "
424 		    "ring DMA contents: resetting device");
425 		xhci_fm_runtime_reset(xhcip);
426 		return (USB_HC_HARDWARE_ERROR);
427 	}
428 
429 	/*
430 	 * Always ring the door bell. You never know what state the ring will be
431 	 * in, but we do know that we won't be waiting for an abort as we're
432 	 * protecting that state currently with the xcr_lock.
433 	 */
434 	xhci_put32(xhcip, XHCI_R_DOOR, XHCI_DOORBELL(0), 0);
435 	if (xhci_check_regs_acc(xhcip) != DDI_FM_OK) {
436 		mutex_exit(&xcr->xcr_lock);
437 		xhci_error(xhcip, "encountered fatal FM error ringing command "
438 		    "ring doorbell: resetting device");
439 		xhci_fm_runtime_reset(xhcip);
440 		return (USB_HC_HARDWARE_ERROR);
441 	}
442 
443 	/*
444 	 * If the command ring is currently considered idle, make sure to start
445 	 * up the timeout.
446 	 */
447 	if (xcr->xcr_state == XHCI_COMMAND_RING_IDLE) {
448 		VERIFY(xcr->xcr_timeout == 0);
449 
450 		xhci_command_settimeout(xhcip, xhci_command_wait);
451 		xcr->xcr_state = XHCI_COMMAND_RING_RUNNING;
452 	}
453 
454 	while (xco->xco_state < XHCI_COMMAND_S_DONE)
455 		cv_wait(&xco->xco_cv, &xcr->xcr_lock);
456 
457 	/*
458 	 * When we return USB_SUCCESS, the actual error is returned in the
459 	 * command's structure.
460 	 */
461 	if (xco->xco_state == XHCI_COMMAND_S_DONE)
462 		ret = USB_SUCCESS;
463 	else
464 		ret = USB_HC_HARDWARE_ERROR;
465 	mutex_exit(&xcr->xcr_lock);
466 
467 	return (ret);
468 }
469 
470 int
xhci_command_enable_slot(xhci_t * xhcip,uint8_t * slotp)471 xhci_command_enable_slot(xhci_t *xhcip, uint8_t *slotp)
472 {
473 	int ret;
474 	uint8_t slot, code;
475 	xhci_command_t co;
476 
477 	VERIFY(xhcip != NULL);
478 	VERIFY(slotp != NULL);
479 
480 	xhci_command_init(&co);
481 
482 	/*
483 	 * Note, the slot type is supposed to vary depending on the protocol
484 	 * type. However, XHCI 1.1/7.2.2.1.4 explicitly says that this will
485 	 * always be set to zero for both USB 2 and USB 3, hence why we hardcode
486 	 * this to zero and thus only have the command to enable the slot set
487 	 * below.
488 	 */
489 	co.xco_req.trb_flags = LE_32(XHCI_CMD_ENABLE_SLOT) |
490 	    XHCI_TRB_SET_STYPE(0);
491 	ret = xhci_command_submit(xhcip, &co);
492 	if (ret != 0)
493 		goto done;
494 
495 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
496 	slot = XHCI_TRB_GET_SLOT(co.xco_res.trb_flags);
497 
498 	if (code == XHCI_CODE_SUCCESS) {
499 		*slotp = slot;
500 		ret = USB_SUCCESS;
501 	} else if (code == XHCI_CODE_NO_SLOTS) {
502 		ret = USB_NO_RESOURCES;
503 	} else if (code == XHCI_CODE_CMD_ABORTED) {
504 		ret = USB_CR_TIMEOUT;
505 	} else {
506 		ret = USB_HC_HARDWARE_ERROR;
507 		xhci_log(xhcip, "!unexpected error when enabling slot: "
508 		    "%d", code);
509 	}
510 
511 done:
512 	xhci_command_fini(&co);
513 	return (ret);
514 }
515 
516 int
xhci_command_disable_slot(xhci_t * xhcip,uint8_t slot)517 xhci_command_disable_slot(xhci_t *xhcip, uint8_t slot)
518 {
519 	int ret, code;
520 	xhci_command_t co;
521 
522 	VERIFY(xhcip != NULL);
523 
524 	xhci_command_init(&co);
525 	co.xco_req.trb_flags = LE_32(XHCI_CMD_DISABLE_SLOT |
526 	    XHCI_TRB_SET_SLOT(slot));
527 	ret = xhci_command_submit(xhcip, &co);
528 	if (ret != 0)
529 		goto done;
530 
531 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
532 	if (code == XHCI_CODE_SUCCESS) {
533 		ret = USB_SUCCESS;
534 	} else if (code == XHCI_CODE_CMD_ABORTED) {
535 		ret = USB_CR_TIMEOUT;
536 	} else {
537 		ret = USB_HC_HARDWARE_ERROR;
538 		xhci_log(xhcip, "!unexpected error when disabling slot: "
539 		    "%d", code);
540 	}
541 
542 done:
543 	xhci_command_fini(&co);
544 	return (ret);
545 }
546 
547 int
xhci_command_set_address(xhci_t * xhcip,xhci_device_t * xd,boolean_t bsr)548 xhci_command_set_address(xhci_t *xhcip, xhci_device_t *xd, boolean_t bsr)
549 {
550 	int ret, code;
551 	xhci_command_t co;
552 
553 	VERIFY(xhcip != NULL);
554 	VERIFY(xd != NULL);
555 
556 	xhci_command_init(&co);
557 	co.xco_req.trb_addr = LE_64(xhci_dma_pa(&xd->xd_ictx));
558 	co.xco_req.trb_status = 0;
559 	co.xco_req.trb_flags = LE_32(XHCI_CMD_ADDRESS_DEVICE |
560 	    XHCI_TRB_SET_SLOT(xd->xd_slot));
561 	if (bsr == B_TRUE)
562 		co.xco_req.trb_flags |= LE_32(XHCI_TRB_BSR);
563 
564 	ret = xhci_command_submit(xhcip, &co);
565 	if (ret != 0)
566 		goto done;
567 
568 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
569 	if (code == XHCI_CODE_SUCCESS) {
570 		ret = USB_SUCCESS;
571 	} else if (code == XHCI_CODE_CMD_ABORTED) {
572 		ret = USB_CR_TIMEOUT;
573 	} else {
574 		ret = USB_HC_HARDWARE_ERROR;
575 		xhci_log(xhcip, "!unexpected error when setting address: "
576 		    "%d", code);
577 	}
578 done:
579 	xhci_command_fini(&co);
580 	return (ret);
581 }
582 
583 int
xhci_command_configure_endpoint(xhci_t * xhcip,xhci_device_t * xd)584 xhci_command_configure_endpoint(xhci_t *xhcip, xhci_device_t *xd)
585 {
586 	int ret, code;
587 	xhci_command_t co;
588 
589 	VERIFY(xhcip != NULL);
590 	VERIFY(xd != NULL);
591 
592 	xhci_command_init(&co);
593 	co.xco_req.trb_addr = LE_64(xhci_dma_pa(&xd->xd_ictx));
594 	co.xco_req.trb_status = LE_32(0);
595 	co.xco_req.trb_flags = LE_32(XHCI_CMD_CONFIG_EP |
596 	    XHCI_TRB_SET_SLOT(xd->xd_slot));
597 
598 	ret = xhci_command_submit(xhcip, &co);
599 	if (ret != 0)
600 		goto done;
601 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
602 	switch (code) {
603 	case XHCI_CODE_SUCCESS:
604 		ret = USB_SUCCESS;
605 		break;
606 	case XHCI_CODE_CMD_ABORTED:
607 		ret = USB_CR_TIMEOUT;
608 		break;
609 	case XHCI_CODE_SLOT_NOT_ON:
610 		xhci_log(xhcip, "!failed to configure endpoints for slot %d, "
611 		    "slot not on, likely driver bug!", xd->xd_slot);
612 		ret = USB_FAILURE;
613 		break;
614 	case XHCI_CODE_BANDWIDTH:
615 		ret = USB_NO_BANDWIDTH;
616 		break;
617 	case XHCI_CODE_RESOURCE:
618 		ret = USB_NO_RESOURCES;
619 		break;
620 	default:
621 		ret = USB_HC_HARDWARE_ERROR;
622 		xhci_log(xhcip, "!unexpected error when configuring enpoints: "
623 		    "%d", code);
624 		break;
625 	}
626 done:
627 	xhci_command_fini(&co);
628 	return (ret);
629 }
630 
631 int
xhci_command_evaluate_context(xhci_t * xhcip,xhci_device_t * xd)632 xhci_command_evaluate_context(xhci_t *xhcip, xhci_device_t *xd)
633 {
634 	int ret, code;
635 	xhci_command_t co;
636 
637 	VERIFY(xhcip != NULL);
638 	VERIFY(xd != NULL);
639 
640 	xhci_command_init(&co);
641 	co.xco_req.trb_addr = LE_64(xhci_dma_pa(&xd->xd_ictx));
642 	co.xco_req.trb_status = LE_32(0);
643 	co.xco_req.trb_flags = LE_32(XHCI_CMD_EVAL_CTX |
644 	    XHCI_TRB_SET_SLOT(xd->xd_slot));
645 
646 	ret = xhci_command_submit(xhcip, &co);
647 	if (ret != 0)
648 		goto done;
649 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
650 	switch (code) {
651 	case XHCI_CODE_SUCCESS:
652 		ret = USB_SUCCESS;
653 		break;
654 	case XHCI_CODE_CMD_ABORTED:
655 		ret = USB_CR_TIMEOUT;
656 		break;
657 	case XHCI_CODE_SLOT_NOT_ON:
658 		xhci_log(xhcip, "!failed to evaluate endpoints for slot %d, "
659 		    "slot not on, likely driver bug!", xd->xd_slot);
660 		ret = USB_FAILURE;
661 		break;
662 	default:
663 		ret = USB_HC_HARDWARE_ERROR;
664 		xhci_log(xhcip, "!unexpected error when evaluating enpoints: "
665 		    "%d", code);
666 		break;
667 	}
668 done:
669 	xhci_command_fini(&co);
670 	return (ret);
671 
672 }
673 
674 int
xhci_command_reset_endpoint(xhci_t * xhcip,xhci_device_t * xd,xhci_endpoint_t * xep)675 xhci_command_reset_endpoint(xhci_t *xhcip, xhci_device_t *xd,
676     xhci_endpoint_t *xep)
677 {
678 	int ret, code;
679 	xhci_command_t co;
680 
681 	VERIFY(xhcip != NULL);
682 	VERIFY(xd != NULL);
683 	VERIFY(xep != NULL);
684 
685 	xhci_command_init(&co);
686 
687 	co.xco_req.trb_addr = LE_64(0);
688 	co.xco_req.trb_status = LE_32(0);
689 	co.xco_req.trb_flags = LE_32(XHCI_CMD_RESET_EP |
690 	    XHCI_TRB_SET_SLOT(xd->xd_slot) |
691 	    XHCI_TRB_SET_EP(xep->xep_num + 1));
692 
693 	ret = xhci_command_submit(xhcip, &co);
694 	if (ret != 0)
695 		goto done;
696 
697 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
698 	switch (code) {
699 	case XHCI_CODE_SUCCESS:
700 		ret = USB_SUCCESS;
701 		break;
702 	case XHCI_CODE_CMD_ABORTED:
703 		ret = USB_CR_TIMEOUT;
704 		break;
705 	case XHCI_CODE_CONTEXT_STATE:
706 	case XHCI_CODE_SLOT_NOT_ON:
707 		xhci_log(xhcip, "!xhci reset endpoint command: asked to modify "
708 		    "endpoint (%u)/slot (%d) in wrong state: %d", xep->xep_num,
709 		    xd->xd_slot, code);
710 		if (code == XHCI_CODE_CONTEXT_STATE) {
711 			xhci_endpoint_context_t *epctx;
712 
713 			epctx = xd->xd_endout[xep->xep_num];
714 			xhci_log(xhcip, "!endpoint is in state %d",
715 			    XHCI_EPCTX_STATE(epctx->xec_info));
716 		}
717 		ret = USB_INVALID_CONTEXT;
718 		break;
719 	default:
720 		ret = USB_HC_HARDWARE_ERROR;
721 		xhci_log(xhcip, "!unexpected error when resetting enpoint: %d",
722 		    code);
723 		break;
724 	}
725 
726 done:
727 	xhci_command_fini(&co);
728 	return (ret);
729 }
730 
731 int
xhci_command_set_tr_dequeue(xhci_t * xhcip,xhci_device_t * xd,xhci_endpoint_t * xep)732 xhci_command_set_tr_dequeue(xhci_t *xhcip, xhci_device_t *xd,
733     xhci_endpoint_t *xep)
734 {
735 	uint64_t pa;
736 	int ret, code;
737 	xhci_command_t co;
738 	xhci_ring_t *xrp;
739 
740 	VERIFY(xhcip != NULL);
741 	VERIFY(xd != NULL);
742 	VERIFY(xep != NULL);
743 
744 	xhci_command_init(&co);
745 
746 	xrp = &xep->xep_ring;
747 	pa = xhci_dma_pa(&xrp->xr_dma) + sizeof (xhci_trb_t) * xrp->xr_tail;
748 	pa |= xrp->xr_cycle;
749 	co.xco_req.trb_addr = LE_64(pa);
750 	co.xco_req.trb_status = LE_32(0);
751 	co.xco_req.trb_flags = LE_32(XHCI_CMD_SET_TR_DEQ |
752 	    XHCI_TRB_SET_SLOT(xd->xd_slot) |
753 	    XHCI_TRB_SET_EP(xep->xep_num + 1));
754 
755 	ret = xhci_command_submit(xhcip, &co);
756 	if (ret != 0)
757 		goto done;
758 
759 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
760 	switch (code) {
761 	case XHCI_CODE_SUCCESS:
762 		ret = USB_SUCCESS;
763 		break;
764 	case XHCI_CODE_CMD_ABORTED:
765 		ret = USB_CR_TIMEOUT;
766 		break;
767 	case XHCI_CODE_CONTEXT_STATE:
768 	case XHCI_CODE_SLOT_NOT_ON:
769 		xhci_log(xhcip, "!xhci set tr dequeue command: asked to modify "
770 		    "endpoint (%u)/slot (%d) in wrong state: %d", xep->xep_num,
771 		    xd->xd_slot, code);
772 		if (code == XHCI_CODE_CONTEXT_STATE) {
773 			xhci_endpoint_context_t *epctx;
774 
775 			epctx = xd->xd_endout[xep->xep_num];
776 			xhci_log(xhcip, "!endpoint is in state %d",
777 			    XHCI_EPCTX_STATE(epctx->xec_info));
778 		}
779 		ret = USB_INVALID_CONTEXT;
780 		break;
781 	default:
782 		ret = USB_HC_HARDWARE_ERROR;
783 		xhci_log(xhcip, "!unexpected error when resetting enpoint: %d",
784 		    code);
785 		break;
786 	}
787 
788 done:
789 	xhci_command_fini(&co);
790 	return (ret);
791 
792 }
793 
794 int
xhci_command_stop_endpoint(xhci_t * xhcip,xhci_device_t * xd,xhci_endpoint_t * xep)795 xhci_command_stop_endpoint(xhci_t *xhcip, xhci_device_t *xd,
796     xhci_endpoint_t *xep)
797 {
798 	int ret, code;
799 	xhci_command_t co;
800 	xhci_endpoint_context_t *epctx;
801 
802 	VERIFY(xhcip != NULL);
803 	VERIFY(xd != NULL);
804 	VERIFY(xep != NULL);
805 
806 	xhci_command_init(&co);
807 
808 	co.xco_req.trb_addr = LE_64(0);
809 	co.xco_req.trb_status = LE_32(0);
810 	co.xco_req.trb_flags = LE_32(XHCI_CMD_STOP_EP |
811 	    XHCI_TRB_SET_SLOT(xd->xd_slot) |
812 	    XHCI_TRB_SET_EP(xep->xep_num + 1));
813 
814 	ret = xhci_command_submit(xhcip, &co);
815 	if (ret != 0)
816 		goto done;
817 
818 	code = XHCI_TRB_GET_CODE(co.xco_res.trb_status);
819 	switch (code) {
820 	case XHCI_CODE_SUCCESS:
821 		ret = USB_SUCCESS;
822 		break;
823 	case XHCI_CODE_CMD_ABORTED:
824 		ret = USB_CR_TIMEOUT;
825 		break;
826 	case XHCI_CODE_CONTEXT_STATE:
827 		/*
828 		 * This error occurs if we try to stop an endpoint that was not
829 		 * already in the RUNNING state.  We're trying to get to
830 		 * STOPPED, so if we were already there we don't need to
831 		 * complain about it.
832 		 */
833 		epctx = xd->xd_endout[xep->xep_num];
834 		if (XHCI_EPCTX_STATE(epctx->xec_info) != XHCI_EP_STOPPED) {
835 			xhci_log(xhcip, "!stopped endpoint (%d)/slot (%u) in "
836 			    "unexpected state %d", xep->xep_num, xd->xd_slot,
837 			    XHCI_EPCTX_STATE(epctx->xec_info));
838 		}
839 		ret = USB_INVALID_CONTEXT;
840 		break;
841 	default:
842 		ret = USB_HC_HARDWARE_ERROR;
843 		xhci_log(xhcip, "!unexpected error (%d) when resetting "
844 		    "endpoint (%d)/slot (%u)", code,
845 		    xep->xep_num, xd->xd_slot);
846 		break;
847 	}
848 
849 done:
850 	xhci_command_fini(&co);
851 	return (ret);
852 }
853