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 (c) 2018, Joyent, Inc.
14 *
15 * Copyright (c) 2019 by Western Digital Corporation
16 */
17
18 /*
19 * This next series of routines is used for USB console polled I/O.
20 */
21
22 #include <sys/usb/hcd/xhci/xhci.h>
23
24 #include <sys/cmn_err.h>
25
26 static void xhci_polled_panic(xhci_polled_t *xhci_polledp, const char *format,
27 ...) __KVPRINTFLIKE(2) __NORETURN;
28
29 static void
xhci_polled_panic(xhci_polled_t * xhci_polledp,const char * format,...)30 xhci_polled_panic(xhci_polled_t *xhci_polledp, const char *format, ...)
31 {
32 va_list ap;
33
34 va_start(ap, format);
35 vdev_err(xhci_polledp->xhci_polled_xhci->xhci_dip, CE_PANIC, format,
36 ap);
37
38 /*
39 * We will not reach this call. However the compiler doesn't know
40 * that vdev_err(..., CE_PANIC, ...) will not return. So this call
41 * convinces it that this function does indeed never return.
42 */
43 panic(__func__);
44 }
45
46 static void
xhci_polled_set_persistent_error(xhci_polled_t * xhci_polledp,int error)47 xhci_polled_set_persistent_error(xhci_polled_t *xhci_polledp, int error)
48 {
49 if (error != USB_SUCCESS &&
50 xhci_polledp->xhci_polled_persistent_error == USB_SUCCESS) {
51 xhci_polledp->xhci_polled_persistent_error = error;
52 }
53 }
54
55 /*
56 * xhci_polled_init:
57 *
58 * Initialize generic information that is needed to provide USB/POLLED
59 * support.
60 */
61 static int
xhci_polled_init(usba_pipe_handle_data_t * input_pipe_handle,xhci_t * xhcip,usb_console_info_impl_t * console_info)62 xhci_polled_init(usba_pipe_handle_data_t *input_pipe_handle, xhci_t *xhcip,
63 usb_console_info_impl_t *console_info)
64 {
65 xhci_pipe_t *xp;
66 xhci_endpoint_t *xep;
67 xhci_polled_t *xhci_polledp;
68
69 ASSERT(mutex_owned(&xhcip->xhci_lock));
70
71 /*
72 * We have already initialized this structure. If the structure
73 * has already been initialized, then we don't need to redo it.
74 */
75 if (console_info->uci_private != NULL)
76 return (USB_SUCCESS);
77
78 xp = (xhci_pipe_t *)input_pipe_handle->p_hcd_private;
79 if (xp == NULL)
80 return (USB_FAILURE);
81
82 /*
83 * We only support interrupt (keyboards) and not bulk (serial)
84 * endpoints at the moment.
85 */
86 xep = xp->xp_ep;
87 if (xep->xep_type != USB_EP_ATTR_INTR)
88 return (USB_NOT_SUPPORTED);
89
90 /* Allocate and initialize a state structure */
91 xhci_polledp = kmem_zalloc(sizeof (xhci_polled_t), KM_SLEEP);
92
93 xhci_polledp->xhci_polled_xhci = xhcip;
94 xhci_polledp->xhci_polled_input_pipe_handle = input_pipe_handle;
95 xhci_polledp->xhci_polled_endpoint = xep;
96
97 console_info->uci_private = (usb_console_info_private_t)xhci_polledp;
98 return (USB_SUCCESS);
99 }
100
101 static xhci_endpoint_t *
xhci_polled_get_endpoint(xhci_t * xhcip,xhci_trb_t * trb)102 xhci_polled_get_endpoint(xhci_t *xhcip, xhci_trb_t *trb)
103 {
104 int slot, endpoint;
105 xhci_device_t *xd;
106
107 endpoint = XHCI_TRB_GET_EP(LE_32(trb->trb_flags));
108 slot = XHCI_TRB_GET_SLOT(LE_32(trb->trb_flags));
109
110 xd = xhci_device_lookup_by_slot(xhcip, slot);
111 if (xd == NULL)
112 return (NULL);
113
114 /*
115 * Endpoint IDs are indexed based on their Device Context Index, which
116 * means that we need to subtract one to get the actual ID that we use.
117 */
118 return (xd->xd_endpoints[endpoint - 1]);
119 }
120
121 static int
xhci_polled_endpoint_transfer(xhci_polled_t * xhci_polledp,xhci_endpoint_t * xep,xhci_trb_t * trb,uint_t * num_characters)122 xhci_polled_endpoint_transfer(xhci_polled_t *xhci_polledp, xhci_endpoint_t *xep,
123 xhci_trb_t *trb, uint_t *num_characters)
124 {
125 xhci_t *xhcip = xhci_polledp->xhci_polled_xhci;
126 xhci_device_t *xd = xep->xep_xd;
127 uint_t off;
128 int code;
129 xhci_transfer_t *xt;
130 size_t len;
131 xhci_transfer_t *rem;
132 int sched_err;
133
134 /*
135 * This TRB should be part of a transfer. If it's not, then we ignore
136 * it. We also check whether or not it's for the first transfer. Because
137 * the rings are serviced in order, it should be.
138 */
139 if ((xt = xhci_endpoint_determine_transfer(xhcip, xep, trb, &off)) ==
140 NULL) {
141 return (USB_FAILURE);
142 }
143
144 code = XHCI_TRB_GET_CODE(LE_32(trb->trb_status));
145 if (code != XHCI_CODE_SUCCESS)
146 return (USB_FAILURE);
147
148 ASSERT(xep->xep_type == USB_EP_ATTR_INTR);
149
150 if (!xt->xt_data_tohost)
151 return (USB_SUCCESS);
152
153 if (xt->xt_short != 0)
154 return (USB_CR_DATA_UNDERRUN);
155
156 if (xhci_transfer_sync(xhcip, xt, DDI_DMA_SYNC_FORCPU) != DDI_FM_OK) {
157 xhci_polled_panic(xhci_polledp, "failed to process normal "
158 "transfer callback for endpoint %u of device on slot %d "
159 "and port %d: encountered fatal FM error synchronizing "
160 "DMA memory", xhcip, xep->xep_num, xd->xd_slot,
161 xd->xd_port);
162 }
163
164 len = xt->xt_buffer.xdb_len;
165 if (len > sizeof (xhci_polledp->xhci_polled_buf))
166 len = sizeof (xhci_polledp->xhci_polled_buf);
167 xhci_transfer_copy(xt, xhci_polledp->xhci_polled_buf, len, B_TRUE);
168
169 *num_characters = (uint_t)len;
170
171 VERIFY(xhci_ring_trb_consumed(&xep->xep_ring, LE_64(trb->trb_addr)));
172 rem = list_remove_head(&xep->xep_transfers);
173 VERIFY3P(rem, ==, xt);
174
175 xt->xt_short = 0;
176 xt->xt_cr = USB_CR_OK;
177
178 /*
179 * The call below can fail but there isn't much we can do other
180 * than panicing the machine. But that might only re-enter the
181 * kernel debugger with now broken keyboard input. So we are
182 * simply returning the keyboard input that we have succesfully
183 * received because it might enable some progress.
184 */
185 sched_err = xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE);
186 xhci_polled_set_persistent_error(xhci_polledp, sched_err);
187
188 return (USB_SUCCESS);
189 }
190
191 /*
192 * Process the event ring
193 */
194 static int
xhci_polled_event_process(xhci_polled_t * xhci_polledp,uint_t * num_characters)195 xhci_polled_event_process(xhci_polled_t *xhci_polledp, uint_t *num_characters)
196 {
197 xhci_t *xhcip = xhci_polledp->xhci_polled_xhci;
198 xhci_ring_t *xrp = &xhcip->xhci_event.xev_ring;
199 uint_t nevents;
200 int ret;
201 uint64_t addr;
202
203 if (xhcip->xhci_state & XHCI_S_ERROR)
204 return (USB_HC_HARDWARE_ERROR);
205
206 VERIFY(xhcip->xhci_event.xev_segs != NULL);
207
208 XHCI_DMA_SYNC(xrp->xr_dma, DDI_DMA_SYNC_FORKERNEL);
209
210 /* Look for any transfer events */
211 ret = USB_SUCCESS;
212 for (nevents = 0; nevents < xrp->xr_ntrb; nevents++) {
213 xhci_trb_t *trb;
214 xhci_endpoint_t *xep;
215 uint32_t type;
216
217 if ((trb = xhci_ring_event_advance(xrp)) == NULL)
218 break;
219
220 xep = xhci_polled_get_endpoint(xhcip, trb);
221 if (xep == NULL) {
222 xhci_polled_set_persistent_error(xhci_polledp,
223 USB_HC_HARDWARE_ERROR);
224 return (USB_HC_HARDWARE_ERROR);
225 }
226 type = LE_32(trb->trb_flags) & XHCI_TRB_TYPE_MASK;
227
228 if (xep != xhci_polledp->xhci_polled_endpoint ||
229 type != XHCI_EVT_XFER) {
230 /*
231 * We got an event which we are not prepared to
232 * handle here. Call into the normal driver code
233 * which should return here after dispatching a task.
234 */
235 boolean_t processed;
236
237 mutex_exit(&xhcip->xhci_lock);
238 processed = xhci_event_process_trb(xhcip, trb);
239 mutex_enter(&xhcip->xhci_lock);
240
241 if (!processed && xhcip->xhci_state & XHCI_S_ERROR)
242 return (USB_HC_HARDWARE_ERROR);
243 continue;
244 }
245
246 ret = xhci_polled_endpoint_transfer(xhci_polledp, xep, trb,
247 num_characters);
248 if (ret != USB_SUCCESS) {
249 xhci_polled_set_persistent_error(xhci_polledp, ret);
250 break;
251 }
252 }
253
254 addr = xhci_dma_pa(&xrp->xr_dma) + sizeof (xhci_trb_t) * xrp->xr_tail;
255 addr |= XHCI_ERDP_BUSY;
256 xhci_put64(xhcip, XHCI_R_RUN, XHCI_ERDP(0), addr);
257
258 return (ret);
259 }
260
261 int
xhci_hcdi_console_input_init(usba_pipe_handle_data_t * pipe_handle,uchar_t ** polled_buf,usb_console_info_impl_t * console_input_info)262 xhci_hcdi_console_input_init(usba_pipe_handle_data_t *pipe_handle,
263 uchar_t **polled_buf, usb_console_info_impl_t *console_input_info)
264 {
265 xhci_t *xhcip;
266 int ret;
267 xhci_polled_t *xhci_polledp;
268
269 xhcip = xhci_hcdi_get_xhcip_from_dev(pipe_handle->p_usba_device);
270
271 mutex_enter(&xhcip->xhci_lock);
272
273 ret = xhci_polled_init(pipe_handle, xhcip, console_input_info);
274 if (ret != USB_SUCCESS) {
275 mutex_exit(&xhcip->xhci_lock);
276 return (ret);
277 }
278
279 xhci_polledp = (xhci_polled_t *)console_input_info->uci_private;
280 *polled_buf = xhci_polledp->xhci_polled_buf;
281
282 mutex_exit(&xhcip->xhci_lock);
283
284 return (ret);
285 }
286
287 int
xhci_hcdi_console_input_fini(usb_console_info_impl_t * console_input_info)288 xhci_hcdi_console_input_fini(usb_console_info_impl_t *console_input_info)
289 {
290 xhci_polled_t *xhci_polledp;
291
292 xhci_polledp = (xhci_polled_t *)console_input_info->uci_private;
293 if (xhci_polledp != NULL) {
294 kmem_free(xhci_polledp, sizeof (xhci_polled_t));
295 console_input_info->uci_private = NULL;
296 }
297
298 return (USB_SUCCESS);
299 }
300
301 int
xhci_hcdi_console_input_enter(usb_console_info_impl_t * console_input_info)302 xhci_hcdi_console_input_enter(usb_console_info_impl_t *console_input_info)
303 {
304 xhci_polled_t *xhci_polledp;
305 xhci_t *xhcip;
306 xhci_endpoint_t *xep;
307 uint32_t status;
308
309 xhci_polledp = (xhci_polled_t *)console_input_info->uci_private;
310 xhcip = xhci_polledp->xhci_polled_xhci;
311 xep = xhci_polledp->xhci_polled_endpoint;
312
313 if (mutex_tryenter(&xhcip->xhci_lock) == 0)
314 return (USB_BUSY);
315
316 /*
317 * If the controller is already switched over, just return
318 */
319 if (xhci_polledp->xhci_polled_entry > 0) {
320 xhci_polledp->xhci_polled_entry++;
321 ASSERT(xep->xep_state & XHCI_ENDPOINT_POLLED);
322 mutex_exit(&xhcip->xhci_lock);
323 return (USB_SUCCESS);
324 }
325
326 /*
327 * Check to see if we have a fatal bit set. If this is the case the
328 * host controller is not working properly and we don't want to
329 * enter the kernel debugger and leave the system unresponsive.
330 */
331 status = xhci_get32(xhcip, XHCI_R_OPER, XHCI_USBSTS);
332 if ((status & (XHCI_STS_HSE | XHCI_STS_SRE | XHCI_STS_HCE)) != 0) {
333 mutex_exit(&xhcip->xhci_lock);
334 xhci_polled_set_persistent_error(xhci_polledp,
335 USB_HC_HARDWARE_ERROR);
336 return (USB_HC_HARDWARE_ERROR);
337 }
338
339 /*
340 * We only support interrupt (keyboards) and not bulk (serial)
341 * endpoints at the moment.
342 */
343 if (xhci_polledp->xhci_polled_endpoint->xep_type != USB_EP_ATTR_INTR) {
344 mutex_exit(&xhcip->xhci_lock);
345 return (USB_NOT_SUPPORTED);
346 }
347
348 xhci_polledp->xhci_polled_persistent_error = USB_SUCCESS;
349 xhci_polledp->xhci_polled_entry++;
350
351 ASSERT(!(xep->xep_state & XHCI_ENDPOINT_POLLED));
352 xep->xep_state |= XHCI_ENDPOINT_POLLED;
353
354 mutex_exit(&xhcip->xhci_lock);
355 return (USB_SUCCESS);
356 }
357
358 int
xhci_hcdi_console_read(usb_console_info_impl_t * console_input_info,uint_t * num_characters)359 xhci_hcdi_console_read(usb_console_info_impl_t *console_input_info,
360 uint_t *num_characters)
361 {
362 xhci_polled_t *xhci_polledp;
363 xhci_t *xhcip;
364 uint32_t status, iman;
365 int ret;
366
367 *num_characters = 0;
368
369 xhci_polledp = (xhci_polled_t *)console_input_info->uci_private;
370 VERIFY(xhci_polledp != NULL);
371
372 if (xhci_polledp->xhci_polled_persistent_error != USB_SUCCESS)
373 return (xhci_polledp->xhci_polled_persistent_error);
374
375 xhcip = xhci_polledp->xhci_polled_xhci;
376 if (mutex_tryenter(&xhcip->xhci_lock) == 0)
377 return (USB_BUSY);
378
379 /*
380 * Before we read the interrupt management register, check to see if we
381 * have a fatal bit set. As we cannot reset the host controller while
382 * the kernel debugger is running we give up.
383 */
384 status = xhci_get32(xhcip, XHCI_R_OPER, XHCI_USBSTS);
385 if ((status & (XHCI_STS_HSE | XHCI_STS_SRE | XHCI_STS_HCE)) != 0) {
386 xhci_polled_panic(xhci_polledp, "found fatal error bit in "
387 "status register, value: 0x%x", xhcip, status);
388 }
389
390 iman = xhci_get32(xhcip, XHCI_R_RUN, XHCI_IMAN(0));
391
392 ret = xhci_polled_event_process(xhci_polledp, num_characters);
393
394 if (ret == USB_SUCCESS)
395 xhci_put32(xhcip, XHCI_R_RUN, XHCI_IMAN(0), iman);
396
397 mutex_exit(&xhcip->xhci_lock);
398 return (ret);
399 }
400
401 int
xhci_hcdi_console_input_exit(usb_console_info_impl_t * console_input_info)402 xhci_hcdi_console_input_exit(usb_console_info_impl_t *console_input_info)
403 {
404 xhci_polled_t *xhci_polledp;
405 xhci_t *xhcip;
406 xhci_endpoint_t *xep;
407
408 xhci_polledp = (xhci_polled_t *)console_input_info->uci_private;
409 VERIFY(xhci_polledp != NULL);
410
411 xhcip = xhci_polledp->xhci_polled_xhci;
412 mutex_enter(&xhcip->xhci_lock);
413
414 xep = xhci_polledp->xhci_polled_endpoint;
415 ASSERT(xep->xep_state & XHCI_ENDPOINT_POLLED);
416
417 VERIFY(xhci_polledp->xhci_polled_entry > 0);
418 xhci_polledp->xhci_polled_entry--;
419 if (xhci_polledp->xhci_polled_entry > 0) {
420 mutex_exit(&xhcip->xhci_lock);
421 return (USB_SUCCESS);
422 }
423
424 xep->xep_state &= ~XHCI_ENDPOINT_POLLED;
425
426 /*
427 * Initiate a reset of the host controller if we encountered problems
428 * or ignored events while in polled mode. The reset will not be
429 * performed in this context and instead be scheduled to a
430 * task queue. It will therefore only happen once the kernel is
431 * fully up and running again which should be perfectly safe.
432 */
433 if (xhci_polledp->xhci_polled_persistent_error != USB_SUCCESS) {
434 xhci_fm_runtime_reset(xhcip);
435 }
436
437 mutex_exit(&xhcip->xhci_lock);
438 return (USB_SUCCESS);
439 }
440
441 int
xhci_hcdi_console_output_init(usba_pipe_handle_data_t * pipe_handle,usb_console_info_impl_t * console_output_info)442 xhci_hcdi_console_output_init(usba_pipe_handle_data_t *pipe_handle,
443 usb_console_info_impl_t *console_output_info)
444 {
445 return (USB_NOT_SUPPORTED);
446 }
447
448 int
xhci_hcdi_console_output_fini(usb_console_info_impl_t * console_output_info)449 xhci_hcdi_console_output_fini(usb_console_info_impl_t *console_output_info)
450 {
451 return (USB_NOT_SUPPORTED);
452 }
453
454 int
xhci_hcdi_console_output_enter(usb_console_info_impl_t * console_output_info)455 xhci_hcdi_console_output_enter(usb_console_info_impl_t *console_output_info)
456 {
457 return (USB_NOT_SUPPORTED);
458 }
459
460 int
xhci_hcdi_console_write(usb_console_info_impl_t * console_output_info,uchar_t * buf,uint_t num_characters,uint_t * num_characters_written)461 xhci_hcdi_console_write(usb_console_info_impl_t *console_output_info,
462 uchar_t *buf, uint_t num_characters, uint_t *num_characters_written)
463 {
464 return (USB_NOT_SUPPORTED);
465 }
466
467 int
xhci_hcdi_console_output_exit(usb_console_info_impl_t * console_output_info)468 xhci_hcdi_console_output_exit(usb_console_info_impl_t *console_output_info)
469 {
470 return (USB_NOT_SUPPORTED);
471 }
472