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 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 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 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 * 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 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 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 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 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 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 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 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 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 449 xhci_hcdi_console_output_fini(usb_console_info_impl_t *console_output_info) 450 { 451 return (USB_NOT_SUPPORTED); 452 } 453 454 int 455 xhci_hcdi_console_output_enter(usb_console_info_impl_t *console_output_info) 456 { 457 return (USB_NOT_SUPPORTED); 458 } 459 460 int 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 468 xhci_hcdi_console_output_exit(usb_console_info_impl_t *console_output_info) 469 { 470 return (USB_NOT_SUPPORTED); 471 } 472