1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Universal Host Controller Driver (UHCI) 30 * 31 * The UHCI driver is a driver which interfaces to the Universal 32 * Serial Bus Driver (USBA) and the Host Controller (HC). The interface to 33 * the Host Controller is defined by the UHCI. 34 * This file contains misc functions. 35 */ 36 #include <sys/usb/hcd/uhci/uhcid.h> 37 #include <sys/usb/hcd/uhci/uhciutil.h> 38 #include <sys/usb/hcd/uhci/uhcipolled.h> 39 40 #include <sys/disp.h> 41 42 /* Globals */ 43 extern uint_t uhci_td_pool_size; /* Num TDs */ 44 extern uint_t uhci_qh_pool_size; /* Num QHs */ 45 extern ushort_t uhci_tree_bottom_nodes[]; 46 extern void *uhci_statep; 47 48 /* function prototypes */ 49 static void uhci_build_interrupt_lattice(uhci_state_t *uhcip); 50 static int uhci_init_frame_lst_table(dev_info_t *dip, uhci_state_t *uhcip); 51 52 static uint_t uhci_lattice_height(uint_t bandwidth); 53 static uint_t uhci_lattice_parent(uint_t node); 54 static uint_t uhci_leftmost_leaf(uint_t node, uint_t height); 55 static uint_t uhci_compute_total_bandwidth(usb_ep_descr_t *endpoint, 56 usb_port_status_t port_status); 57 58 static int uhci_bandwidth_adjust(uhci_state_t *uhcip, 59 usb_ep_descr_t *endpoint, usb_port_status_t port_status); 60 61 static uhci_td_t *uhci_allocate_td_from_pool(uhci_state_t *uhcip); 62 static void uhci_fill_in_td(uhci_state_t *uhcip, 63 uhci_td_t *td, uhci_td_t *current_dummy, 64 uint32_t buffer_offset, size_t length, 65 uhci_pipe_private_t *pp, uchar_t PID, 66 usb_req_attrs_t attrs, uhci_trans_wrapper_t *tw); 67 static uint32_t uhci_get_tw_paddr_by_offs(uhci_state_t *uhcip, 68 uint32_t buffer_offset, size_t length, 69 uhci_trans_wrapper_t *tw); 70 static uhci_trans_wrapper_t *uhci_create_transfer_wrapper( 71 uhci_state_t *uhcip, uhci_pipe_private_t *pp, 72 size_t length, usb_flags_t usb_flags); 73 static uhci_trans_wrapper_t *uhci_create_isoc_transfer_wrapper( 74 uhci_state_t *uhcip, uhci_pipe_private_t *pp, 75 usb_isoc_req_t *req, size_t length, 76 usb_flags_t usb_flags); 77 78 static int uhci_create_setup_pkt(uhci_state_t *uhcip, 79 uhci_pipe_private_t *pp, uhci_trans_wrapper_t *tw); 80 static void uhci_insert_ctrl_qh(uhci_state_t *uhcip, 81 uhci_pipe_private_t *pp); 82 static void uhci_remove_ctrl_qh(uhci_state_t *uhcip, 83 uhci_pipe_private_t *pp); 84 static void uhci_insert_intr_qh(uhci_state_t *uhcip, 85 uhci_pipe_private_t *pp); 86 static void uhci_remove_intr_qh(uhci_state_t *uhcip, 87 uhci_pipe_private_t *pp); 88 static void uhci_remove_bulk_qh(uhci_state_t *uhcip, 89 uhci_pipe_private_t *pp); 90 static void uhci_insert_bulk_qh(uhci_state_t *uhcip, 91 uhci_pipe_private_t *pp); 92 static void uhci_handle_bulk_td_errors(uhci_state_t *uhcip, uhci_td_t *td); 93 static int uhci_alloc_memory_for_tds(uhci_state_t *uhcip, uint_t num_tds, 94 uhci_bulk_isoc_xfer_t *info); 95 static int uhci_alloc_bulk_isoc_tds(uhci_state_t *uhcip, uint_t num_tds, 96 uhci_bulk_isoc_xfer_t *info); 97 static void uhci_get_isoc_td_by_index(uhci_state_t *uhcip, 98 uhci_bulk_isoc_xfer_t *info, uint_t index, 99 uhci_td_t **tdpp, uhci_bulk_isoc_td_pool_t **td_pool_pp); 100 static void uhci_get_bulk_td_by_paddr(uhci_state_t *uhcip, 101 uhci_bulk_isoc_xfer_t *info, uint32_t paddr, 102 uhci_bulk_isoc_td_pool_t **td_pool_pp); 103 104 static int uhci_handle_isoc_receive(uhci_state_t *uhcip, 105 uhci_pipe_private_t *pp, uhci_trans_wrapper_t *tw); 106 static void uhci_delete_isoc_td(uhci_state_t *uhcip, 107 uhci_td_t *td); 108 #ifdef DEBUG 109 static void uhci_print_td(uhci_state_t *uhcip, uhci_td_t *td); 110 static void uhci_print_qh(uhci_state_t *uhcip, queue_head_t *qh); 111 #endif 112 113 114 /* 115 * uhci_build_interrupt_lattice: 116 * 117 * Construct the interrupt lattice tree using static Queue Head pointers. 118 * This interrupt lattice tree will have total of 63 queue heads and the 119 * Host Controller (HC) processes queue heads every frame. 120 */ 121 static void 122 uhci_build_interrupt_lattice(uhci_state_t *uhcip) 123 { 124 int half_list = NUM_INTR_QH_LISTS / 2; 125 uint16_t i, j, k; 126 uhci_td_t *sof_td, *isoc_td; 127 uintptr_t addr; 128 queue_head_t *list_array = uhcip->uhci_qh_pool_addr; 129 queue_head_t *tmp_qh; 130 frame_lst_table_t *frame_lst_tablep = 131 uhcip->uhci_frame_lst_tablep; 132 133 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 134 "uhci_build_interrupt_lattice:"); 135 136 /* 137 * Reserve the first 63 queue head structures in the pool as static 138 * queue heads & these are required for constructing interrupt 139 * lattice tree. 140 */ 141 for (i = 0; i < NUM_INTR_QH_LISTS; i++) { 142 SetQH32(uhcip, list_array[i].link_ptr, HC_END_OF_LIST); 143 SetQH32(uhcip, list_array[i].element_ptr, HC_END_OF_LIST); 144 list_array[i].qh_flag = QUEUE_HEAD_FLAG_STATIC; 145 list_array[i].node = i; 146 } 147 148 /* Build the interrupt lattice tree */ 149 for (i = 0; i < half_list - 1; i++) { 150 /* 151 * The next pointer in the host controller queue head 152 * descriptor must contain an iommu address. Calculate 153 * the offset into the cpu address and add this to the 154 * starting iommu address. 155 */ 156 addr = QH_PADDR(&list_array[i]) | HC_QUEUE_HEAD; 157 158 SetQH32(uhcip, list_array[2*i + 1].link_ptr, addr); 159 SetQH32(uhcip, list_array[2*i + 2].link_ptr, addr); 160 } 161 162 /* 163 * Initialize the interrupt list in the Frame list Table 164 * so that it points to the bottom of the tree. 165 */ 166 for (i = 0, j = 0; i < pow_2(TREE_HEIGHT); i++) { 167 addr = QH_PADDR(&list_array[half_list + i - 1]); 168 for (k = 0; k < pow_2(VIRTUAL_TREE_HEIGHT); k++) { 169 SetFL32(uhcip, 170 frame_lst_tablep[uhci_tree_bottom_nodes[j++]], 171 addr | HC_QUEUE_HEAD); 172 } 173 } 174 175 /* 176 * Create a controller and bulk Queue heads 177 */ 178 uhcip->uhci_ctrl_xfers_q_head = uhci_alloc_queue_head(uhcip); 179 tmp_qh = uhcip->uhci_ctrl_xfers_q_tail = uhcip->uhci_ctrl_xfers_q_head; 180 181 SetQH32(uhcip, list_array[0].link_ptr, 182 (QH_PADDR(tmp_qh) | HC_QUEUE_HEAD)); 183 184 uhcip->uhci_bulk_xfers_q_head = uhci_alloc_queue_head(uhcip); 185 uhcip->uhci_bulk_xfers_q_tail = uhcip->uhci_bulk_xfers_q_head; 186 SetQH32(uhcip, tmp_qh->link_ptr, 187 (QH_PADDR(uhcip->uhci_bulk_xfers_q_head)|HC_QUEUE_HEAD)); 188 189 SetQH32(uhcip, uhcip->uhci_bulk_xfers_q_head->link_ptr, HC_END_OF_LIST); 190 191 /* 192 * Add a dummy TD to the static queue head 0. THis is used 193 * to generate an at the end of frame. 194 */ 195 sof_td = uhci_allocate_td_from_pool(uhcip); 196 197 SetQH32(uhcip, list_array[0].element_ptr, 198 TD_PADDR(sof_td) | HC_TD_HEAD); 199 SetTD32(uhcip, sof_td->link_ptr, HC_END_OF_LIST); 200 uhcip->uhci_sof_td = sof_td; 201 202 /* 203 * Add a dummy td that is used to generate an interrupt for 204 * every 1024 frames. 205 */ 206 isoc_td = uhci_allocate_td_from_pool(uhcip); 207 SetTD32(uhcip, isoc_td->link_ptr, HC_END_OF_LIST); 208 uhcip->uhci_isoc_td = isoc_td; 209 210 uhcip->uhci_isoc_qh = uhci_alloc_queue_head(uhcip); 211 SetQH32(uhcip, uhcip->uhci_isoc_qh->link_ptr, 212 GetFL32(uhcip, uhcip->uhci_frame_lst_tablep[MAX_FRAME_NUM])); 213 SetQH32(uhcip, uhcip->uhci_isoc_qh->element_ptr, TD_PADDR(isoc_td)); 214 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[MAX_FRAME_NUM], 215 QH_PADDR(uhcip->uhci_isoc_qh) | HC_QUEUE_HEAD); 216 } 217 218 219 /* 220 * uhci_allocate_pools: 221 * Allocate the system memory for the Queue Heads Descriptor and 222 * for the Transfer Descriptor (TD) pools. Both QH and TD structures 223 * must be aligned to a 16 byte boundary. 224 */ 225 int 226 uhci_allocate_pools(uhci_state_t *uhcip) 227 { 228 dev_info_t *dip = uhcip->uhci_dip; 229 size_t real_length; 230 int i, result; 231 uint_t ccount; 232 ddi_device_acc_attr_t dev_attr; 233 234 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 235 "uhci_allocate_pools:"); 236 237 /* The host controller will be little endian */ 238 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 239 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 240 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 241 242 /* Allocate the TD pool DMA handle */ 243 if (ddi_dma_alloc_handle(dip, &uhcip->uhci_dma_attr, DDI_DMA_SLEEP, 0, 244 &uhcip->uhci_td_pool_dma_handle) != DDI_SUCCESS) { 245 246 return (USB_FAILURE); 247 } 248 249 /* Allocate the memory for the TD pool */ 250 if (ddi_dma_mem_alloc(uhcip->uhci_td_pool_dma_handle, 251 uhci_td_pool_size * sizeof (uhci_td_t), 252 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 0, 253 (caddr_t *)&uhcip->uhci_td_pool_addr, &real_length, 254 &uhcip->uhci_td_pool_mem_handle)) { 255 256 return (USB_FAILURE); 257 } 258 259 /* Map the TD pool into the I/O address space */ 260 result = ddi_dma_addr_bind_handle(uhcip->uhci_td_pool_dma_handle, 261 NULL, (caddr_t)uhcip->uhci_td_pool_addr, real_length, 262 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 263 NULL, &uhcip->uhci_td_pool_cookie, &ccount); 264 265 bzero((void *)uhcip->uhci_td_pool_addr, 266 uhci_td_pool_size * sizeof (uhci_td_t)); 267 268 /* Process the result */ 269 if (result == DDI_DMA_MAPPED) { 270 /* The cookie count should be 1 */ 271 if (ccount != 1) { 272 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 273 "uhci_allocate_pools: More than 1 cookie"); 274 275 return (USB_FAILURE); 276 } 277 } else { 278 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 279 "uhci_allocate_pools: Result = %d", result); 280 281 uhci_decode_ddi_dma_addr_bind_handle_result(uhcip, result); 282 283 return (USB_FAILURE); 284 } 285 286 uhcip->uhci_dma_addr_bind_flag |= UHCI_TD_POOL_BOUND; 287 288 /* Initialize the TD pool */ 289 for (i = 0; i < uhci_td_pool_size; i++) { 290 uhcip->uhci_td_pool_addr[i].flag = TD_FLAG_FREE; 291 } 292 293 /* Allocate the TD pool DMA handle */ 294 if (ddi_dma_alloc_handle(dip, &uhcip->uhci_dma_attr, DDI_DMA_SLEEP, 295 0, &uhcip->uhci_qh_pool_dma_handle) != DDI_SUCCESS) { 296 297 return (USB_FAILURE); 298 } 299 300 /* Allocate the memory for the QH pool */ 301 if (ddi_dma_mem_alloc(uhcip->uhci_qh_pool_dma_handle, 302 uhci_qh_pool_size * sizeof (queue_head_t), 303 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 0, 304 (caddr_t *)&uhcip->uhci_qh_pool_addr, &real_length, 305 &uhcip->uhci_qh_pool_mem_handle) != DDI_SUCCESS) { 306 307 return (USB_FAILURE); 308 } 309 310 result = ddi_dma_addr_bind_handle(uhcip->uhci_qh_pool_dma_handle, 311 NULL, (caddr_t)uhcip->uhci_qh_pool_addr, real_length, 312 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 313 &uhcip->uhci_qh_pool_cookie, &ccount); 314 315 /* Process the result */ 316 if (result == DDI_DMA_MAPPED) { 317 /* The cookie count should be 1 */ 318 if (ccount != 1) { 319 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 320 "uhci_allocate_pools: More than 1 cookie"); 321 322 return (USB_FAILURE); 323 } 324 } else { 325 uhci_decode_ddi_dma_addr_bind_handle_result(uhcip, result); 326 327 return (USB_FAILURE); 328 } 329 330 uhcip->uhci_dma_addr_bind_flag |= UHCI_QH_POOL_BOUND; 331 332 bzero((void *)uhcip->uhci_qh_pool_addr, 333 uhci_qh_pool_size * sizeof (queue_head_t)); 334 335 /* Initialize the QH pool */ 336 for (i = 0; i < uhci_qh_pool_size; i ++) { 337 uhcip->uhci_qh_pool_addr[i].qh_flag = QUEUE_HEAD_FLAG_FREE; 338 } 339 340 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 341 "uhci_allocate_pools: Completed"); 342 343 return (USB_SUCCESS); 344 } 345 346 347 /* 348 * uhci_free_pools: 349 * Cleanup on attach failure or detach 350 */ 351 void 352 uhci_free_pools(uhci_state_t *uhcip) 353 { 354 int i, flag, rval; 355 uhci_td_t *td; 356 uhci_trans_wrapper_t *tw; 357 358 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 359 "uhci_free_pools:"); 360 361 if (uhcip->uhci_td_pool_addr && uhcip->uhci_td_pool_mem_handle) { 362 for (i = 0; i < uhci_td_pool_size; i ++) { 363 td = &uhcip->uhci_td_pool_addr[i]; 364 365 flag = uhcip->uhci_td_pool_addr[i].flag; 366 if ((flag != TD_FLAG_FREE) && 367 (flag != TD_FLAG_DUMMY) && (td->tw != NULL)) { 368 tw = td->tw; 369 uhci_free_tw(uhcip, tw); 370 } 371 372 } 373 374 if (uhcip->uhci_dma_addr_bind_flag & UHCI_TD_POOL_BOUND) { 375 rval = ddi_dma_unbind_handle( 376 uhcip->uhci_td_pool_dma_handle); 377 ASSERT(rval == DDI_SUCCESS); 378 } 379 380 ddi_dma_mem_free(&uhcip->uhci_td_pool_mem_handle); 381 } 382 383 /* Free the TD pool */ 384 if (uhcip->uhci_td_pool_dma_handle) { 385 ddi_dma_free_handle(&uhcip->uhci_td_pool_dma_handle); 386 } 387 388 if (uhcip->uhci_qh_pool_addr && uhcip->uhci_qh_pool_mem_handle) { 389 if (uhcip->uhci_dma_addr_bind_flag & UHCI_QH_POOL_BOUND) { 390 rval = ddi_dma_unbind_handle( 391 uhcip->uhci_qh_pool_dma_handle); 392 ASSERT(rval == DDI_SUCCESS); 393 } 394 ddi_dma_mem_free(&uhcip->uhci_qh_pool_mem_handle); 395 } 396 397 /* Free the QH pool */ 398 if (uhcip->uhci_qh_pool_dma_handle) { 399 ddi_dma_free_handle(&uhcip->uhci_qh_pool_dma_handle); 400 } 401 402 /* Free the Frame list Table area */ 403 if (uhcip->uhci_frame_lst_tablep && uhcip->uhci_flt_mem_handle) { 404 if (uhcip->uhci_dma_addr_bind_flag & UHCI_FLA_POOL_BOUND) { 405 rval = ddi_dma_unbind_handle( 406 uhcip->uhci_flt_dma_handle); 407 ASSERT(rval == DDI_SUCCESS); 408 } 409 ddi_dma_mem_free(&uhcip->uhci_flt_mem_handle); 410 } 411 412 if (uhcip->uhci_flt_dma_handle) { 413 ddi_dma_free_handle(&uhcip->uhci_flt_dma_handle); 414 } 415 } 416 417 418 /* 419 * uhci_decode_ddi_dma_addr_bind_handle_result: 420 * Process the return values of ddi_dma_addr_bind_handle() 421 */ 422 void 423 uhci_decode_ddi_dma_addr_bind_handle_result(uhci_state_t *uhcip, int result) 424 { 425 char *msg; 426 427 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 428 "uhci_decode_ddi_dma_addr_bind_handle_result:"); 429 430 switch (result) { 431 case DDI_DMA_PARTIAL_MAP: 432 msg = "Partial transfers not allowed"; 433 break; 434 case DDI_DMA_INUSE: 435 msg = "Handle is in use"; 436 break; 437 case DDI_DMA_NORESOURCES: 438 msg = "No resources"; 439 break; 440 case DDI_DMA_NOMAPPING: 441 msg = "No mapping"; 442 break; 443 case DDI_DMA_TOOBIG: 444 msg = "Object is too big"; 445 break; 446 default: 447 msg = "Unknown dma error"; 448 } 449 450 USB_DPRINTF_L4(PRINT_MASK_ALL, uhcip->uhci_log_hdl, "%s", msg); 451 } 452 453 454 /* 455 * uhci_init_ctlr: 456 * Initialize the Host Controller (HC). 457 */ 458 int 459 uhci_init_ctlr(uhci_state_t *uhcip) 460 { 461 dev_info_t *dip = uhcip->uhci_dip; 462 uint_t cmd_reg; 463 uint_t frame_base_addr; 464 465 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_init_ctlr:"); 466 467 /* 468 * When USB legacy mode is enabled, the BIOS manages the USB keyboard 469 * attached to the UHCI controller. It has been observed that some 470 * times the BIOS does not clear the interrupts in the legacy mode 471 * register in the PCI configuration space. So, disable the SMI intrs 472 * and route the intrs to PIRQD here. 473 */ 474 pci_config_put16(uhcip->uhci_config_handle, 475 LEGACYMODE_REG_OFFSET, LEGACYMODE_REG_INIT_VALUE); 476 477 /* 478 * Disable all the interrupts. 479 */ 480 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 481 482 mutex_enter(&uhcip->uhci_int_mutex); 483 cmd_reg = Get_OpReg16(USBCMD); 484 cmd_reg &= (~USBCMD_REG_HC_RUN); 485 486 /* Stop the controller */ 487 Set_OpReg16(USBCMD, cmd_reg); 488 489 /* Reset the host controller */ 490 Set_OpReg16(USBCMD, USBCMD_REG_GBL_RESET); 491 492 /* Wait 10ms for reset to complete */ 493 mutex_exit(&uhcip->uhci_int_mutex); 494 delay(drv_usectohz(UHCI_RESET_DELAY)); 495 mutex_enter(&uhcip->uhci_int_mutex); 496 497 Set_OpReg16(USBCMD, 0); 498 499 /* Set the frame number to zero */ 500 Set_OpReg16(FRNUM, 0); 501 502 /* Initialize the Frame list base address area */ 503 if (uhci_init_frame_lst_table(dip, uhcip) != USB_SUCCESS) { 504 mutex_exit(&uhcip->uhci_int_mutex); 505 506 return (USB_FAILURE); 507 } 508 509 /* Save the contents of the Frame Interval Registers */ 510 uhcip->uhci_frame_interval = Get_OpReg8(SOFMOD); 511 512 frame_base_addr = uhcip->uhci_flt_cookie.dmac_address; 513 514 /* Set the Frame list base address */ 515 Set_OpReg32(FRBASEADD, frame_base_addr); 516 517 /* 518 * Begin sending SOFs 519 * Set the Host Controller Functional State to Operational 520 */ 521 cmd_reg = Get_OpReg16(USBCMD); 522 cmd_reg |= (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 523 USBCMD_REG_CONFIG_FLAG); 524 525 Set_OpReg16(USBCMD, cmd_reg); 526 mutex_exit(&uhcip->uhci_int_mutex); 527 528 /* 529 * Verify the Command and interrupt enable registers, 530 * a sanity check whether actually initialized or not 531 */ 532 cmd_reg = Get_OpReg16(USBCMD); 533 534 if (!(cmd_reg & (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 535 USBCMD_REG_CONFIG_FLAG))) { 536 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 537 "uhci_init_ctlr: Controller initialization failed"); 538 539 return (USB_FAILURE); 540 } 541 542 /* 543 * Set the ioc bit of the isoc intr td. This enables 544 * the generation of an interrupt for every 1024 frames. 545 */ 546 SetTD_ioc(uhcip, uhcip->uhci_isoc_td, 1); 547 548 /* Set the flag that uhci controller has been initialized. */ 549 uhcip->uhci_ctlr_init_flag = B_TRUE; 550 551 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 552 "uhci_init_ctlr: Completed"); 553 554 return (USB_SUCCESS); 555 } 556 557 558 /* 559 * uhci_uninit_ctlr: 560 * uninitialize the Host Controller (HC). 561 */ 562 void 563 uhci_uninit_ctlr(uhci_state_t *uhcip) 564 { 565 if (uhcip->uhci_regs_handle) { 566 /* Disable all the interrupts. */ 567 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 568 569 /* Complete the current transaction and then halt. */ 570 Set_OpReg16(USBCMD, 0); 571 572 /* Wait for sometime */ 573 mutex_exit(&uhcip->uhci_int_mutex); 574 delay(drv_usectohz(UHCI_TIMEWAIT)); 575 mutex_enter(&uhcip->uhci_int_mutex); 576 } 577 } 578 579 580 /* 581 * uhci_map_regs: 582 * The Host Controller (HC) contains a set of on-chip operational 583 * registers and which should be mapped into a non-cacheable 584 * portion of the system addressable space. 585 */ 586 int 587 uhci_map_regs(uhci_state_t *uhcip) 588 { 589 dev_info_t *dip = uhcip->uhci_dip; 590 int index; 591 uint32_t regs_prop_len; 592 int32_t *regs_list; 593 uint16_t command_reg; 594 ddi_device_acc_attr_t attr; 595 596 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, "uhci_map_regs:"); 597 598 /* The host controller will be little endian */ 599 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 600 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 601 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 602 603 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, uhcip->uhci_dip, 604 DDI_PROP_DONTPASS, "reg", ®s_list, ®s_prop_len) != 605 DDI_PROP_SUCCESS) { 606 607 return (USB_FAILURE); 608 } 609 610 for (index = 0; index * 5 < regs_prop_len; index++) { 611 if (regs_list[index * 5] & UHCI_PROP_MASK) { 612 break; 613 } 614 } 615 616 /* 617 * Deallocate the memory allocated by the ddi_prop_lookup_int_array 618 */ 619 ddi_prop_free(regs_list); 620 621 if (index * 5 >= regs_prop_len) { 622 623 return (USB_FAILURE); 624 } 625 626 /* Map in operational registers */ 627 if (ddi_regs_map_setup(dip, index, (caddr_t *)&uhcip->uhci_regsp, 628 0, sizeof (hc_regs_t), &attr, &uhcip->uhci_regs_handle) != 629 DDI_SUCCESS) { 630 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 631 "ddi_regs_map_setup: failed"); 632 633 return (USB_FAILURE); 634 } 635 636 if (pci_config_setup(dip, &uhcip->uhci_config_handle) != DDI_SUCCESS) { 637 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 638 "uhci_map_regs: Config error"); 639 640 return (USB_FAILURE); 641 } 642 643 /* Make sure Memory Access Enable and Master Enable are set */ 644 command_reg = pci_config_get16(uhcip->uhci_config_handle, 645 PCI_CONF_COMM); 646 if (!(command_reg & (PCI_COMM_MAE | PCI_COMM_ME))) { 647 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 648 "uhci_map_regs: No MAE/ME"); 649 } 650 651 command_reg |= PCI_COMM_MAE | PCI_COMM_ME; 652 pci_config_put16(uhcip->uhci_config_handle, PCI_CONF_COMM, command_reg); 653 654 /* 655 * Check whether I/O base address is configured and enabled. 656 */ 657 if (!(command_reg & PCI_COMM_IO)) { 658 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 659 "I/O Base address access disabled"); 660 661 return (USB_FAILURE); 662 } 663 /* 664 * Get the IO base address of the controller 665 */ 666 uhcip->uhci_iobase = (pci_config_get16(uhcip->uhci_config_handle, 667 PCI_CONF_IOBASE) & PCI_CONF_IOBASE_MASK); 668 669 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 670 "uhci_map_regs: Completed"); 671 672 return (USB_SUCCESS); 673 } 674 675 676 void 677 uhci_unmap_regs(uhci_state_t *uhcip) 678 { 679 /* Unmap the UHCI registers */ 680 if (uhcip->uhci_regs_handle) { 681 /* Reset the host controller */ 682 Set_OpReg16(USBCMD, USBCMD_REG_GBL_RESET); 683 684 ddi_regs_map_free(&uhcip->uhci_regs_handle); 685 } 686 687 if (uhcip->uhci_config_handle) { 688 pci_config_teardown(&uhcip->uhci_config_handle); 689 } 690 } 691 692 693 /* 694 * uhci_set_dma_attributes: 695 * Set the limits in the DMA attributes structure. Most of the values used 696 * in the DMA limit structres are the default values as specified by the 697 * Writing PCI device drivers document. 698 */ 699 void 700 uhci_set_dma_attributes(uhci_state_t *uhcip) 701 { 702 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 703 "uhci_set_dma_attributes:"); 704 705 /* Initialize the DMA attributes */ 706 uhcip->uhci_dma_attr.dma_attr_version = DMA_ATTR_V0; 707 uhcip->uhci_dma_attr.dma_attr_addr_lo = 0x00000000ull; 708 uhcip->uhci_dma_attr.dma_attr_addr_hi = 0xfffffff0ull; 709 710 /* 32 bit addressing */ 711 uhcip->uhci_dma_attr.dma_attr_count_max = 0xffffffull; 712 713 /* 714 * Setting the dam_att_align to 512, some times fails the 715 * binding handle. I dont know why ? But setting to 16 will 716 * be right for our case (16 byte alignment required per 717 * UHCI spec for TD descriptors). 718 */ 719 720 /* 16 byte alignment */ 721 uhcip->uhci_dma_attr.dma_attr_align = 0x10; 722 723 /* 724 * Since PCI specification is byte alignment, the 725 * burstsize field should be set to 1 for PCI devices. 726 */ 727 uhcip->uhci_dma_attr.dma_attr_burstsizes = 0x1; 728 729 uhcip->uhci_dma_attr.dma_attr_minxfer = 0x1; 730 uhcip->uhci_dma_attr.dma_attr_maxxfer = 0xffffffull; 731 uhcip->uhci_dma_attr.dma_attr_seg = 0xffffffffull; 732 uhcip->uhci_dma_attr.dma_attr_sgllen = 1; 733 uhcip->uhci_dma_attr.dma_attr_granular = 1; 734 uhcip->uhci_dma_attr.dma_attr_flags = 0; 735 } 736 737 738 uint_t 739 pow_2(uint_t x) 740 { 741 return ((x == 0) ? 1 : (1 << x)); 742 } 743 744 745 uint_t 746 log_2(uint_t x) 747 { 748 int ret_val = 0; 749 750 while (x != 1) { 751 ret_val++; 752 x = x >> 1; 753 } 754 755 return (ret_val); 756 } 757 758 759 /* 760 * uhci_obtain_state: 761 */ 762 uhci_state_t * 763 uhci_obtain_state(dev_info_t *dip) 764 { 765 int instance = ddi_get_instance(dip); 766 uhci_state_t *state = ddi_get_soft_state(uhci_statep, instance); 767 768 ASSERT(state != NULL); 769 770 return (state); 771 } 772 773 774 /* 775 * uhci_alloc_hcdi_ops: 776 * The HCDI interfaces or entry points are the software interfaces used by 777 * the Universal Serial Bus Driver (USBA) to access the services of the 778 * Host Controller Driver (HCD). During HCD initialization, inform USBA 779 * about all available HCDI interfaces or entry points. 780 */ 781 usba_hcdi_ops_t * 782 uhci_alloc_hcdi_ops(uhci_state_t *uhcip) 783 { 784 usba_hcdi_ops_t *hcdi_ops; 785 786 USB_DPRINTF_L4(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 787 "uhci_alloc_hcdi_ops:"); 788 789 hcdi_ops = usba_alloc_hcdi_ops(); 790 791 hcdi_ops->usba_hcdi_ops_version = HCDI_OPS_VERSION_1; 792 793 hcdi_ops->usba_hcdi_pipe_open = uhci_hcdi_pipe_open; 794 hcdi_ops->usba_hcdi_pipe_close = uhci_hcdi_pipe_close; 795 hcdi_ops->usba_hcdi_pipe_reset = uhci_hcdi_pipe_reset; 796 797 hcdi_ops->usba_hcdi_pipe_ctrl_xfer = uhci_hcdi_pipe_ctrl_xfer; 798 hcdi_ops->usba_hcdi_pipe_bulk_xfer = uhci_hcdi_pipe_bulk_xfer; 799 hcdi_ops->usba_hcdi_pipe_intr_xfer = uhci_hcdi_pipe_intr_xfer; 800 hcdi_ops->usba_hcdi_pipe_isoc_xfer = uhci_hcdi_pipe_isoc_xfer; 801 802 hcdi_ops->usba_hcdi_bulk_transfer_size = uhci_hcdi_bulk_transfer_size; 803 hcdi_ops->usba_hcdi_pipe_stop_intr_polling = 804 uhci_hcdi_pipe_stop_intr_polling; 805 hcdi_ops->usba_hcdi_pipe_stop_isoc_polling = 806 uhci_hcdi_pipe_stop_isoc_polling; 807 808 hcdi_ops->usba_hcdi_get_current_frame_number = 809 uhci_hcdi_get_current_frame_number; 810 hcdi_ops->usba_hcdi_get_max_isoc_pkts = uhci_hcdi_get_max_isoc_pkts; 811 812 hcdi_ops->usba_hcdi_console_input_init = uhci_hcdi_polled_input_init; 813 hcdi_ops->usba_hcdi_console_input_enter = uhci_hcdi_polled_input_enter; 814 hcdi_ops->usba_hcdi_console_read = uhci_hcdi_polled_read; 815 hcdi_ops->usba_hcdi_console_input_exit = uhci_hcdi_polled_input_exit; 816 hcdi_ops->usba_hcdi_console_input_fini = uhci_hcdi_polled_input_fini; 817 818 hcdi_ops->usba_hcdi_console_output_init = uhci_hcdi_polled_output_init; 819 hcdi_ops->usba_hcdi_console_output_enter = 820 uhci_hcdi_polled_output_enter; 821 hcdi_ops->usba_hcdi_console_write = uhci_hcdi_polled_write; 822 hcdi_ops->usba_hcdi_console_output_exit = uhci_hcdi_polled_output_exit; 823 hcdi_ops->usba_hcdi_console_output_fini = uhci_hcdi_polled_output_fini; 824 825 return (hcdi_ops); 826 } 827 828 829 /* 830 * uhci_init_frame_lst_table : 831 * Allocate the system memory and initialize Host Controller 832 * Frame list table area The starting of the Frame list Table 833 * area must be 4096 byte aligned. 834 */ 835 static int 836 uhci_init_frame_lst_table(dev_info_t *dip, uhci_state_t *uhcip) 837 { 838 int result; 839 uint_t ccount; 840 size_t real_length; 841 ddi_device_acc_attr_t dev_attr; 842 843 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 844 845 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 846 "uhci_init_frame_lst_table:"); 847 848 /* The host controller will be little endian */ 849 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 850 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 851 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 852 853 /* 4K alignment required */ 854 uhcip->uhci_dma_attr.dma_attr_align = 0x1000; 855 856 /* Create space for the HCCA block */ 857 if (ddi_dma_alloc_handle(dip, &uhcip->uhci_dma_attr, DDI_DMA_SLEEP, 858 0, &uhcip->uhci_flt_dma_handle) != DDI_SUCCESS) { 859 860 return (USB_FAILURE); 861 } 862 863 /* Reset to default 16 bytes */ 864 uhcip->uhci_dma_attr.dma_attr_align = 0x10; 865 866 if (ddi_dma_mem_alloc(uhcip->uhci_flt_dma_handle, 867 SIZE_OF_FRAME_LST_TABLE, &dev_attr, DDI_DMA_CONSISTENT, 868 DDI_DMA_SLEEP, 0, (caddr_t *)&uhcip->uhci_frame_lst_tablep, 869 &real_length, &uhcip->uhci_flt_mem_handle)) { 870 871 return (USB_FAILURE); 872 } 873 874 /* Map the whole Frame list base area into the I/O address space */ 875 result = ddi_dma_addr_bind_handle(uhcip->uhci_flt_dma_handle, 876 NULL, (caddr_t)uhcip->uhci_frame_lst_tablep, real_length, 877 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 878 &uhcip->uhci_flt_cookie, &ccount); 879 880 if (result == DDI_DMA_MAPPED) { 881 /* The cookie count should be 1 */ 882 if (ccount != 1) { 883 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 884 "uhci_init_frame_list_table: More than 1 cookie"); 885 886 return (USB_FAILURE); 887 } 888 } else { 889 uhci_decode_ddi_dma_addr_bind_handle_result(uhcip, result); 890 891 return (USB_FAILURE); 892 } 893 894 uhcip->uhci_dma_addr_bind_flag |= UHCI_FLA_POOL_BOUND; 895 896 bzero((void *)uhcip->uhci_frame_lst_tablep, real_length); 897 898 /* Initialize the interrupt lists */ 899 uhci_build_interrupt_lattice(uhcip); 900 901 return (USB_SUCCESS); 902 } 903 904 905 /* 906 * uhci_alloc_queue_head: 907 * Allocate a queue head 908 */ 909 queue_head_t * 910 uhci_alloc_queue_head(uhci_state_t *uhcip) 911 { 912 int index; 913 uhci_td_t *dummy_td; 914 queue_head_t *queue_head; 915 916 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 917 "uhci_alloc_queue_head"); 918 919 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 920 921 /* Allocate a dummy td first. */ 922 if ((dummy_td = uhci_allocate_td_from_pool(uhcip)) == NULL) { 923 924 USB_DPRINTF_L2(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 925 "uhci_alloc_queue_head: allocate td from pool failed"); 926 927 return (NULL); 928 } 929 930 /* 931 * The first 63 queue heads in the Queue Head (QH) 932 * buffer pool are reserved for building interrupt lattice 933 * tree. Search for a blank Queue head in the QH buffer pool. 934 */ 935 for (index = NUM_STATIC_NODES; index < uhci_qh_pool_size; index++) { 936 if (uhcip->uhci_qh_pool_addr[index].qh_flag == 937 QUEUE_HEAD_FLAG_FREE) { 938 break; 939 } 940 } 941 942 USB_DPRINTF_L3(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 943 "uhci_alloc_queue_head: Allocated %d", index); 944 945 if (index == uhci_qh_pool_size) { 946 USB_DPRINTF_L2(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 947 "uhci_alloc_queue_head: All QH exhausted"); 948 949 /* Free the dummy td allocated for this qh. */ 950 dummy_td->flag = TD_FLAG_FREE; 951 952 return (NULL); 953 } 954 955 queue_head = &uhcip->uhci_qh_pool_addr[index]; 956 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 957 "uhci_alloc_queue_head: Allocated address 0x%p", queue_head); 958 959 bzero((void *)queue_head, sizeof (queue_head_t)); 960 SetQH32(uhcip, queue_head->link_ptr, HC_END_OF_LIST); 961 SetQH32(uhcip, queue_head->element_ptr, HC_END_OF_LIST); 962 queue_head->prev_qh = NULL; 963 queue_head->qh_flag = QUEUE_HEAD_FLAG_BUSY; 964 965 bzero((char *)dummy_td, sizeof (uhci_td_t)); 966 queue_head->td_tailp = dummy_td; 967 SetQH32(uhcip, queue_head->element_ptr, TD_PADDR(dummy_td)); 968 969 return (queue_head); 970 } 971 972 973 /* 974 * uhci_allocate_bandwidth: 975 * Figure out whether or not this interval may be supported. Return 976 * the index into the lattice if it can be supported. Return 977 * allocation failure if it can not be supported. 978 */ 979 int 980 uhci_allocate_bandwidth( 981 uhci_state_t *uhcip, 982 usba_pipe_handle_data_t *pipe_handle, 983 uint_t *node) 984 { 985 int bandwidth; /* Requested bandwidth */ 986 uint_t min, min_index; 987 uint_t i; 988 uint_t height; /* Bandwidth's height in the tree */ 989 uint_t leftmost; 990 uint_t length; 991 uint32_t paddr; 992 queue_head_t *tmp_qh; 993 usb_ep_descr_t *endpoint = &pipe_handle->p_ep; 994 995 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 996 997 /* 998 * Calculate the length in bytes of a transaction on this 999 * periodic endpoint. 1000 */ 1001 mutex_enter(&pipe_handle->p_usba_device->usb_mutex); 1002 1003 length = uhci_compute_total_bandwidth(endpoint, 1004 pipe_handle->p_usba_device->usb_port_status); 1005 mutex_exit(&pipe_handle->p_usba_device->usb_mutex); 1006 1007 /* 1008 * If the length in bytes plus the allocated bandwidth exceeds 1009 * the maximum, return bandwidth allocation failure. 1010 */ 1011 if ((length + uhcip->uhci_bandwidth_intr_min + 1012 uhcip->uhci_bandwidth_isoch_sum) > (MAX_PERIODIC_BANDWIDTH)) { 1013 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1014 "uhci_allocate_bandwidth: " 1015 "Reached maximum bandwidth value and cannot allocate " 1016 "bandwidth for a given Interrupt/Isoch endpoint"); 1017 1018 return (USB_NO_BANDWIDTH); 1019 } 1020 1021 /* 1022 * ISOC xfers are not supported at this point type 1023 */ 1024 if (UHCI_XFER_TYPE(endpoint) == USB_EP_ATTR_ISOCH) { 1025 uhcip->uhci_bandwidth_isoch_sum += length; 1026 1027 return (USB_SUCCESS); 1028 } 1029 1030 /* 1031 * This is an interrupt endpoint. 1032 * Adjust bandwidth to be a power of 2 1033 */ 1034 mutex_enter(&pipe_handle->p_usba_device->usb_mutex); 1035 bandwidth = uhci_bandwidth_adjust(uhcip, endpoint, 1036 pipe_handle->p_usba_device->usb_port_status); 1037 mutex_exit(&pipe_handle->p_usba_device->usb_mutex); 1038 1039 /* 1040 * If this bandwidth can't be supported, 1041 * return allocation failure. 1042 */ 1043 if (bandwidth == USB_FAILURE) { 1044 1045 return (USB_FAILURE); 1046 } 1047 1048 USB_DPRINTF_L3(PRINT_MASK_BW, uhcip->uhci_log_hdl, 1049 "The new bandwidth is %d", bandwidth); 1050 1051 /* Find the leaf with the smallest allocated bandwidth */ 1052 min_index = 0; 1053 min = uhcip->uhci_bandwidth[0]; 1054 1055 for (i = 1; i < NUM_FRAME_LST_ENTRIES; i++) { 1056 if (uhcip->uhci_bandwidth[i] < min) { 1057 min_index = i; 1058 min = uhcip->uhci_bandwidth[i]; 1059 } 1060 } 1061 1062 USB_DPRINTF_L3(PRINT_MASK_BW, uhcip->uhci_log_hdl, 1063 "The leaf with minimal bandwidth %d, " 1064 "The smallest bandwidth %d", min_index, min); 1065 1066 /* 1067 * Find the index into the lattice given the 1068 * leaf with the smallest allocated bandwidth. 1069 */ 1070 height = uhci_lattice_height(bandwidth); 1071 USB_DPRINTF_L3(PRINT_MASK_BW, uhcip->uhci_log_hdl, 1072 "The height is %d", height); 1073 1074 *node = uhci_tree_bottom_nodes[min_index]; 1075 1076 /* check if there are isocs TDs scheduled for this frame */ 1077 if (uhcip->uhci_isoc_q_tailp[*node]) { 1078 paddr = (uhcip->uhci_isoc_q_tailp[*node]->link_ptr & 1079 FRAME_LST_PTR_MASK); 1080 } else { 1081 paddr = (uhcip->uhci_frame_lst_tablep[*node] & 1082 FRAME_LST_PTR_MASK); 1083 } 1084 1085 tmp_qh = QH_VADDR(paddr); 1086 *node = tmp_qh->node; 1087 for (i = 0; i < height; i++) { 1088 *node = uhci_lattice_parent(*node); 1089 } 1090 1091 USB_DPRINTF_L3(PRINT_MASK_BW, uhcip->uhci_log_hdl, 1092 "The real node is %d", *node); 1093 1094 /* 1095 * Find the leftmost leaf in the subtree specified by the node. 1096 */ 1097 leftmost = uhci_leftmost_leaf(*node, height); 1098 USB_DPRINTF_L3(PRINT_MASK_BW, uhcip->uhci_log_hdl, 1099 "Leftmost %d", leftmost); 1100 1101 for (i = leftmost; i < leftmost + 1102 (NUM_FRAME_LST_ENTRIES/bandwidth); i ++) { 1103 1104 if ((length + uhcip->uhci_bandwidth_isoch_sum + 1105 uhcip->uhci_bandwidth[i]) > MAX_PERIODIC_BANDWIDTH) { 1106 1107 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1108 "uhci_allocate_bandwidth: " 1109 "Reached maximum bandwidth value and cannot " 1110 "allocate bandwidth for Interrupt endpoint"); 1111 1112 return (USB_NO_BANDWIDTH); 1113 } 1114 } 1115 1116 /* 1117 * All the leaves for this node must be updated with the bandwidth. 1118 */ 1119 for (i = leftmost; i < leftmost + 1120 (NUM_FRAME_LST_ENTRIES/bandwidth); i ++) { 1121 uhcip->uhci_bandwidth[i] += length; 1122 } 1123 1124 /* Find the leaf with the smallest allocated bandwidth */ 1125 min_index = 0; 1126 min = uhcip->uhci_bandwidth[0]; 1127 1128 for (i = 1; i < NUM_FRAME_LST_ENTRIES; i++) { 1129 if (uhcip->uhci_bandwidth[i] < min) { 1130 min_index = i; 1131 min = uhcip->uhci_bandwidth[i]; 1132 } 1133 } 1134 1135 /* Save the minimum for later use */ 1136 uhcip->uhci_bandwidth_intr_min = min; 1137 1138 return (USB_SUCCESS); 1139 } 1140 1141 1142 /* 1143 * uhci_deallocate_bandwidth: 1144 * Deallocate bandwidth for the given node in the lattice 1145 * and the length of transfer. 1146 */ 1147 void 1148 uhci_deallocate_bandwidth(uhci_state_t *uhcip, 1149 usba_pipe_handle_data_t *pipe_handle) 1150 { 1151 uint_t bandwidth; 1152 uint_t height; 1153 uint_t leftmost; 1154 uint_t i; 1155 uint_t min; 1156 usb_ep_descr_t *endpoint = &pipe_handle->p_ep; 1157 uint_t node, length; 1158 uhci_pipe_private_t *pp = 1159 (uhci_pipe_private_t *)pipe_handle->p_hcd_private; 1160 1161 /* This routine is protected by the uhci_int_mutex */ 1162 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1163 1164 /* Obtain the length */ 1165 mutex_enter(&pipe_handle->p_usba_device->usb_mutex); 1166 length = uhci_compute_total_bandwidth(endpoint, 1167 pipe_handle->p_usba_device->usb_port_status); 1168 mutex_exit(&pipe_handle->p_usba_device->usb_mutex); 1169 1170 /* 1171 * If this is an isochronous endpoint, just delete endpoint's 1172 * bandwidth from the total allocated isochronous bandwidth. 1173 */ 1174 if (UHCI_XFER_TYPE(endpoint) == USB_EP_ATTR_ISOCH) { 1175 uhcip->uhci_bandwidth_isoch_sum -= length; 1176 1177 return; 1178 } 1179 1180 /* Obtain the node */ 1181 node = pp->pp_node; 1182 1183 /* Adjust bandwidth to be a power of 2 */ 1184 mutex_enter(&pipe_handle->p_usba_device->usb_mutex); 1185 bandwidth = uhci_bandwidth_adjust(uhcip, endpoint, 1186 pipe_handle->p_usba_device->usb_port_status); 1187 mutex_exit(&pipe_handle->p_usba_device->usb_mutex); 1188 1189 /* Find the height in the tree */ 1190 height = uhci_lattice_height(bandwidth); 1191 1192 /* 1193 * Find the leftmost leaf in the subtree specified by the node 1194 */ 1195 leftmost = uhci_leftmost_leaf(node, height); 1196 1197 /* Delete the bandwith from the appropriate lists */ 1198 for (i = leftmost; i < leftmost + (NUM_FRAME_LST_ENTRIES/bandwidth); 1199 i ++) { 1200 uhcip->uhci_bandwidth[i] -= length; 1201 } 1202 1203 min = uhcip->uhci_bandwidth[0]; 1204 1205 /* Recompute the minimum */ 1206 for (i = 1; i < NUM_FRAME_LST_ENTRIES; i++) { 1207 if (uhcip->uhci_bandwidth[i] < min) { 1208 min = uhcip->uhci_bandwidth[i]; 1209 } 1210 } 1211 1212 /* Save the minimum for later use */ 1213 uhcip->uhci_bandwidth_intr_min = min; 1214 } 1215 1216 1217 /* 1218 * uhci_compute_total_bandwidth: 1219 * 1220 * Given a periodic endpoint (interrupt or isochronous) determine the total 1221 * bandwidth for one transaction. The UHCI host controller traverses the 1222 * endpoint descriptor lists on a first-come-first-serve basis. When the HC 1223 * services an endpoint, only a single transaction attempt is made. The HC 1224 * moves to the next Endpoint Descriptor after the first transaction attempt 1225 * rather than finishing the entire Transfer Descriptor. Therefore, when a 1226 * Transfer Descriptor is inserted into the lattice, we will only count the 1227 * number of bytes for one transaction. 1228 * 1229 * The following are the formulas used for calculating bandwidth in terms 1230 * bytes and it is for the single USB full speed and low speed transaction 1231 * respectively. The protocol overheads will be different for each of type 1232 * of USB transfer and all these formulas & protocol overheads are derived 1233 * from the 5.9.3 section of USB Specification & with the help of Bandwidth 1234 * Analysis white paper which is posted on the USB developer forum. 1235 * 1236 * Full-Speed: 1237 * Protocol overhead + ((MaxPacketSize * 7)/6 ) + Host_Delay 1238 * 1239 * Low-Speed: 1240 * Protocol overhead + Hub LS overhead + 1241 * (Low-Speed clock * ((MaxPacketSize * 7)/6 )) + Host_Delay 1242 */ 1243 static uint_t 1244 uhci_compute_total_bandwidth(usb_ep_descr_t *endpoint, 1245 usb_port_status_t port_status) 1246 { 1247 uint_t bandwidth; 1248 ushort_t MaxPacketSize = endpoint->wMaxPacketSize; 1249 1250 /* Add Host Controller specific delay to required bandwidth */ 1251 bandwidth = HOST_CONTROLLER_DELAY; 1252 1253 /* Add bit-stuffing overhead */ 1254 MaxPacketSize = (ushort_t)((MaxPacketSize * 7) / 6); 1255 1256 /* Low Speed interrupt transaction */ 1257 if (port_status == USBA_LOW_SPEED_DEV) { 1258 /* Low Speed interrupt transaction */ 1259 bandwidth += (LOW_SPEED_PROTO_OVERHEAD + 1260 HUB_LOW_SPEED_PROTO_OVERHEAD + 1261 (LOW_SPEED_CLOCK * MaxPacketSize)); 1262 } else { 1263 /* Full Speed transaction */ 1264 bandwidth += MaxPacketSize; 1265 1266 if (UHCI_XFER_TYPE(endpoint) == USB_EP_ATTR_INTR) { 1267 /* Full Speed interrupt transaction */ 1268 bandwidth += FS_NON_ISOC_PROTO_OVERHEAD; 1269 } else { 1270 /* Isochronus and input transaction */ 1271 if (UHCI_XFER_DIR(endpoint) == USB_EP_DIR_IN) { 1272 bandwidth += FS_ISOC_INPUT_PROTO_OVERHEAD; 1273 } else { 1274 /* Isochronus and output transaction */ 1275 bandwidth += FS_ISOC_OUTPUT_PROTO_OVERHEAD; 1276 } 1277 } 1278 } 1279 1280 return (bandwidth); 1281 } 1282 1283 1284 /* 1285 * uhci_bandwidth_adjust: 1286 */ 1287 static int 1288 uhci_bandwidth_adjust( 1289 uhci_state_t *uhcip, 1290 usb_ep_descr_t *endpoint, 1291 usb_port_status_t port_status) 1292 { 1293 int i = 0; 1294 uint_t interval; 1295 1296 /* 1297 * Get the polling interval from the endpoint descriptor 1298 */ 1299 interval = endpoint->bInterval; 1300 1301 /* 1302 * The bInterval value in the endpoint descriptor can range 1303 * from 1 to 255ms. The interrupt lattice has 32 leaf nodes, 1304 * and the host controller cycles through these nodes every 1305 * 32ms. The longest polling interval that the controller 1306 * supports is 32ms. 1307 */ 1308 1309 /* 1310 * Return an error if the polling interval is less than 1ms 1311 * and greater than 255ms 1312 */ 1313 if ((interval < MIN_POLL_INTERVAL) || (interval > MAX_POLL_INTERVAL)) { 1314 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1315 "uhci_bandwidth_adjust: Endpoint's poll interval must be " 1316 "between %d and %d ms", MIN_POLL_INTERVAL, 1317 MAX_POLL_INTERVAL); 1318 1319 return (USB_FAILURE); 1320 } 1321 1322 /* 1323 * According USB Specifications, a full-speed endpoint can 1324 * specify a desired polling interval 1ms to 255ms and a low 1325 * speed endpoints are limited to specifying only 10ms to 1326 * 255ms. But some old keyboards & mice uses polling interval 1327 * of 8ms. For compatibility purpose, we are using polling 1328 * interval between 8ms & 255ms for low speed endpoints. 1329 */ 1330 if ((port_status == USBA_LOW_SPEED_DEV) && 1331 (interval < MIN_LOW_SPEED_POLL_INTERVAL)) { 1332 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1333 "uhci_bandwidth_adjust: Low speed endpoint's poll interval " 1334 "must be >= %d ms, adjusted", 1335 MIN_LOW_SPEED_POLL_INTERVAL); 1336 1337 interval = MIN_LOW_SPEED_POLL_INTERVAL; 1338 } 1339 1340 /* 1341 * If polling interval is greater than 32ms, 1342 * adjust polling interval equal to 32ms. 1343 */ 1344 if (interval > 32) { 1345 interval = 32; 1346 } 1347 1348 /* 1349 * Find the nearest power of 2 that's less 1350 * than interval. 1351 */ 1352 while ((pow_2(i)) <= interval) { 1353 i++; 1354 } 1355 1356 return (pow_2((i - 1))); 1357 } 1358 1359 1360 /* 1361 * uhci_lattice_height: 1362 * Given the requested bandwidth, find the height in the tree at 1363 * which the nodes for this bandwidth fall. The height is measured 1364 * as the number of nodes from the leaf to the level specified by 1365 * bandwidth The root of the tree is at height TREE_HEIGHT. 1366 */ 1367 static uint_t 1368 uhci_lattice_height(uint_t bandwidth) 1369 { 1370 return (TREE_HEIGHT - (log_2(bandwidth))); 1371 } 1372 1373 1374 static uint_t 1375 uhci_lattice_parent(uint_t node) 1376 { 1377 return (((node % 2) == 0) ? ((node/2) - 1) : (node/2)); 1378 } 1379 1380 1381 /* 1382 * uhci_leftmost_leaf: 1383 * Find the leftmost leaf in the subtree specified by the node. 1384 * Height refers to number of nodes from the bottom of the tree 1385 * to the node, including the node. 1386 */ 1387 static uint_t 1388 uhci_leftmost_leaf(uint_t node, uint_t height) 1389 { 1390 node = pow_2(height + VIRTUAL_TREE_HEIGHT) * (node+1) - 1391 NUM_FRAME_LST_ENTRIES; 1392 return (node); 1393 } 1394 1395 1396 /* 1397 * uhci_insert_qh: 1398 * Add the Queue Head (QH) into the Host Controller's (HC) 1399 * appropriate queue head list. 1400 */ 1401 void 1402 uhci_insert_qh(uhci_state_t *uhcip, usba_pipe_handle_data_t *ph) 1403 { 1404 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 1405 1406 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1407 "uhci_insert_qh:"); 1408 1409 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1410 1411 switch (UHCI_XFER_TYPE(&ph->p_ep)) { 1412 case USB_EP_ATTR_CONTROL: 1413 uhci_insert_ctrl_qh(uhcip, pp); 1414 break; 1415 case USB_EP_ATTR_BULK: 1416 uhci_insert_bulk_qh(uhcip, pp); 1417 break; 1418 case USB_EP_ATTR_INTR: 1419 uhci_insert_intr_qh(uhcip, pp); 1420 break; 1421 case USB_EP_ATTR_ISOCH: 1422 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 1423 "uhci_insert_qh: Illegal request"); 1424 break; 1425 } 1426 } 1427 1428 1429 /* 1430 * uhci_insert_ctrl_qh: 1431 * Insert a control QH into the Host Controller's (HC) control QH list. 1432 */ 1433 static void 1434 uhci_insert_ctrl_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 1435 { 1436 queue_head_t *qh = pp->pp_qh; 1437 1438 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1439 "uhci_insert_ctrl_qh:"); 1440 1441 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1442 1443 if (uhcip->uhci_ctrl_xfers_q_head == uhcip->uhci_ctrl_xfers_q_tail) { 1444 uhcip->uhci_ctrl_xfers_q_head->prev_qh = UHCI_INVALID_PTR; 1445 } 1446 1447 SetQH32(uhcip, qh->link_ptr, 1448 GetQH32(uhcip, uhcip->uhci_ctrl_xfers_q_tail->link_ptr)); 1449 qh->prev_qh = uhcip->uhci_ctrl_xfers_q_tail; 1450 SetQH32(uhcip, uhcip->uhci_ctrl_xfers_q_tail->link_ptr, 1451 QH_PADDR(qh) | HC_QUEUE_HEAD); 1452 uhcip->uhci_ctrl_xfers_q_tail = qh; 1453 1454 } 1455 1456 1457 /* 1458 * uhci_insert_bulk_qh: 1459 * Insert a bulk QH into the Host Controller's (HC) bulk QH list. 1460 */ 1461 static void 1462 uhci_insert_bulk_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 1463 { 1464 queue_head_t *qh = pp->pp_qh; 1465 1466 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1467 "uhci_insert_bulk_qh:"); 1468 1469 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1470 1471 if (uhcip->uhci_bulk_xfers_q_head == uhcip->uhci_bulk_xfers_q_tail) { 1472 uhcip->uhci_bulk_xfers_q_head->prev_qh = UHCI_INVALID_PTR; 1473 } else if (uhcip->uhci_bulk_xfers_q_head->link_ptr == 1474 uhcip->uhci_bulk_xfers_q_tail->link_ptr) { 1475 1476 /* If there is already a loop, we should keep the loop. */ 1477 qh->link_ptr = uhcip->uhci_bulk_xfers_q_tail->link_ptr; 1478 } 1479 1480 qh->prev_qh = uhcip->uhci_bulk_xfers_q_tail; 1481 SetQH32(uhcip, uhcip->uhci_bulk_xfers_q_tail->link_ptr, 1482 QH_PADDR(qh) | HC_QUEUE_HEAD); 1483 uhcip->uhci_bulk_xfers_q_tail = qh; 1484 } 1485 1486 1487 /* 1488 * uhci_insert_intr_qh: 1489 * Insert a periodic Queue head i.e Interrupt queue head into the 1490 * Host Controller's (HC) interrupt lattice tree. 1491 */ 1492 static void 1493 uhci_insert_intr_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 1494 { 1495 uint_t node = pp->pp_node; /* The appropriate node was */ 1496 /* found during the opening */ 1497 /* of the pipe. */ 1498 queue_head_t *qh = pp->pp_qh; 1499 queue_head_t *next_lattice_qh, *lattice_qh; 1500 1501 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1502 "uhci_insert_intr_qh:"); 1503 1504 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1505 1506 /* Find the lattice queue head */ 1507 lattice_qh = &uhcip->uhci_qh_pool_addr[node]; 1508 next_lattice_qh = 1509 QH_VADDR(GetQH32(uhcip, lattice_qh->link_ptr) & QH_LINK_PTR_MASK); 1510 1511 next_lattice_qh->prev_qh = qh; 1512 qh->link_ptr = lattice_qh->link_ptr; 1513 qh->prev_qh = lattice_qh; 1514 SetQH32(uhcip, lattice_qh->link_ptr, QH_PADDR(qh) | HC_QUEUE_HEAD); 1515 pp->pp_data_toggle = 0; 1516 } 1517 1518 1519 /* 1520 * uhci_insert_intr_td: 1521 * Create a TD and a data buffer for an interrupt endpoint. 1522 */ 1523 int 1524 uhci_insert_intr_td( 1525 uhci_state_t *uhcip, 1526 usba_pipe_handle_data_t *ph, 1527 usb_intr_req_t *req, 1528 usb_flags_t flags) 1529 { 1530 int error, pipe_dir; 1531 uint_t length, mps; 1532 uint32_t buf_offs; 1533 uhci_td_t *tmp_td; 1534 usb_intr_req_t *intr_reqp; 1535 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 1536 uhci_trans_wrapper_t *tw; 1537 1538 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1539 "uhci_insert_intr_td: req: 0x%p", req); 1540 1541 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1542 1543 /* Get the interrupt pipe direction */ 1544 pipe_dir = UHCI_XFER_DIR(&ph->p_ep); 1545 1546 /* Get the current interrupt request pointer */ 1547 if (req) { 1548 length = req->intr_len; 1549 } else { 1550 ASSERT(pipe_dir == USB_EP_DIR_IN); 1551 length = (pp->pp_client_periodic_in_reqp) ? 1552 (((usb_intr_req_t *)pp-> 1553 pp_client_periodic_in_reqp)->intr_len) : 1554 ph->p_ep.wMaxPacketSize; 1555 } 1556 1557 /* Check the size of interrupt request */ 1558 if (length > UHCI_MAX_TD_XFER_SIZE) { 1559 1560 /* the length shouldn't exceed 8K */ 1561 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1562 "uhci_insert_intr_td: Intr request size 0x%lx is " 1563 "more than 0x%x", length, UHCI_MAX_TD_XFER_SIZE); 1564 1565 return (USB_INVALID_REQUEST); 1566 } 1567 1568 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1569 "uhci_insert_intr_td: length: 0x%lx", length); 1570 1571 /* Allocate a transaction wrapper */ 1572 if ((tw = uhci_create_transfer_wrapper(uhcip, pp, length, flags)) == 1573 NULL) { 1574 1575 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1576 "uhci_insert_intr_td: TW allocation failed"); 1577 1578 return (USB_NO_RESOURCES); 1579 } 1580 1581 /* 1582 * Initialize the callback and any callback 1583 * data for when the td completes. 1584 */ 1585 tw->tw_handle_td = uhci_handle_intr_td; 1586 tw->tw_handle_callback_value = NULL; 1587 tw->tw_direction = (pipe_dir == USB_EP_DIR_OUT) ? 1588 PID_OUT : PID_IN; 1589 tw->tw_curr_xfer_reqp = (usb_opaque_t)req; 1590 1591 /* 1592 * If it is an Interrupt IN request and interrupt request is NULL, 1593 * allocate the usb interrupt request structure for the current 1594 * interrupt polling request. 1595 */ 1596 if (tw->tw_direction == PID_IN) { 1597 if ((error = uhci_allocate_periodic_in_resource(uhcip, 1598 pp, tw, flags)) != USB_SUCCESS) { 1599 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1600 "uhci_insert_intr_td: Interrupt request structure " 1601 "allocation failed"); 1602 1603 /* free the transfer wrapper */ 1604 uhci_deallocate_tw(uhcip, pp, tw); 1605 1606 return (error); 1607 } 1608 } 1609 1610 intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp; 1611 ASSERT(tw->tw_curr_xfer_reqp != NULL); 1612 1613 tw->tw_timeout_cnt = (intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER) ? 1614 intr_reqp->intr_timeout : 0; 1615 1616 /* DATA IN */ 1617 if (tw->tw_direction == PID_IN) { 1618 /* Insert the td onto the queue head */ 1619 error = uhci_insert_hc_td(uhcip, 0, 1620 length, pp, tw, PID_IN, intr_reqp->intr_attributes); 1621 1622 if (error != USB_SUCCESS) { 1623 1624 uhci_deallocate_periodic_in_resource(uhcip, pp, tw); 1625 /* free the transfer wrapper */ 1626 uhci_deallocate_tw(uhcip, pp, tw); 1627 1628 return (USB_NO_RESOURCES); 1629 } 1630 tw->tw_bytes_xfered = 0; 1631 1632 return (USB_SUCCESS); 1633 } 1634 1635 if (req->intr_len) { 1636 /* DATA OUT */ 1637 ASSERT(req->intr_data != NULL); 1638 1639 /* Copy the data into the message */ 1640 ddi_rep_put8(tw->tw_accesshandle, req->intr_data->b_rptr, 1641 (uint8_t *)tw->tw_buf, req->intr_len, DDI_DEV_AUTOINCR); 1642 } 1643 1644 /* set tw->tw_claim flag, so that nobody else works on this tw. */ 1645 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 1646 1647 mps = ph->p_ep.wMaxPacketSize; 1648 buf_offs = 0; 1649 1650 /* Insert tds onto the queue head */ 1651 while (length > 0) { 1652 1653 error = uhci_insert_hc_td(uhcip, buf_offs, 1654 (length > mps) ? mps : length, 1655 pp, tw, PID_OUT, 1656 intr_reqp->intr_attributes); 1657 1658 if (error != USB_SUCCESS) { 1659 /* no resource. */ 1660 break; 1661 } 1662 1663 if (length <= mps) { 1664 /* inserted all data. */ 1665 length = 0; 1666 1667 } else { 1668 1669 buf_offs += mps; 1670 length -= mps; 1671 } 1672 } 1673 1674 if (error != USB_SUCCESS) { 1675 1676 USB_DPRINTF_L2(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 1677 "uhci_insert_intr_td: allocate td failed, free resource"); 1678 1679 /* remove all the tds */ 1680 while (tw->tw_hctd_head != NULL) { 1681 uhci_delete_td(uhcip, tw->tw_hctd_head); 1682 } 1683 1684 tw->tw_claim = UHCI_NOT_CLAIMED; 1685 uhci_deallocate_tw(uhcip, pp, tw); 1686 1687 return (error); 1688 } 1689 1690 /* allow HC to xfer the tds of this tw */ 1691 tmp_td = tw->tw_hctd_head; 1692 while (tmp_td != NULL) { 1693 1694 SetTD_status(uhcip, tmp_td, UHCI_TD_ACTIVE); 1695 tmp_td = tmp_td->tw_td_next; 1696 } 1697 1698 tw->tw_bytes_xfered = 0; 1699 tw->tw_claim = UHCI_NOT_CLAIMED; 1700 1701 return (error); 1702 } 1703 1704 1705 /* 1706 * uhci_create_transfer_wrapper: 1707 * Create a Transaction Wrapper (TW) for non-isoc transfer types. 1708 * This involves the allocating of DMA resources. 1709 * 1710 * For non-isoc transfers, one DMA handle and one DMA buffer are 1711 * allocated per transfer. The DMA buffer may contain multiple 1712 * DMA cookies and the cookies should meet certain alignment 1713 * requirement to be able to fit in the multiple TDs. The alignment 1714 * needs to ensure: 1715 * 1. the size of a cookie be larger than max TD length (0x500) 1716 * 2. the size of a cookie be a multiple of wMaxPacketSize of the 1717 * ctrl/bulk pipes 1718 * 1719 * wMaxPacketSize for ctrl and bulk pipes may be 8, 16, 32 or 64 bytes. 1720 * So the alignment should be a multiple of 64. wMaxPacketSize for intr 1721 * pipes is a little different since it only specifies the max to be 1722 * 64 bytes, but as long as an intr transfer is limited to max TD length, 1723 * any alignment can work if the cookie size is larger than max TD length. 1724 * 1725 * Considering the above conditions, 2K alignment is used. 4K alignment 1726 * should also be fine. 1727 */ 1728 static uhci_trans_wrapper_t * 1729 uhci_create_transfer_wrapper( 1730 uhci_state_t *uhcip, 1731 uhci_pipe_private_t *pp, 1732 size_t length, 1733 usb_flags_t usb_flags) 1734 { 1735 size_t real_length; 1736 uhci_trans_wrapper_t *tw; 1737 ddi_device_acc_attr_t dev_attr; 1738 ddi_dma_attr_t dma_attr; 1739 int kmem_flag; 1740 int (*dmamem_wait)(caddr_t); 1741 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1742 1743 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1744 "uhci_create_transfer_wrapper: length = 0x%lx flags = 0x%x", 1745 length, usb_flags); 1746 1747 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1748 1749 /* isochronous pipe should not call into this function */ 1750 if (UHCI_XFER_TYPE(&ph->p_ep) == USB_EP_ATTR_ISOCH) { 1751 1752 return (NULL); 1753 } 1754 1755 /* SLEEP flag should not be used in interrupt context */ 1756 if (servicing_interrupt()) { 1757 kmem_flag = KM_NOSLEEP; 1758 dmamem_wait = DDI_DMA_DONTWAIT; 1759 } else { 1760 kmem_flag = KM_SLEEP; 1761 dmamem_wait = DDI_DMA_SLEEP; 1762 } 1763 1764 /* Allocate space for the transfer wrapper */ 1765 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), kmem_flag)) == 1766 NULL) { 1767 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1768 "uhci_create_transfer_wrapper: kmem_alloc failed"); 1769 1770 return (NULL); 1771 } 1772 1773 /* zero-length packet doesn't need to allocate dma memory */ 1774 if (length == 0) { 1775 1776 goto dmadone; 1777 } 1778 1779 /* allow sg lists for transfer wrapper dma memory */ 1780 bcopy(&uhcip->uhci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 1781 dma_attr.dma_attr_sgllen = UHCI_DMA_ATTR_SGLLEN; 1782 dma_attr.dma_attr_align = UHCI_DMA_ATTR_ALIGN; 1783 1784 /* Store the transfer length */ 1785 tw->tw_length = length; 1786 1787 /* Allocate the DMA handle */ 1788 if (ddi_dma_alloc_handle(uhcip->uhci_dip, &dma_attr, dmamem_wait, 1789 0, &tw->tw_dmahandle) != DDI_SUCCESS) { 1790 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1791 "uhci_create_transfer_wrapper: Alloc handle failed"); 1792 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 1793 1794 return (NULL); 1795 } 1796 1797 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1798 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 1799 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1800 1801 /* Allocate the memory */ 1802 if (ddi_dma_mem_alloc(tw->tw_dmahandle, tw->tw_length, &dev_attr, 1803 DDI_DMA_CONSISTENT, dmamem_wait, NULL, (caddr_t *)&tw->tw_buf, 1804 &real_length, &tw->tw_accesshandle) != DDI_SUCCESS) { 1805 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1806 "uhci_create_transfer_wrapper: dma_mem_alloc fail"); 1807 ddi_dma_free_handle(&tw->tw_dmahandle); 1808 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 1809 1810 return (NULL); 1811 } 1812 1813 ASSERT(real_length >= length); 1814 1815 /* Bind the handle */ 1816 if (ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 1817 (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 1818 dmamem_wait, NULL, &tw->tw_cookie, &tw->tw_ncookies) != 1819 DDI_DMA_MAPPED) { 1820 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1821 "uhci_create_transfer_wrapper: Bind handle failed"); 1822 ddi_dma_mem_free(&tw->tw_accesshandle); 1823 ddi_dma_free_handle(&tw->tw_dmahandle); 1824 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 1825 1826 return (NULL); 1827 } 1828 1829 tw->tw_cookie_idx = 0; 1830 tw->tw_dma_offs = 0; 1831 1832 dmadone: 1833 /* 1834 * Only allow one wrapper to be added at a time. Insert the 1835 * new transaction wrapper into the list for this pipe. 1836 */ 1837 if (pp->pp_tw_head == NULL) { 1838 pp->pp_tw_head = tw; 1839 pp->pp_tw_tail = tw; 1840 } else { 1841 pp->pp_tw_tail->tw_next = tw; 1842 pp->pp_tw_tail = tw; 1843 ASSERT(tw->tw_next == NULL); 1844 } 1845 1846 /* Store a back pointer to the pipe private structure */ 1847 tw->tw_pipe_private = pp; 1848 1849 /* Store the transfer type - synchronous or asynchronous */ 1850 tw->tw_flags = usb_flags; 1851 1852 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 1853 "uhci_create_transfer_wrapper: tw = 0x%p, ncookies = %u", 1854 tw, tw->tw_ncookies); 1855 1856 return (tw); 1857 } 1858 1859 1860 /* 1861 * uhci_insert_hc_td: 1862 * Insert a Transfer Descriptor (TD) on an QH. 1863 */ 1864 int 1865 uhci_insert_hc_td( 1866 uhci_state_t *uhcip, 1867 uint32_t buffer_offset, 1868 size_t hcgtd_length, 1869 uhci_pipe_private_t *pp, 1870 uhci_trans_wrapper_t *tw, 1871 uchar_t PID, 1872 usb_req_attrs_t attrs) 1873 { 1874 uhci_td_t *td, *current_dummy; 1875 queue_head_t *qh = pp->pp_qh; 1876 1877 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 1878 1879 if ((td = uhci_allocate_td_from_pool(uhcip)) == NULL) { 1880 1881 return (USB_NO_RESOURCES); 1882 } 1883 1884 current_dummy = qh->td_tailp; 1885 1886 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 1887 "uhci_insert_hc_td: td %p, attrs = 0x%x", td, attrs); 1888 1889 /* 1890 * Fill in the current dummy td and 1891 * add the new dummy to the end. 1892 */ 1893 uhci_fill_in_td(uhcip, td, current_dummy, buffer_offset, 1894 hcgtd_length, pp, PID, attrs, tw); 1895 1896 /* 1897 * Allow HC hardware xfer the td, except interrupt out td. 1898 */ 1899 if ((tw->tw_handle_td != uhci_handle_intr_td) || (PID != PID_OUT)) { 1900 1901 SetTD_status(uhcip, current_dummy, UHCI_TD_ACTIVE); 1902 } 1903 1904 /* Insert this td onto the tw */ 1905 1906 if (tw->tw_hctd_head == NULL) { 1907 ASSERT(tw->tw_hctd_tail == NULL); 1908 tw->tw_hctd_head = current_dummy; 1909 tw->tw_hctd_tail = current_dummy; 1910 } else { 1911 /* Add the td to the end of the list */ 1912 tw->tw_hctd_tail->tw_td_next = current_dummy; 1913 tw->tw_hctd_tail = current_dummy; 1914 } 1915 1916 /* 1917 * Insert the TD on to the QH. When this occurs, 1918 * the Host Controller will see the newly filled in TD 1919 */ 1920 current_dummy->outst_td_next = NULL; 1921 current_dummy->outst_td_prev = uhcip->uhci_outst_tds_tail; 1922 if (uhcip->uhci_outst_tds_head == NULL) { 1923 uhcip->uhci_outst_tds_head = current_dummy; 1924 } else { 1925 uhcip->uhci_outst_tds_tail->outst_td_next = current_dummy; 1926 } 1927 uhcip->uhci_outst_tds_tail = current_dummy; 1928 current_dummy->tw = tw; 1929 1930 return (USB_SUCCESS); 1931 } 1932 1933 1934 /* 1935 * uhci_fill_in_td: 1936 * Fill in the fields of a Transfer Descriptor (TD). 1937 */ 1938 static void 1939 uhci_fill_in_td( 1940 uhci_state_t *uhcip, 1941 uhci_td_t *td, 1942 uhci_td_t *current_dummy, 1943 uint32_t buffer_offset, 1944 size_t length, 1945 uhci_pipe_private_t *pp, 1946 uchar_t PID, 1947 usb_req_attrs_t attrs, 1948 uhci_trans_wrapper_t *tw) 1949 { 1950 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 1951 uint32_t buf_addr; 1952 1953 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 1954 "uhci_fill_in_td: td 0x%p buf_offs 0x%x len 0x%lx " 1955 "attrs 0x%x", td, buffer_offset, length, attrs); 1956 1957 /* 1958 * If this is an isochronous TD, just return 1959 */ 1960 if (UHCI_XFER_TYPE(&ph->p_ep) == USB_EP_ATTR_ISOCH) { 1961 1962 return; 1963 } 1964 1965 /* The maximum transfer length of UHCI cannot exceed 0x500 bytes */ 1966 ASSERT(length <= UHCI_MAX_TD_XFER_SIZE); 1967 1968 bzero((char *)td, sizeof (uhci_td_t)); /* Clear the TD */ 1969 SetTD32(uhcip, current_dummy->link_ptr, TD_PADDR(td)); 1970 1971 if (attrs & USB_ATTRS_SHORT_XFER_OK) { 1972 SetTD_spd(uhcip, current_dummy, 1); 1973 } 1974 1975 mutex_enter(&ph->p_usba_device->usb_mutex); 1976 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 1977 SetTD_ls(uhcip, current_dummy, LOW_SPEED_DEVICE); 1978 } 1979 1980 SetTD_c_err(uhcip, current_dummy, UHCI_MAX_ERR_COUNT); 1981 SetTD_mlen(uhcip, current_dummy, 1982 (length == 0) ? ZERO_LENGTH : (length - 1)); 1983 SetTD_dtogg(uhcip, current_dummy, pp->pp_data_toggle); 1984 1985 /* Adjust the data toggle bit */ 1986 ADJ_DATA_TOGGLE(pp); 1987 1988 SetTD_devaddr(uhcip, current_dummy, ph->p_usba_device->usb_addr); 1989 SetTD_endpt(uhcip, current_dummy, 1990 ph->p_ep.bEndpointAddress & END_POINT_ADDRESS_MASK); 1991 SetTD_PID(uhcip, current_dummy, PID); 1992 SetTD_ioc(uhcip, current_dummy, INTERRUPT_ON_COMPLETION); 1993 1994 buf_addr = uhci_get_tw_paddr_by_offs(uhcip, buffer_offset, length, tw); 1995 SetTD32(uhcip, current_dummy->buffer_address, buf_addr); 1996 1997 td->qh_td_prev = current_dummy; 1998 current_dummy->qh_td_prev = NULL; 1999 pp->pp_qh->td_tailp = td; 2000 mutex_exit(&ph->p_usba_device->usb_mutex); 2001 } 2002 2003 /* 2004 * uhci_get_tw_paddr_by_offs: 2005 * Walk through the DMA cookies of a TW buffer to retrieve 2006 * the device address used for a TD. 2007 * 2008 * buffer_offset - the starting offset into the TW buffer, where the 2009 * TD should transfer from. When a TW has more than 2010 * one TD, the TDs must be filled in increasing order. 2011 */ 2012 static uint32_t 2013 uhci_get_tw_paddr_by_offs( 2014 uhci_state_t *uhcip, 2015 uint32_t buffer_offset, 2016 size_t length, 2017 uhci_trans_wrapper_t *tw) 2018 { 2019 uint32_t buf_addr; 2020 int rem_len; 2021 2022 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2023 "uhci_get_tw_paddr_by_offs: buf_offs 0x%x len 0x%lx", 2024 buffer_offset, length); 2025 2026 /* 2027 * TDs must be filled in increasing DMA offset order. 2028 * tw_dma_offs is initialized to be 0 at TW creation and 2029 * is only increased in this function. 2030 */ 2031 ASSERT(length == 0 || buffer_offset >= tw->tw_dma_offs); 2032 2033 if (length == 0) { 2034 buf_addr = 0; 2035 2036 return (buf_addr); 2037 } 2038 2039 /* 2040 * Advance to the next DMA cookie until finding the cookie 2041 * that buffer_offset falls in. 2042 * It is very likely this loop will never repeat more than 2043 * once. It is here just to accommodate the case buffer_offset 2044 * is increased by multiple cookies during two consecutive 2045 * calls into this function. In that case, the interim DMA 2046 * buffer is allowed to be skipped. 2047 */ 2048 while ((tw->tw_dma_offs + tw->tw_cookie.dmac_size) <= 2049 buffer_offset) { 2050 /* 2051 * tw_dma_offs always points to the starting offset 2052 * of a cookie 2053 */ 2054 tw->tw_dma_offs += tw->tw_cookie.dmac_size; 2055 ddi_dma_nextcookie(tw->tw_dmahandle, &tw->tw_cookie); 2056 tw->tw_cookie_idx++; 2057 ASSERT(tw->tw_cookie_idx < tw->tw_ncookies); 2058 } 2059 2060 /* 2061 * Counting the remained buffer length to be filled in 2062 * the TDs for current DMA cookie 2063 */ 2064 rem_len = (tw->tw_dma_offs + tw->tw_cookie.dmac_size) - 2065 buffer_offset; 2066 2067 /* Calculate the beginning address of the buffer */ 2068 ASSERT(length <= rem_len); 2069 buf_addr = (buffer_offset - tw->tw_dma_offs) + 2070 tw->tw_cookie.dmac_address; 2071 2072 USB_DPRINTF_L3(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2073 "uhci_get_tw_paddr_by_offs: dmac_addr 0x%p dmac_size " 2074 "0x%lx idx %d", buf_addr, tw->tw_cookie.dmac_size, 2075 tw->tw_cookie_idx); 2076 2077 return (buf_addr); 2078 } 2079 2080 2081 /* 2082 * uhci_modify_td_active_bits: 2083 * Sets active bit in all the tds of QH to INACTIVE so that 2084 * the HC stops processing the TD's related to the QH. 2085 */ 2086 void 2087 uhci_modify_td_active_bits( 2088 uhci_state_t *uhcip, 2089 uhci_pipe_private_t *pp) 2090 { 2091 uhci_td_t *td_head; 2092 usb_ep_descr_t *ept = &pp->pp_pipe_handle->p_ep; 2093 uhci_trans_wrapper_t *tw_head = pp->pp_tw_head; 2094 2095 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2096 "uhci_modify_td_active_bits: tw head %p", (void *)tw_head); 2097 2098 while (tw_head != NULL) { 2099 tw_head->tw_claim = UHCI_MODIFY_TD_BITS_CLAIMED; 2100 td_head = tw_head->tw_hctd_head; 2101 2102 while (td_head) { 2103 if (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_ISOCH) { 2104 SetTD_status(uhcip, td_head, 2105 GetTD_status(uhcip, td_head) & TD_INACTIVE); 2106 } else { 2107 SetTD32(uhcip, td_head->link_ptr, 2108 GetTD32(uhcip, td_head->link_ptr) | 2109 HC_END_OF_LIST); 2110 } 2111 2112 td_head = td_head->tw_td_next; 2113 } 2114 tw_head = tw_head->tw_next; 2115 } 2116 } 2117 2118 2119 /* 2120 * uhci_insert_ctrl_td: 2121 * Create a TD and a data buffer for a control Queue Head. 2122 */ 2123 int 2124 uhci_insert_ctrl_td( 2125 uhci_state_t *uhcip, 2126 usba_pipe_handle_data_t *ph, 2127 usb_ctrl_req_t *ctrl_reqp, 2128 usb_flags_t flags) 2129 { 2130 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 2131 uhci_trans_wrapper_t *tw; 2132 size_t ctrl_buf_size; 2133 2134 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2135 "uhci_insert_ctrl_td: timeout: 0x%x", ctrl_reqp->ctrl_timeout); 2136 2137 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 2138 2139 /* 2140 * If we have a control data phase, make the data buffer start 2141 * on the next 64-byte boundary so as to ensure the DMA cookie 2142 * can fit in the multiple TDs. The buffer in the range of 2143 * [SETUP_SIZE, UHCI_CTRL_EPT_MAX_SIZE) is just for padding 2144 * and not to be transferred. 2145 */ 2146 if (ctrl_reqp->ctrl_wLength) { 2147 ctrl_buf_size = UHCI_CTRL_EPT_MAX_SIZE + 2148 ctrl_reqp->ctrl_wLength; 2149 } else { 2150 ctrl_buf_size = SETUP_SIZE; 2151 } 2152 2153 /* Allocate a transaction wrapper */ 2154 if ((tw = uhci_create_transfer_wrapper(uhcip, pp, 2155 ctrl_buf_size, flags)) == NULL) { 2156 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2157 "uhci_insert_ctrl_td: TW allocation failed"); 2158 2159 return (USB_NO_RESOURCES); 2160 } 2161 2162 pp->pp_data_toggle = 0; 2163 2164 tw->tw_curr_xfer_reqp = (usb_opaque_t)ctrl_reqp; 2165 tw->tw_bytes_xfered = 0; 2166 tw->tw_bytes_pending = ctrl_reqp->ctrl_wLength; 2167 tw->tw_timeout_cnt = max(UHCI_CTRL_TIMEOUT, ctrl_reqp->ctrl_timeout); 2168 2169 /* 2170 * Initialize the callback and any callback 2171 * data for when the td completes. 2172 */ 2173 tw->tw_handle_td = uhci_handle_ctrl_td; 2174 tw->tw_handle_callback_value = NULL; 2175 2176 if ((uhci_create_setup_pkt(uhcip, pp, tw)) != USB_SUCCESS) { 2177 tw->tw_ctrl_state = 0; 2178 2179 /* free the transfer wrapper */ 2180 uhci_deallocate_tw(uhcip, pp, tw); 2181 2182 return (USB_NO_RESOURCES); 2183 } 2184 2185 tw->tw_ctrl_state = SETUP; 2186 2187 return (USB_SUCCESS); 2188 } 2189 2190 2191 /* 2192 * uhci_create_setup_pkt: 2193 * create a setup packet to initiate a control transfer. 2194 * 2195 * OHCI driver has seen the case where devices fail if there is 2196 * more than one control transfer to the device within a frame. 2197 * So, the UHCI ensures that only one TD will be put on the control 2198 * pipe to one device (to be consistent with OHCI driver). 2199 */ 2200 static int 2201 uhci_create_setup_pkt( 2202 uhci_state_t *uhcip, 2203 uhci_pipe_private_t *pp, 2204 uhci_trans_wrapper_t *tw) 2205 { 2206 int sdata; 2207 usb_ctrl_req_t *req = (usb_ctrl_req_t *)tw->tw_curr_xfer_reqp; 2208 2209 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2210 "uhci_create_setup_pkt: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%p", 2211 req->ctrl_bmRequestType, req->ctrl_bRequest, req->ctrl_wValue, 2212 req->ctrl_wIndex, req->ctrl_wLength, (void *)req->ctrl_data); 2213 2214 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 2215 ASSERT(tw != NULL); 2216 2217 /* Create the first four bytes of the setup packet */ 2218 sdata = (req->ctrl_bmRequestType | (req->ctrl_bRequest << 8) | 2219 (req->ctrl_wValue << 16)); 2220 ddi_put32(tw->tw_accesshandle, (uint_t *)tw->tw_buf, sdata); 2221 2222 /* Create the second four bytes */ 2223 sdata = (uint32_t)(req->ctrl_wIndex | (req->ctrl_wLength << 16)); 2224 ddi_put32(tw->tw_accesshandle, 2225 (uint_t *)(tw->tw_buf + sizeof (uint_t)), sdata); 2226 2227 /* 2228 * The TD's are placed on the QH one at a time. 2229 * Once this TD is placed on the done list, the 2230 * data or status phase TD will be enqueued. 2231 */ 2232 if ((uhci_insert_hc_td(uhcip, 0, SETUP_SIZE, 2233 pp, tw, PID_SETUP, req->ctrl_attributes)) != USB_SUCCESS) { 2234 2235 return (USB_NO_RESOURCES); 2236 } 2237 2238 USB_DPRINTF_L3(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2239 "Create_setup: pp = 0x%p, attrs = 0x%x", pp, req->ctrl_attributes); 2240 2241 /* 2242 * If this control transfer has a data phase, record the 2243 * direction. If the data phase is an OUT transaction , 2244 * copy the data into the buffer of the transfer wrapper. 2245 */ 2246 if (req->ctrl_wLength != 0) { 2247 /* There is a data stage. Find the direction */ 2248 if (req->ctrl_bmRequestType & USB_DEV_REQ_DEV_TO_HOST) { 2249 tw->tw_direction = PID_IN; 2250 } else { 2251 tw->tw_direction = PID_OUT; 2252 2253 /* Copy the data into the buffer */ 2254 ddi_rep_put8(tw->tw_accesshandle, 2255 req->ctrl_data->b_rptr, 2256 (uint8_t *)(tw->tw_buf + UHCI_CTRL_EPT_MAX_SIZE), 2257 req->ctrl_wLength, 2258 DDI_DEV_AUTOINCR); 2259 } 2260 } 2261 2262 return (USB_SUCCESS); 2263 } 2264 2265 2266 /* 2267 * uhci_create_stats: 2268 * Allocate and initialize the uhci kstat structures 2269 */ 2270 void 2271 uhci_create_stats(uhci_state_t *uhcip) 2272 { 2273 int i; 2274 char kstatname[KSTAT_STRLEN]; 2275 char *usbtypes[USB_N_COUNT_KSTATS] = 2276 {"ctrl", "isoch", "bulk", "intr"}; 2277 uint_t instance = uhcip->uhci_instance; 2278 const char *dname = ddi_driver_name(uhcip->uhci_dip); 2279 uhci_intrs_stats_t *isp; 2280 2281 if (UHCI_INTRS_STATS(uhcip) == NULL) { 2282 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs", 2283 dname, instance); 2284 UHCI_INTRS_STATS(uhcip) = kstat_create("usba", instance, 2285 kstatname, "usb_interrupts", KSTAT_TYPE_NAMED, 2286 sizeof (uhci_intrs_stats_t) / sizeof (kstat_named_t), 2287 KSTAT_FLAG_PERSISTENT); 2288 2289 if (UHCI_INTRS_STATS(uhcip) != NULL) { 2290 isp = UHCI_INTRS_STATS_DATA(uhcip); 2291 kstat_named_init(&isp->uhci_intrs_hc_halted, 2292 "HC Halted", KSTAT_DATA_UINT64); 2293 kstat_named_init(&isp->uhci_intrs_hc_process_err, 2294 "HC Process Errors", KSTAT_DATA_UINT64); 2295 kstat_named_init(&isp->uhci_intrs_host_sys_err, 2296 "Host Sys Errors", KSTAT_DATA_UINT64); 2297 kstat_named_init(&isp->uhci_intrs_resume_detected, 2298 "Resume Detected", KSTAT_DATA_UINT64); 2299 kstat_named_init(&isp->uhci_intrs_usb_err_intr, 2300 "USB Error", KSTAT_DATA_UINT64); 2301 kstat_named_init(&isp->uhci_intrs_usb_intr, 2302 "USB Interrupts", KSTAT_DATA_UINT64); 2303 kstat_named_init(&isp->uhci_intrs_total, 2304 "Total Interrupts", KSTAT_DATA_UINT64); 2305 kstat_named_init(&isp->uhci_intrs_not_claimed, 2306 "Not Claimed", KSTAT_DATA_UINT64); 2307 2308 UHCI_INTRS_STATS(uhcip)->ks_private = uhcip; 2309 UHCI_INTRS_STATS(uhcip)->ks_update = nulldev; 2310 kstat_install(UHCI_INTRS_STATS(uhcip)); 2311 } 2312 } 2313 2314 if (UHCI_TOTAL_STATS(uhcip) == NULL) { 2315 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total", 2316 dname, instance); 2317 UHCI_TOTAL_STATS(uhcip) = kstat_create("usba", instance, 2318 kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1, 2319 KSTAT_FLAG_PERSISTENT); 2320 2321 if (UHCI_TOTAL_STATS(uhcip) != NULL) { 2322 kstat_install(UHCI_TOTAL_STATS(uhcip)); 2323 } 2324 } 2325 2326 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 2327 if (uhcip->uhci_count_stats[i] == NULL) { 2328 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s", 2329 dname, instance, usbtypes[i]); 2330 uhcip->uhci_count_stats[i] = kstat_create("usba", 2331 instance, kstatname, "usb_byte_count", 2332 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT); 2333 2334 if (uhcip->uhci_count_stats[i] != NULL) { 2335 kstat_install(uhcip->uhci_count_stats[i]); 2336 } 2337 } 2338 } 2339 } 2340 2341 2342 /* 2343 * uhci_destroy_stats: 2344 * Clean up uhci kstat structures 2345 */ 2346 void 2347 uhci_destroy_stats(uhci_state_t *uhcip) 2348 { 2349 int i; 2350 2351 if (UHCI_INTRS_STATS(uhcip)) { 2352 kstat_delete(UHCI_INTRS_STATS(uhcip)); 2353 UHCI_INTRS_STATS(uhcip) = NULL; 2354 } 2355 2356 if (UHCI_TOTAL_STATS(uhcip)) { 2357 kstat_delete(UHCI_TOTAL_STATS(uhcip)); 2358 UHCI_TOTAL_STATS(uhcip) = NULL; 2359 } 2360 2361 for (i = 0; i < USB_N_COUNT_KSTATS; i++) { 2362 if (uhcip->uhci_count_stats[i]) { 2363 kstat_delete(uhcip->uhci_count_stats[i]); 2364 uhcip->uhci_count_stats[i] = NULL; 2365 } 2366 } 2367 } 2368 2369 2370 void 2371 uhci_do_intrs_stats(uhci_state_t *uhcip, int val) 2372 { 2373 if (UHCI_INTRS_STATS(uhcip) == NULL) { 2374 2375 return; 2376 } 2377 2378 UHCI_INTRS_STATS_DATA(uhcip)->uhci_intrs_total.value.ui64++; 2379 switch (val) { 2380 case USBSTS_REG_HC_HALTED: 2381 UHCI_INTRS_STATS_DATA(uhcip)->uhci_intrs_hc_halted.value.ui64++; 2382 break; 2383 case USBSTS_REG_HC_PROCESS_ERR: 2384 UHCI_INTRS_STATS_DATA(uhcip)-> 2385 uhci_intrs_hc_process_err.value.ui64++; 2386 break; 2387 case USBSTS_REG_HOST_SYS_ERR: 2388 UHCI_INTRS_STATS_DATA(uhcip)-> 2389 uhci_intrs_host_sys_err.value.ui64++; 2390 break; 2391 case USBSTS_REG_RESUME_DETECT: 2392 UHCI_INTRS_STATS_DATA(uhcip)-> 2393 uhci_intrs_resume_detected.value.ui64++; 2394 break; 2395 case USBSTS_REG_USB_ERR_INTR: 2396 UHCI_INTRS_STATS_DATA(uhcip)-> 2397 uhci_intrs_usb_err_intr.value.ui64++; 2398 break; 2399 case USBSTS_REG_USB_INTR: 2400 UHCI_INTRS_STATS_DATA(uhcip)->uhci_intrs_usb_intr.value.ui64++; 2401 break; 2402 default: 2403 UHCI_INTRS_STATS_DATA(uhcip)-> 2404 uhci_intrs_not_claimed.value.ui64++; 2405 break; 2406 } 2407 } 2408 2409 2410 void 2411 uhci_do_byte_stats(uhci_state_t *uhcip, size_t len, uint8_t attr, uint8_t addr) 2412 { 2413 uint8_t type = attr & USB_EP_ATTR_MASK; 2414 uint8_t dir = addr & USB_EP_DIR_MASK; 2415 2416 switch (dir) { 2417 case USB_EP_DIR_IN: 2418 UHCI_TOTAL_STATS_DATA(uhcip)->reads++; 2419 UHCI_TOTAL_STATS_DATA(uhcip)->nread += len; 2420 switch (type) { 2421 case USB_EP_ATTR_CONTROL: 2422 UHCI_CTRL_STATS(uhcip)->reads++; 2423 UHCI_CTRL_STATS(uhcip)->nread += len; 2424 break; 2425 case USB_EP_ATTR_BULK: 2426 UHCI_BULK_STATS(uhcip)->reads++; 2427 UHCI_BULK_STATS(uhcip)->nread += len; 2428 break; 2429 case USB_EP_ATTR_INTR: 2430 UHCI_INTR_STATS(uhcip)->reads++; 2431 UHCI_INTR_STATS(uhcip)->nread += len; 2432 break; 2433 case USB_EP_ATTR_ISOCH: 2434 UHCI_ISOC_STATS(uhcip)->reads++; 2435 UHCI_ISOC_STATS(uhcip)->nread += len; 2436 break; 2437 } 2438 break; 2439 case USB_EP_DIR_OUT: 2440 UHCI_TOTAL_STATS_DATA(uhcip)->writes++; 2441 UHCI_TOTAL_STATS_DATA(uhcip)->nwritten += len; 2442 switch (type) { 2443 case USB_EP_ATTR_CONTROL: 2444 UHCI_CTRL_STATS(uhcip)->writes++; 2445 UHCI_CTRL_STATS(uhcip)->nwritten += len; 2446 break; 2447 case USB_EP_ATTR_BULK: 2448 UHCI_BULK_STATS(uhcip)->writes++; 2449 UHCI_BULK_STATS(uhcip)->nwritten += len; 2450 break; 2451 case USB_EP_ATTR_INTR: 2452 UHCI_INTR_STATS(uhcip)->writes++; 2453 UHCI_INTR_STATS(uhcip)->nwritten += len; 2454 break; 2455 case USB_EP_ATTR_ISOCH: 2456 UHCI_ISOC_STATS(uhcip)->writes++; 2457 UHCI_ISOC_STATS(uhcip)->nwritten += len; 2458 break; 2459 } 2460 break; 2461 } 2462 } 2463 2464 2465 /* 2466 * uhci_free_tw: 2467 * Free the Transfer Wrapper (TW). 2468 */ 2469 void 2470 uhci_free_tw(uhci_state_t *uhcip, uhci_trans_wrapper_t *tw) 2471 { 2472 int rval, i; 2473 2474 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, "uhci_free_tw:"); 2475 2476 ASSERT(tw != NULL); 2477 2478 if (tw->tw_isoc_strtlen > 0) { 2479 ASSERT(tw->tw_isoc_bufs != NULL); 2480 for (i = 0; i < tw->tw_ncookies; i++) { 2481 rval = ddi_dma_unbind_handle( 2482 tw->tw_isoc_bufs[i].dma_handle); 2483 ASSERT(rval == USB_SUCCESS); 2484 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 2485 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 2486 } 2487 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen); 2488 } else if (tw->tw_dmahandle != NULL) { 2489 rval = ddi_dma_unbind_handle(tw->tw_dmahandle); 2490 ASSERT(rval == DDI_SUCCESS); 2491 2492 ddi_dma_mem_free(&tw->tw_accesshandle); 2493 ddi_dma_free_handle(&tw->tw_dmahandle); 2494 } 2495 2496 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 2497 } 2498 2499 2500 /* 2501 * uhci_deallocate_tw: 2502 * Deallocate of a Transaction Wrapper (TW) and this involves 2503 * the freeing of DMA resources. 2504 */ 2505 void 2506 uhci_deallocate_tw(uhci_state_t *uhcip, 2507 uhci_pipe_private_t *pp, uhci_trans_wrapper_t *tw) 2508 { 2509 uhci_trans_wrapper_t *head; 2510 2511 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2512 "uhci_deallocate_tw:"); 2513 2514 /* 2515 * If the transfer wrapper has no Host Controller (HC) 2516 * Transfer Descriptors (TD) associated with it, then 2517 * remove the transfer wrapper. The transfers are done 2518 * in FIFO order, so this should be the first transfer 2519 * wrapper on the list. 2520 */ 2521 if (tw->tw_hctd_head != NULL) { 2522 ASSERT(tw->tw_hctd_tail != NULL); 2523 2524 return; 2525 } 2526 2527 ASSERT(tw->tw_hctd_tail == NULL); 2528 ASSERT(pp->pp_tw_head != NULL); 2529 2530 /* 2531 * If pp->pp_tw_head is NULL, set the tail also to NULL. 2532 */ 2533 head = pp->pp_tw_head; 2534 2535 if (head == tw) { 2536 pp->pp_tw_head = head->tw_next; 2537 if (pp->pp_tw_head == NULL) { 2538 pp->pp_tw_tail = NULL; 2539 } 2540 } else { 2541 while (head->tw_next != tw) 2542 head = head->tw_next; 2543 head->tw_next = tw->tw_next; 2544 if (tw->tw_next == NULL) { 2545 pp->pp_tw_tail = head; 2546 } 2547 } 2548 uhci_free_tw(uhcip, tw); 2549 } 2550 2551 2552 void 2553 uhci_delete_td(uhci_state_t *uhcip, uhci_td_t *td) 2554 { 2555 uhci_td_t *tmp_td; 2556 uhci_trans_wrapper_t *tw = td->tw; 2557 2558 if ((td->outst_td_next == NULL) && (td->outst_td_prev == NULL)) { 2559 uhcip->uhci_outst_tds_head = NULL; 2560 uhcip->uhci_outst_tds_tail = NULL; 2561 } else if (td->outst_td_next == NULL) { 2562 td->outst_td_prev->outst_td_next = NULL; 2563 uhcip->uhci_outst_tds_tail = td->outst_td_prev; 2564 } else if (td->outst_td_prev == NULL) { 2565 td->outst_td_next->outst_td_prev = NULL; 2566 uhcip->uhci_outst_tds_head = td->outst_td_next; 2567 } else { 2568 td->outst_td_prev->outst_td_next = td->outst_td_next; 2569 td->outst_td_next->outst_td_prev = td->outst_td_prev; 2570 } 2571 2572 tmp_td = tw->tw_hctd_head; 2573 2574 if (tmp_td != td) { 2575 while (tmp_td->tw_td_next != td) { 2576 tmp_td = tmp_td->tw_td_next; 2577 } 2578 ASSERT(tmp_td); 2579 tmp_td->tw_td_next = td->tw_td_next; 2580 if (td->tw_td_next == NULL) { 2581 tw->tw_hctd_tail = tmp_td; 2582 } 2583 } else { 2584 tw->tw_hctd_head = tw->tw_hctd_head->tw_td_next; 2585 if (tw->tw_hctd_head == NULL) { 2586 tw->tw_hctd_tail = NULL; 2587 } 2588 } 2589 2590 td->flag = TD_FLAG_FREE; 2591 } 2592 2593 2594 void 2595 uhci_remove_tds_tws( 2596 uhci_state_t *uhcip, 2597 usba_pipe_handle_data_t *ph) 2598 { 2599 usb_opaque_t curr_reqp; 2600 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 2601 usb_ep_descr_t *ept = &pp->pp_pipe_handle->p_ep; 2602 uhci_trans_wrapper_t *tw_tmp; 2603 uhci_trans_wrapper_t *tw_head = pp->pp_tw_head; 2604 2605 while (tw_head != NULL) { 2606 tw_tmp = tw_head; 2607 tw_head = tw_head->tw_next; 2608 2609 curr_reqp = tw_tmp->tw_curr_xfer_reqp; 2610 if (curr_reqp) { 2611 /* do this for control/bulk/intr */ 2612 if ((tw_tmp->tw_direction == PID_IN) && 2613 (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_INTR)) { 2614 uhci_deallocate_periodic_in_resource(uhcip, 2615 pp, tw_tmp); 2616 } else { 2617 uhci_hcdi_callback(uhcip, pp, 2618 pp->pp_pipe_handle, tw_tmp, USB_CR_FLUSHED); 2619 } 2620 } /* end of curr_reqp */ 2621 2622 if (tw_tmp->tw_claim != UHCI_MODIFY_TD_BITS_CLAIMED) { 2623 continue; 2624 } 2625 2626 while (tw_tmp->tw_hctd_head != NULL) { 2627 uhci_delete_td(uhcip, tw_tmp->tw_hctd_head); 2628 } 2629 2630 uhci_deallocate_tw(uhcip, pp, tw_tmp); 2631 } 2632 } 2633 2634 2635 /* 2636 * uhci_remove_qh: 2637 * Remove the Queue Head from the Host Controller's 2638 * appropriate QH list. 2639 */ 2640 void 2641 uhci_remove_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 2642 { 2643 uhci_td_t *dummy_td; 2644 2645 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 2646 2647 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2648 "uhci_remove_qh:"); 2649 2650 dummy_td = pp->pp_qh->td_tailp; 2651 dummy_td->flag = TD_FLAG_FREE; 2652 2653 switch (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep)) { 2654 case USB_EP_ATTR_CONTROL: 2655 uhci_remove_ctrl_qh(uhcip, pp); 2656 break; 2657 case USB_EP_ATTR_BULK: 2658 uhci_remove_bulk_qh(uhcip, pp); 2659 break; 2660 case USB_EP_ATTR_INTR: 2661 uhci_remove_intr_qh(uhcip, pp); 2662 break; 2663 } 2664 } 2665 2666 2667 static void 2668 uhci_remove_intr_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 2669 { 2670 queue_head_t *qh = pp->pp_qh; 2671 queue_head_t *next_lattice_qh = 2672 QH_VADDR(GetQH32(uhcip, qh->link_ptr) & QH_LINK_PTR_MASK); 2673 2674 qh->prev_qh->link_ptr = qh->link_ptr; 2675 next_lattice_qh->prev_qh = qh->prev_qh; 2676 qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 2677 2678 } 2679 2680 /* 2681 * uhci_remove_bulk_qh: 2682 * Remove a bulk QH from the Host Controller's QH list. There may be a 2683 * loop for bulk QHs, we must care about this while removing a bulk QH. 2684 */ 2685 static void 2686 uhci_remove_bulk_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 2687 { 2688 queue_head_t *qh = pp->pp_qh; 2689 queue_head_t *next_lattice_qh; 2690 uint32_t paddr; 2691 2692 paddr = (GetQH32(uhcip, qh->link_ptr) & QH_LINK_PTR_MASK); 2693 next_lattice_qh = (qh == uhcip->uhci_bulk_xfers_q_tail) ? 2694 0 : QH_VADDR(paddr); 2695 2696 if ((qh == uhcip->uhci_bulk_xfers_q_tail) && 2697 (qh->prev_qh == uhcip->uhci_bulk_xfers_q_head)) { 2698 SetQH32(uhcip, qh->prev_qh->link_ptr, HC_END_OF_LIST); 2699 } else { 2700 qh->prev_qh->link_ptr = qh->link_ptr; 2701 } 2702 2703 if (next_lattice_qh == NULL) { 2704 uhcip->uhci_bulk_xfers_q_tail = qh->prev_qh; 2705 } else { 2706 next_lattice_qh->prev_qh = qh->prev_qh; 2707 } 2708 2709 qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 2710 2711 } 2712 2713 2714 static void 2715 uhci_remove_ctrl_qh(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 2716 { 2717 queue_head_t *qh = pp->pp_qh; 2718 queue_head_t *next_lattice_qh = 2719 QH_VADDR(GetQH32(uhcip, qh->link_ptr) & QH_LINK_PTR_MASK); 2720 2721 qh->prev_qh->link_ptr = qh->link_ptr; 2722 if (next_lattice_qh->prev_qh != NULL) { 2723 next_lattice_qh->prev_qh = qh->prev_qh; 2724 } else { 2725 uhcip->uhci_ctrl_xfers_q_tail = qh->prev_qh; 2726 } 2727 2728 qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 2729 } 2730 2731 2732 /* 2733 * uhci_allocate_td_from_pool: 2734 * Allocate a Transfer Descriptor (TD) from the TD buffer pool. 2735 */ 2736 static uhci_td_t * 2737 uhci_allocate_td_from_pool(uhci_state_t *uhcip) 2738 { 2739 int index; 2740 uhci_td_t *td; 2741 2742 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 2743 2744 /* 2745 * Search for a blank Transfer Descriptor (TD) 2746 * in the TD buffer pool. 2747 */ 2748 for (index = 0; index < uhci_td_pool_size; index ++) { 2749 if (uhcip->uhci_td_pool_addr[index].flag == TD_FLAG_FREE) { 2750 break; 2751 } 2752 } 2753 2754 if (index == uhci_td_pool_size) { 2755 USB_DPRINTF_L2(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2756 "uhci_allocate_td_from_pool: TD exhausted"); 2757 2758 return (NULL); 2759 } 2760 2761 USB_DPRINTF_L4(PRINT_MASK_ALLOC, uhcip->uhci_log_hdl, 2762 "uhci_allocate_td_from_pool: Allocated %d", index); 2763 2764 /* Create a new dummy for the end of the TD list */ 2765 td = &uhcip->uhci_td_pool_addr[index]; 2766 2767 /* Mark the newly allocated TD as a dummy */ 2768 td->flag = TD_FLAG_DUMMY; 2769 td->qh_td_prev = NULL; 2770 2771 return (td); 2772 } 2773 2774 2775 /* 2776 * uhci_insert_bulk_td: 2777 */ 2778 int 2779 uhci_insert_bulk_td( 2780 uhci_state_t *uhcip, 2781 usba_pipe_handle_data_t *ph, 2782 usb_bulk_req_t *req, 2783 usb_flags_t flags) 2784 { 2785 size_t length; 2786 uint_t mps; /* MaxPacketSize */ 2787 uint_t num_bulk_tds, i, j; 2788 uint32_t buf_offs; 2789 uhci_td_t *bulk_td_ptr; 2790 uhci_td_t *current_dummy, *tmp_td; 2791 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 2792 uhci_trans_wrapper_t *tw; 2793 uhci_bulk_isoc_xfer_t *bulk_xfer_info; 2794 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 2795 2796 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2797 "uhci_insert_bulk_td: req: 0x%p, flags = 0x%x", req, flags); 2798 2799 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 2800 2801 /* 2802 * Create transfer wrapper 2803 */ 2804 if ((tw = uhci_create_transfer_wrapper(uhcip, pp, req->bulk_len, 2805 flags)) == NULL) { 2806 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2807 "uhci_insert_bulk_td: TW allocation failed"); 2808 2809 return (USB_NO_RESOURCES); 2810 } 2811 2812 tw->tw_bytes_xfered = 0; 2813 tw->tw_bytes_pending = req->bulk_len; 2814 tw->tw_handle_td = uhci_handle_bulk_td; 2815 tw->tw_handle_callback_value = (usb_opaque_t)req->bulk_data; 2816 tw->tw_timeout_cnt = req->bulk_timeout; 2817 tw->tw_data = req->bulk_data; 2818 tw->tw_curr_xfer_reqp = (usb_opaque_t)req; 2819 2820 /* Get the bulk pipe direction */ 2821 tw->tw_direction = (UHCI_XFER_DIR(&ph->p_ep) == USB_EP_DIR_OUT) ? 2822 PID_OUT : PID_IN; 2823 2824 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2825 "uhci_insert_bulk_td: direction: 0x%x", tw->tw_direction); 2826 2827 /* If the DATA OUT, copy the data into transfer buffer. */ 2828 if (tw->tw_direction == PID_OUT) { 2829 if (req->bulk_len) { 2830 ASSERT(req->bulk_data != NULL); 2831 2832 /* Copy the data into the message */ 2833 ddi_rep_put8(tw->tw_accesshandle, 2834 req->bulk_data->b_rptr, 2835 (uint8_t *)tw->tw_buf, 2836 req->bulk_len, DDI_DEV_AUTOINCR); 2837 } 2838 } 2839 2840 /* Get the max packet size. */ 2841 length = mps = pp->pp_pipe_handle->p_ep.wMaxPacketSize; 2842 2843 /* 2844 * Calculate number of TD's to insert in the current frame interval. 2845 * Max number TD's allowed (driver implementation) is 128 2846 * in one frame interval. Once all the TD's are completed 2847 * then the remaining TD's will be inserted into the lattice 2848 * in the uhci_handle_bulk_td(). 2849 */ 2850 if ((tw->tw_bytes_pending / mps) >= MAX_NUM_BULK_TDS_PER_XFER) { 2851 num_bulk_tds = MAX_NUM_BULK_TDS_PER_XFER; 2852 } else { 2853 num_bulk_tds = (tw->tw_bytes_pending / mps); 2854 2855 if (tw->tw_bytes_pending % mps || tw->tw_bytes_pending == 0) { 2856 num_bulk_tds++; 2857 length = (tw->tw_bytes_pending % mps); 2858 } 2859 } 2860 2861 /* 2862 * Allocate memory for the bulk xfer information structure 2863 */ 2864 if ((bulk_xfer_info = kmem_zalloc( 2865 sizeof (uhci_bulk_isoc_xfer_t), KM_NOSLEEP)) == NULL) { 2866 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2867 "uhci_insert_bulk_td: kmem_zalloc failed"); 2868 2869 /* Free the transfer wrapper */ 2870 uhci_deallocate_tw(uhcip, pp, tw); 2871 2872 return (USB_FAILURE); 2873 } 2874 2875 /* Allocate memory for the bulk TD's */ 2876 if (uhci_alloc_bulk_isoc_tds(uhcip, num_bulk_tds, bulk_xfer_info) != 2877 USB_SUCCESS) { 2878 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2879 "uhci_insert_bulk_td: alloc_bulk_isoc_tds failed"); 2880 2881 kmem_free(bulk_xfer_info, sizeof (uhci_bulk_isoc_xfer_t)); 2882 2883 /* Free the transfer wrapper */ 2884 uhci_deallocate_tw(uhcip, pp, tw); 2885 2886 return (USB_FAILURE); 2887 } 2888 2889 td_pool_ptr = &bulk_xfer_info->td_pools[0]; 2890 bulk_td_ptr = (uhci_td_t *)td_pool_ptr->pool_addr; 2891 bulk_td_ptr[0].qh_td_prev = NULL; 2892 current_dummy = pp->pp_qh->td_tailp; 2893 buf_offs = 0; 2894 pp->pp_qh->bulk_xfer_info = bulk_xfer_info; 2895 2896 /* Fill up all the bulk TD's */ 2897 for (i = 0; i < bulk_xfer_info->num_pools; i++) { 2898 for (j = 0; j < (td_pool_ptr->num_tds - 1); j++) { 2899 uhci_fill_in_bulk_isoc_td(uhcip, &bulk_td_ptr[j], 2900 &bulk_td_ptr[j+1], BULKTD_PADDR(td_pool_ptr, 2901 &bulk_td_ptr[j+1]), ph, buf_offs, mps, tw); 2902 buf_offs += mps; 2903 } 2904 2905 /* fill in the last TD */ 2906 if (i == (bulk_xfer_info->num_pools - 1)) { 2907 uhci_fill_in_bulk_isoc_td(uhcip, &bulk_td_ptr[j], 2908 current_dummy, TD_PADDR(current_dummy), 2909 ph, buf_offs, length, tw); 2910 } else { 2911 /* fill in the TD at the tail of a pool */ 2912 tmp_td = &bulk_td_ptr[j]; 2913 td_pool_ptr = &bulk_xfer_info->td_pools[i + 1]; 2914 bulk_td_ptr = (uhci_td_t *)td_pool_ptr->pool_addr; 2915 uhci_fill_in_bulk_isoc_td(uhcip, tmp_td, 2916 &bulk_td_ptr[0], BULKTD_PADDR(td_pool_ptr, 2917 &bulk_td_ptr[0]), ph, buf_offs, mps, tw); 2918 buf_offs += mps; 2919 } 2920 } 2921 2922 bulk_xfer_info->num_tds = num_bulk_tds; 2923 2924 /* 2925 * Point the end of the lattice tree to the start of the bulk xfers 2926 * queue head. This allows the HC to execute the same Queue Head/TD 2927 * in the same frame. There are some bulk devices, which NAKs after 2928 * completing each TD. As a result, the performance on such devices 2929 * is very bad. This loop will provide a chance to execute NAk'ed 2930 * bulk TDs again in the same frame. 2931 */ 2932 if (uhcip->uhci_pending_bulk_cmds++ == 0) { 2933 uhcip->uhci_bulk_xfers_q_tail->link_ptr = 2934 uhcip->uhci_bulk_xfers_q_head->link_ptr; 2935 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 2936 "uhci_insert_bulk_td: count = %d no tds %d", 2937 uhcip->uhci_pending_bulk_cmds, num_bulk_tds); 2938 } 2939 2940 /* Insert on the bulk queue head for the execution by HC */ 2941 SetQH32(uhcip, pp->pp_qh->element_ptr, 2942 bulk_xfer_info->td_pools[0].cookie.dmac_address); 2943 2944 return (USB_SUCCESS); 2945 } 2946 2947 2948 /* 2949 * uhci_fill_in_bulk_isoc_td 2950 * Fills the bulk/isoc TD 2951 * 2952 * offset - different meanings for bulk and isoc TDs: 2953 * starting offset into the TW buffer for a bulk TD 2954 * and the index into the isoc packet list for an isoc TD 2955 */ 2956 void 2957 uhci_fill_in_bulk_isoc_td(uhci_state_t *uhcip, uhci_td_t *current_td, 2958 uhci_td_t *next_td, 2959 uint32_t next_td_paddr, 2960 usba_pipe_handle_data_t *ph, 2961 uint_t offset, 2962 uint_t length, 2963 uhci_trans_wrapper_t *tw) 2964 { 2965 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 2966 usb_ep_descr_t *ept = &pp->pp_pipe_handle->p_ep; 2967 uint32_t buf_addr; 2968 2969 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 2970 "uhci_fill_in_bulk_isoc_td: tw 0x%p offs 0x%x length 0x%x", 2971 tw, offset, length); 2972 2973 bzero((char *)current_td, sizeof (uhci_td_t)); 2974 SetTD32(uhcip, current_td->link_ptr, next_td_paddr | HC_DEPTH_FIRST); 2975 2976 switch (UHCI_XFER_TYPE(ept)) { 2977 case USB_EP_ATTR_ISOCH: 2978 if (((usb_isoc_req_t *)tw->tw_curr_xfer_reqp)->isoc_attributes 2979 & USB_ATTRS_SHORT_XFER_OK) { 2980 SetTD_spd(uhcip, current_td, 1); 2981 } 2982 break; 2983 case USB_EP_ATTR_BULK: 2984 if (((usb_bulk_req_t *)tw->tw_curr_xfer_reqp)->bulk_attributes 2985 & USB_ATTRS_SHORT_XFER_OK) { 2986 SetTD_spd(uhcip, current_td, 1); 2987 } 2988 break; 2989 } 2990 2991 mutex_enter(&ph->p_usba_device->usb_mutex); 2992 2993 SetTD_c_err(uhcip, current_td, UHCI_MAX_ERR_COUNT); 2994 SetTD_status(uhcip, current_td, UHCI_TD_ACTIVE); 2995 SetTD_ioc(uhcip, current_td, INTERRUPT_ON_COMPLETION); 2996 SetTD_mlen(uhcip, current_td, 2997 (length == 0) ? ZERO_LENGTH : (length - 1)); 2998 SetTD_dtogg(uhcip, current_td, pp->pp_data_toggle); 2999 SetTD_devaddr(uhcip, current_td, ph->p_usba_device->usb_addr); 3000 SetTD_endpt(uhcip, current_td, ph->p_ep.bEndpointAddress & 3001 END_POINT_ADDRESS_MASK); 3002 SetTD_PID(uhcip, current_td, tw->tw_direction); 3003 3004 /* Get the right buffer address for the current TD */ 3005 switch (UHCI_XFER_TYPE(ept)) { 3006 case USB_EP_ATTR_ISOCH: 3007 buf_addr = tw->tw_isoc_bufs[offset].cookie.dmac_address; 3008 break; 3009 case USB_EP_ATTR_BULK: 3010 buf_addr = uhci_get_tw_paddr_by_offs(uhcip, offset, 3011 length, tw); 3012 break; 3013 } 3014 SetTD32(uhcip, current_td->buffer_address, buf_addr); 3015 3016 /* 3017 * Adjust the data toggle. 3018 * The data toggle bit must always be 0 for isoc transfers. 3019 * And set the "iso" bit in the TD for isoc transfers. 3020 */ 3021 if (UHCI_XFER_TYPE(ept) == USB_EP_ATTR_ISOCH) { 3022 pp->pp_data_toggle = 0; 3023 SetTD_iso(uhcip, current_td, 1); 3024 } else { 3025 ADJ_DATA_TOGGLE(pp); 3026 next_td->qh_td_prev = current_td; 3027 pp->pp_qh->td_tailp = next_td; 3028 } 3029 3030 current_td->outst_td_next = NULL; 3031 current_td->outst_td_prev = uhcip->uhci_outst_tds_tail; 3032 if (uhcip->uhci_outst_tds_head == NULL) { 3033 uhcip->uhci_outst_tds_head = current_td; 3034 } else { 3035 uhcip->uhci_outst_tds_tail->outst_td_next = current_td; 3036 } 3037 uhcip->uhci_outst_tds_tail = current_td; 3038 current_td->tw = tw; 3039 3040 if (tw->tw_hctd_head == NULL) { 3041 ASSERT(tw->tw_hctd_tail == NULL); 3042 tw->tw_hctd_head = current_td; 3043 tw->tw_hctd_tail = current_td; 3044 } else { 3045 /* Add the td to the end of the list */ 3046 tw->tw_hctd_tail->tw_td_next = current_td; 3047 tw->tw_hctd_tail = current_td; 3048 } 3049 3050 mutex_exit(&ph->p_usba_device->usb_mutex); 3051 } 3052 3053 3054 /* 3055 * uhci_alloc_bulk_isoc_tds: 3056 * - Allocates the isoc/bulk TD pools. It will allocate one whole 3057 * pool to store all the TDs if the system allows. Only when the 3058 * first allocation fails, it tries to allocate several small 3059 * pools with each pool limited in physical page size. 3060 */ 3061 static int 3062 uhci_alloc_bulk_isoc_tds( 3063 uhci_state_t *uhcip, 3064 uint_t num_tds, 3065 uhci_bulk_isoc_xfer_t *info) 3066 { 3067 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3068 "uhci_alloc_bulk_isoc_tds: num_tds: 0x%x info: 0x%p", 3069 num_tds, info); 3070 3071 info->num_pools = 1; 3072 /* allocate as a whole pool at the first time */ 3073 if (uhci_alloc_memory_for_tds(uhcip, num_tds, info) != 3074 USB_SUCCESS) { 3075 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3076 "alloc_memory_for_tds failed: num_tds %d num_pools %d", 3077 num_tds, info->num_pools); 3078 3079 /* reduce the td number per pool and alloc again */ 3080 info->num_pools = num_tds / UHCI_MAX_TD_NUM_PER_POOL; 3081 if (num_tds % UHCI_MAX_TD_NUM_PER_POOL) { 3082 info->num_pools++; 3083 } 3084 3085 if (uhci_alloc_memory_for_tds(uhcip, num_tds, info) != 3086 USB_SUCCESS) { 3087 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3088 "alloc_memory_for_tds failed: num_tds %d " 3089 "num_pools %d", num_tds, info->num_pools); 3090 3091 return (USB_NO_RESOURCES); 3092 } 3093 } 3094 3095 return (USB_SUCCESS); 3096 } 3097 3098 3099 /* 3100 * uhci_alloc_memory_for_tds: 3101 * - Allocates memory for the isoc/bulk td pools. 3102 */ 3103 static int 3104 uhci_alloc_memory_for_tds( 3105 uhci_state_t *uhcip, 3106 uint_t num_tds, 3107 uhci_bulk_isoc_xfer_t *info) 3108 { 3109 int result, i, j, err; 3110 size_t real_length; 3111 uint_t ccount, num; 3112 ddi_device_acc_attr_t dev_attr; 3113 uhci_bulk_isoc_td_pool_t *td_pool_ptr1, *td_pool_ptr2; 3114 3115 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3116 "uhci_alloc_memory_for_tds: num_tds: 0x%x info: 0x%p " 3117 "num_pools: %u", num_tds, info, info->num_pools); 3118 3119 /* The host controller will be little endian */ 3120 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 3121 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 3122 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 3123 3124 /* Allocate the TD pool structures */ 3125 if ((info->td_pools = kmem_zalloc( 3126 (sizeof (uhci_bulk_isoc_td_pool_t) * info->num_pools), 3127 KM_SLEEP)) == NULL) { 3128 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3129 "uhci_alloc_memory_for_tds: alloc td_pools failed"); 3130 3131 return (USB_FAILURE); 3132 } 3133 3134 for (i = 0; i < info->num_pools; i++) { 3135 if (info->num_pools == 1) { 3136 num = num_tds; 3137 } else if (i < (info->num_pools - 1)) { 3138 num = UHCI_MAX_TD_NUM_PER_POOL; 3139 } else { 3140 num = (num_tds % UHCI_MAX_TD_NUM_PER_POOL); 3141 } 3142 3143 td_pool_ptr1 = &info->td_pools[i]; 3144 3145 /* Allocate the bulk TD pool DMA handle */ 3146 if (ddi_dma_alloc_handle(uhcip->uhci_dip, 3147 &uhcip->uhci_dma_attr, DDI_DMA_SLEEP, 0, 3148 &td_pool_ptr1->dma_handle) != DDI_SUCCESS) { 3149 3150 for (j = 0; j < i; j++) { 3151 td_pool_ptr2 = &info->td_pools[j]; 3152 result = ddi_dma_unbind_handle( 3153 td_pool_ptr2->dma_handle); 3154 ASSERT(result == DDI_SUCCESS); 3155 ddi_dma_mem_free(&td_pool_ptr2->mem_handle); 3156 ddi_dma_free_handle(&td_pool_ptr2->dma_handle); 3157 } 3158 3159 kmem_free(info->td_pools, 3160 (sizeof (uhci_bulk_isoc_td_pool_t) * 3161 info->num_pools)); 3162 3163 return (USB_FAILURE); 3164 } 3165 3166 /* Allocate the memory for the bulk TD pool */ 3167 if (ddi_dma_mem_alloc(td_pool_ptr1->dma_handle, 3168 num * sizeof (uhci_td_t), &dev_attr, 3169 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 0, 3170 &td_pool_ptr1->pool_addr, &real_length, 3171 &td_pool_ptr1->mem_handle) != DDI_SUCCESS) { 3172 3173 ddi_dma_free_handle(&td_pool_ptr1->dma_handle); 3174 3175 for (j = 0; j < i; j++) { 3176 td_pool_ptr2 = &info->td_pools[j]; 3177 result = ddi_dma_unbind_handle( 3178 td_pool_ptr2->dma_handle); 3179 ASSERT(result == DDI_SUCCESS); 3180 ddi_dma_mem_free(&td_pool_ptr2->mem_handle); 3181 ddi_dma_free_handle(&td_pool_ptr2->dma_handle); 3182 } 3183 3184 kmem_free(info->td_pools, 3185 (sizeof (uhci_bulk_isoc_td_pool_t) * 3186 info->num_pools)); 3187 3188 return (USB_FAILURE); 3189 } 3190 3191 /* Map the bulk TD pool into the I/O address space */ 3192 result = ddi_dma_addr_bind_handle(td_pool_ptr1->dma_handle, 3193 NULL, (caddr_t)td_pool_ptr1->pool_addr, real_length, 3194 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 3195 &td_pool_ptr1->cookie, &ccount); 3196 3197 /* Process the result */ 3198 err = USB_SUCCESS; 3199 3200 if (result != DDI_DMA_MAPPED) { 3201 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3202 "uhci_allocate_memory_for_tds: Result = %d", 3203 result); 3204 uhci_decode_ddi_dma_addr_bind_handle_result(uhcip, 3205 result); 3206 3207 err = USB_FAILURE; 3208 } 3209 3210 if ((result == DDI_DMA_MAPPED) && (ccount != 1)) { 3211 /* The cookie count should be 1 */ 3212 USB_DPRINTF_L2(PRINT_MASK_ATTA, 3213 uhcip->uhci_log_hdl, 3214 "uhci_allocate_memory_for_tds: " 3215 "More than 1 cookie"); 3216 3217 result = ddi_dma_unbind_handle( 3218 td_pool_ptr1->dma_handle); 3219 ASSERT(result == DDI_SUCCESS); 3220 3221 err = USB_FAILURE; 3222 } 3223 3224 if (err == USB_FAILURE) { 3225 3226 ddi_dma_mem_free(&td_pool_ptr1->mem_handle); 3227 ddi_dma_free_handle(&td_pool_ptr1->dma_handle); 3228 3229 for (j = 0; j < i; j++) { 3230 td_pool_ptr2 = &info->td_pools[j]; 3231 result = ddi_dma_unbind_handle( 3232 td_pool_ptr2->dma_handle); 3233 ASSERT(result == DDI_SUCCESS); 3234 ddi_dma_mem_free(&td_pool_ptr2->mem_handle); 3235 ddi_dma_free_handle(&td_pool_ptr2->dma_handle); 3236 } 3237 3238 kmem_free(info->td_pools, 3239 (sizeof (uhci_bulk_isoc_td_pool_t) * 3240 info->num_pools)); 3241 3242 return (USB_FAILURE); 3243 } 3244 3245 bzero((void *)td_pool_ptr1->pool_addr, 3246 num * sizeof (uhci_td_t)); 3247 td_pool_ptr1->num_tds = num; 3248 } 3249 3250 return (USB_SUCCESS); 3251 } 3252 3253 3254 /* 3255 * uhci_handle_bulk_td: 3256 * 3257 * Handles the completed bulk transfer descriptors 3258 */ 3259 void 3260 uhci_handle_bulk_td(uhci_state_t *uhcip, uhci_td_t *td) 3261 { 3262 uint_t num_bulk_tds, index, td_count, j; 3263 usb_cr_t error; 3264 uint_t length, bytes_xfered; 3265 ushort_t MaxPacketSize; 3266 uint32_t buf_offs, paddr; 3267 uhci_td_t *bulk_td_ptr, *current_dummy, *td_head; 3268 uhci_td_t *tmp_td; 3269 queue_head_t *qh, *next_qh; 3270 uhci_trans_wrapper_t *tw = td->tw; 3271 uhci_pipe_private_t *pp = tw->tw_pipe_private; 3272 uhci_bulk_isoc_xfer_t *bulk_xfer_info; 3273 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 3274 usba_pipe_handle_data_t *ph; 3275 3276 USB_DPRINTF_L4(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3277 "uhci_handle_bulk_td: td = 0x%p tw = 0x%p", td, tw); 3278 3279 /* 3280 * Update the tw_bytes_pending, and tw_bytes_xfered 3281 */ 3282 bytes_xfered = ZERO_LENGTH; 3283 3284 /* 3285 * Check whether there are any errors occurred in the xfer. 3286 * If so, update the data_toggle for the queue head and 3287 * return error to the upper layer. 3288 */ 3289 if (GetTD_status(uhcip, td) & TD_STATUS_MASK) { 3290 uhci_handle_bulk_td_errors(uhcip, td); 3291 3292 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3293 "uhci_handle_bulk_td: error; data toggle: 0x%x", 3294 pp->pp_data_toggle); 3295 3296 return; 3297 } 3298 3299 /* 3300 * Update the tw_bytes_pending, and tw_bytes_xfered 3301 */ 3302 bytes_xfered = GetTD_alen(uhcip, td); 3303 if (bytes_xfered != ZERO_LENGTH) { 3304 tw->tw_bytes_pending -= (bytes_xfered + 1); 3305 tw->tw_bytes_xfered += (bytes_xfered + 1); 3306 } 3307 3308 /* 3309 * Get Bulk pipe information and pipe handle 3310 */ 3311 bulk_xfer_info = pp->pp_qh->bulk_xfer_info; 3312 ph = tw->tw_pipe_private->pp_pipe_handle; 3313 3314 /* 3315 * Check whether data underrun occurred. 3316 * If so, complete the transfer 3317 * Update the data toggle bit 3318 */ 3319 if (bytes_xfered != GetTD_mlen(uhcip, td)) { 3320 bulk_xfer_info->num_tds = 1; 3321 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3322 "uhci_handle_bulk_td: Data underrun occured"); 3323 3324 pp->pp_data_toggle = GetTD_dtogg(uhcip, td) == 0 ? 1 : 0; 3325 } 3326 3327 /* 3328 * If the TD's in the current frame are completed, then check 3329 * whether we have any more bytes to xfer. If so, insert TD's. 3330 * If no more bytes needs to be transferred, then do callback to the 3331 * upper layer. 3332 * If the TD's in the current frame are not completed, then 3333 * just delete the TD from the linked lists. 3334 */ 3335 USB_DPRINTF_L3(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3336 "uhci_handle_bulk_td: completed TD data toggle: 0x%x", 3337 GetTD_dtogg(uhcip, td)); 3338 3339 if (--bulk_xfer_info->num_tds == 0) { 3340 uhci_delete_td(uhcip, td); 3341 3342 if ((tw->tw_bytes_pending) && 3343 (GetTD_mlen(uhcip, td) - GetTD_alen(uhcip, td) == 0)) { 3344 3345 MaxPacketSize = pp->pp_pipe_handle->p_ep.wMaxPacketSize; 3346 length = MaxPacketSize; 3347 3348 qh = pp->pp_qh; 3349 paddr = GetQH32(uhcip, qh->link_ptr) & QH_LINK_PTR_MASK; 3350 if (GetQH32(uhcip, qh->link_ptr) != 3351 GetQH32(uhcip, 3352 uhcip->uhci_bulk_xfers_q_head->link_ptr)) { 3353 next_qh = QH_VADDR(paddr); 3354 SetQH32(uhcip, qh->prev_qh->link_ptr, 3355 paddr|(0x2)); 3356 next_qh->prev_qh = qh->prev_qh; 3357 SetQH32(uhcip, qh->link_ptr, 3358 GetQH32(uhcip, 3359 uhcip->uhci_bulk_xfers_q_head->link_ptr)); 3360 qh->prev_qh = uhcip->uhci_bulk_xfers_q_tail; 3361 SetQH32(uhcip, 3362 uhcip->uhci_bulk_xfers_q_tail->link_ptr, 3363 QH_PADDR(qh) | 0x2); 3364 uhcip->uhci_bulk_xfers_q_tail = qh; 3365 } 3366 3367 if ((tw->tw_bytes_pending / MaxPacketSize) >= 3368 MAX_NUM_BULK_TDS_PER_XFER) { 3369 num_bulk_tds = MAX_NUM_BULK_TDS_PER_XFER; 3370 } else { 3371 num_bulk_tds = 3372 (tw->tw_bytes_pending / MaxPacketSize); 3373 if (tw->tw_bytes_pending % MaxPacketSize) { 3374 num_bulk_tds++; 3375 length = (tw->tw_bytes_pending % 3376 MaxPacketSize); 3377 } 3378 } 3379 3380 current_dummy = pp->pp_qh->td_tailp; 3381 td_pool_ptr = &bulk_xfer_info->td_pools[0]; 3382 bulk_td_ptr = (uhci_td_t *)td_pool_ptr->pool_addr; 3383 buf_offs = tw->tw_bytes_xfered; 3384 td_count = num_bulk_tds; 3385 index = 0; 3386 3387 /* reuse the TDs to transfer more data */ 3388 while (td_count > 0) { 3389 for (j = 0; 3390 (j < (td_pool_ptr->num_tds - 1)) && 3391 (td_count > 1); j++, td_count--) { 3392 uhci_fill_in_bulk_isoc_td(uhcip, 3393 &bulk_td_ptr[j], &bulk_td_ptr[j+1], 3394 BULKTD_PADDR(td_pool_ptr, 3395 &bulk_td_ptr[j+1]), ph, buf_offs, 3396 MaxPacketSize, tw); 3397 buf_offs += MaxPacketSize; 3398 } 3399 3400 if (td_count == 1) { 3401 uhci_fill_in_bulk_isoc_td(uhcip, 3402 &bulk_td_ptr[j], current_dummy, 3403 TD_PADDR(current_dummy), ph, 3404 buf_offs, length, tw); 3405 3406 break; 3407 } else { 3408 tmp_td = &bulk_td_ptr[j]; 3409 ASSERT(index < 3410 (bulk_xfer_info->num_pools - 1)); 3411 td_pool_ptr = &bulk_xfer_info-> 3412 td_pools[index + 1]; 3413 bulk_td_ptr = (uhci_td_t *) 3414 td_pool_ptr->pool_addr; 3415 uhci_fill_in_bulk_isoc_td(uhcip, 3416 tmp_td, &bulk_td_ptr[0], 3417 BULKTD_PADDR(td_pool_ptr, 3418 &bulk_td_ptr[0]), ph, buf_offs, 3419 MaxPacketSize, tw); 3420 buf_offs += MaxPacketSize; 3421 td_count--; 3422 index++; 3423 } 3424 } 3425 3426 pp->pp_qh->bulk_xfer_info = bulk_xfer_info; 3427 bulk_xfer_info->num_tds = num_bulk_tds; 3428 SetQH32(uhcip, pp->pp_qh->element_ptr, 3429 bulk_xfer_info->td_pools[0].cookie.dmac_address); 3430 } else { 3431 usba_pipe_handle_data_t *usb_pp = pp->pp_pipe_handle; 3432 3433 pp->pp_qh->bulk_xfer_info = NULL; 3434 3435 if (tw->tw_bytes_pending) { 3436 /* Update the element pointer */ 3437 SetQH32(uhcip, pp->pp_qh->element_ptr, 3438 TD_PADDR(pp->pp_qh->td_tailp)); 3439 3440 /* Remove all the tds */ 3441 td_head = tw->tw_hctd_head; 3442 while (td_head != NULL) { 3443 uhci_delete_td(uhcip, td_head); 3444 td_head = tw->tw_hctd_head; 3445 } 3446 } 3447 3448 if (tw->tw_direction == PID_IN) { 3449 usb_req_attrs_t attrs = ((usb_bulk_req_t *) 3450 tw->tw_curr_xfer_reqp)->bulk_attributes; 3451 3452 error = USB_CR_OK; 3453 3454 /* Data run occurred */ 3455 if (tw->tw_bytes_pending && 3456 (!(attrs & USB_ATTRS_SHORT_XFER_OK))) { 3457 error = USB_CR_DATA_UNDERRUN; 3458 } 3459 3460 uhci_sendup_td_message(uhcip, error, tw); 3461 } else { 3462 uhci_do_byte_stats(uhcip, tw->tw_length, 3463 usb_pp->p_ep.bmAttributes, 3464 usb_pp->p_ep.bEndpointAddress); 3465 3466 /* Data underrun occurred */ 3467 if (tw->tw_bytes_pending) { 3468 3469 tw->tw_data->b_rptr += 3470 tw->tw_bytes_xfered; 3471 3472 USB_DPRINTF_L2(PRINT_MASK_ATTA, 3473 uhcip->uhci_log_hdl, 3474 "uhci_handle_bulk_td: " 3475 "data underrun occurred"); 3476 3477 uhci_hcdi_callback(uhcip, pp, 3478 tw->tw_pipe_private->pp_pipe_handle, 3479 tw, USB_CR_DATA_UNDERRUN); 3480 } else { 3481 uhci_hcdi_callback(uhcip, pp, 3482 tw->tw_pipe_private->pp_pipe_handle, 3483 tw, USB_CR_OK); 3484 } 3485 } /* direction */ 3486 3487 /* Deallocate DMA memory */ 3488 uhci_deallocate_tw(uhcip, pp, tw); 3489 for (j = 0; j < bulk_xfer_info->num_pools; j++) { 3490 td_pool_ptr = &bulk_xfer_info->td_pools[j]; 3491 (void) ddi_dma_unbind_handle( 3492 td_pool_ptr->dma_handle); 3493 ddi_dma_mem_free(&td_pool_ptr->mem_handle); 3494 ddi_dma_free_handle(&td_pool_ptr->dma_handle); 3495 } 3496 kmem_free(bulk_xfer_info->td_pools, 3497 (sizeof (uhci_bulk_isoc_td_pool_t) * 3498 bulk_xfer_info->num_pools)); 3499 kmem_free(bulk_xfer_info, 3500 sizeof (uhci_bulk_isoc_xfer_t)); 3501 3502 /* 3503 * When there are no pending bulk commands, point the 3504 * end of the lattice tree to NULL. This will make sure 3505 * that the HC control does not loop anymore and PCI 3506 * bus is not affected. 3507 */ 3508 if (--uhcip->uhci_pending_bulk_cmds == 0) { 3509 uhcip->uhci_bulk_xfers_q_tail->link_ptr = 3510 HC_END_OF_LIST; 3511 USB_DPRINTF_L3(PRINT_MASK_ATTA, 3512 uhcip->uhci_log_hdl, 3513 "uhci_handle_bulk_td: count = %d", 3514 uhcip->uhci_pending_bulk_cmds); 3515 } 3516 } 3517 } else { 3518 uhci_delete_td(uhcip, td); 3519 } 3520 } 3521 3522 3523 void 3524 uhci_handle_bulk_td_errors(uhci_state_t *uhcip, uhci_td_t *td) 3525 { 3526 usb_cr_t usb_err; 3527 uint32_t paddr_tail, element_ptr, paddr; 3528 uhci_td_t *next_td; 3529 uhci_pipe_private_t *pp; 3530 uhci_trans_wrapper_t *tw = td->tw; 3531 usba_pipe_handle_data_t *ph; 3532 uhci_bulk_isoc_td_pool_t *td_pool_ptr = NULL; 3533 3534 USB_DPRINTF_L2(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3535 "uhci_handle_bulk_td_errors: td = %p", (void *)td); 3536 3537 #ifdef DEBUG 3538 uhci_print_td(uhcip, td); 3539 #endif 3540 3541 tw = td->tw; 3542 ph = tw->tw_pipe_private->pp_pipe_handle; 3543 pp = (uhci_pipe_private_t *)ph->p_hcd_private; 3544 3545 /* 3546 * Find the type of error occurred and return the error 3547 * to the upper layer. And adjust the data toggle. 3548 */ 3549 element_ptr = GetQH32(uhcip, pp->pp_qh->element_ptr) & 3550 QH_ELEMENT_PTR_MASK; 3551 paddr_tail = TD_PADDR(pp->pp_qh->td_tailp); 3552 3553 /* 3554 * If a timeout occurs before a transfer has completed, 3555 * the timeout handler sets the CRC/Timeout bit and clears the Active 3556 * bit in the link_ptr for each td in the transfer. 3557 * It then waits (at least) 1 ms so that any tds the controller might 3558 * have been executing will have completed. 3559 * So at this point element_ptr will point to either: 3560 * 1) the next td for the transfer (which has not been executed, 3561 * and has the CRC/Timeout status bit set and Active bit cleared), 3562 * 2) the dummy td for this qh. 3563 * So if the element_ptr does not point to the dummy td, we know 3564 * it points to the next td that would have been executed. 3565 * That td has the data toggle we want to save. 3566 * All outstanding tds have been marked as CRC/Timeout, 3567 * so it doesn't matter which td we pass to uhci_parse_td_error 3568 * for the error status. 3569 */ 3570 if (element_ptr != paddr_tail) { 3571 paddr = (element_ptr & QH_ELEMENT_PTR_MASK); 3572 uhci_get_bulk_td_by_paddr(uhcip, pp->pp_qh->bulk_xfer_info, 3573 paddr, &td_pool_ptr); 3574 next_td = BULKTD_VADDR(td_pool_ptr, paddr); 3575 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3576 "uhci_handle_bulk_td_errors: next td = %p", 3577 (void *)next_td); 3578 3579 usb_err = uhci_parse_td_error(uhcip, pp, next_td); 3580 } else { 3581 usb_err = uhci_parse_td_error(uhcip, pp, td); 3582 } 3583 3584 /* 3585 * Update the link pointer. 3586 */ 3587 SetQH32(uhcip, pp->pp_qh->element_ptr, TD_PADDR(pp->pp_qh->td_tailp)); 3588 3589 /* 3590 * Send up number of bytes transferred before the error condition. 3591 */ 3592 if ((tw->tw_direction == PID_OUT) && tw->tw_data) { 3593 tw->tw_data->b_rptr += tw->tw_bytes_xfered; 3594 } 3595 3596 uhci_remove_bulk_tds_tws(uhcip, tw->tw_pipe_private, UHCI_IN_ERROR); 3597 3598 /* 3599 * When there are no pending bulk commands, point the end of the 3600 * lattice tree to NULL. This will make sure that the HC control 3601 * does not loop anymore and PCI bus is not affected. 3602 */ 3603 if (--uhcip->uhci_pending_bulk_cmds == 0) { 3604 uhcip->uhci_bulk_xfers_q_tail->link_ptr = HC_END_OF_LIST; 3605 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 3606 "uhci_handle_bulk_td_errors: count = %d", 3607 uhcip->uhci_pending_bulk_cmds); 3608 } 3609 3610 uhci_hcdi_callback(uhcip, pp, ph, tw, usb_err); 3611 uhci_deallocate_tw(uhcip, pp, tw); 3612 } 3613 3614 3615 /* 3616 * uhci_get_bulk_td_by_paddr: 3617 * Obtain the address of the TD pool the physical address falls in. 3618 * 3619 * td_pool_pp - pointer to the address of the TD pool containing the paddr 3620 */ 3621 /* ARGSUSED */ 3622 static void 3623 uhci_get_bulk_td_by_paddr( 3624 uhci_state_t *uhcip, 3625 uhci_bulk_isoc_xfer_t *info, 3626 uint32_t paddr, 3627 uhci_bulk_isoc_td_pool_t **td_pool_pp) 3628 { 3629 uint_t i = 0; 3630 3631 while (i < info->num_pools) { 3632 *td_pool_pp = &info->td_pools[i]; 3633 if (((*td_pool_pp)->cookie.dmac_address <= paddr) && 3634 (((*td_pool_pp)->cookie.dmac_address + 3635 (*td_pool_pp)->cookie.dmac_size) > paddr)) { 3636 3637 break; 3638 } 3639 i++; 3640 } 3641 3642 ASSERT(i < info->num_pools); 3643 } 3644 3645 3646 void 3647 uhci_remove_bulk_tds_tws( 3648 uhci_state_t *uhcip, 3649 uhci_pipe_private_t *pp, 3650 int what) 3651 { 3652 uint_t rval, i; 3653 uhci_td_t *head; 3654 uhci_td_t *head_next; 3655 usb_opaque_t curr_reqp; 3656 uhci_bulk_isoc_xfer_t *info; 3657 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 3658 3659 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 3660 3661 if ((info = pp->pp_qh->bulk_xfer_info) == NULL) { 3662 3663 return; 3664 } 3665 3666 head = uhcip->uhci_outst_tds_head; 3667 3668 while (head) { 3669 uhci_trans_wrapper_t *tw_tmp = head->tw; 3670 head_next = head->outst_td_next; 3671 3672 if (pp->pp_qh == tw_tmp->tw_pipe_private->pp_qh) { 3673 curr_reqp = tw_tmp->tw_curr_xfer_reqp; 3674 if (curr_reqp && 3675 ((what == UHCI_IN_CLOSE) || 3676 (what == UHCI_IN_RESET))) { 3677 uhci_hcdi_callback(uhcip, pp, 3678 pp->pp_pipe_handle, 3679 tw_tmp, USB_CR_FLUSHED); 3680 } /* end of curr_reqp */ 3681 3682 uhci_delete_td(uhcip, head); 3683 3684 if (what == UHCI_IN_CLOSE || what == UHCI_IN_RESET) { 3685 ASSERT(info->num_tds > 0); 3686 if (--info->num_tds == 0) { 3687 uhci_deallocate_tw(uhcip, pp, tw_tmp); 3688 3689 /* 3690 * This will make sure that the HC 3691 * does not loop anymore when there 3692 * are no pending bulk commands. 3693 */ 3694 if (--uhcip->uhci_pending_bulk_cmds 3695 == 0) { 3696 uhcip->uhci_bulk_xfers_q_tail-> 3697 link_ptr = HC_END_OF_LIST; 3698 USB_DPRINTF_L3(PRINT_MASK_ATTA, 3699 uhcip->uhci_log_hdl, 3700 "uhci_remove_bulk_tds_tws:" 3701 " count = %d", 3702 uhcip-> 3703 uhci_pending_bulk_cmds); 3704 } 3705 } 3706 } 3707 } 3708 3709 head = head_next; 3710 } 3711 3712 if (what == UHCI_IN_CLOSE || what == UHCI_IN_RESET) { 3713 ASSERT(info->num_tds == 0); 3714 } 3715 3716 for (i = 0; i < info->num_pools; i++) { 3717 td_pool_ptr = &info->td_pools[i]; 3718 rval = ddi_dma_unbind_handle(td_pool_ptr->dma_handle); 3719 ASSERT(rval == DDI_SUCCESS); 3720 ddi_dma_mem_free(&td_pool_ptr->mem_handle); 3721 ddi_dma_free_handle(&td_pool_ptr->dma_handle); 3722 } 3723 kmem_free(info->td_pools, (sizeof (uhci_bulk_isoc_td_pool_t) * 3724 info->num_pools)); 3725 kmem_free(info, sizeof (uhci_bulk_isoc_xfer_t)); 3726 pp->pp_qh->bulk_xfer_info = NULL; 3727 } 3728 3729 3730 /* 3731 * uhci_save_data_toggle () 3732 * Save the data toggle in the usba_device structure 3733 */ 3734 void 3735 uhci_save_data_toggle(uhci_pipe_private_t *pp) 3736 { 3737 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 3738 3739 /* Save the data toggle in the usb devices structure. */ 3740 mutex_enter(&ph->p_mutex); 3741 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress, 3742 pp->pp_data_toggle); 3743 mutex_exit(&ph->p_mutex); 3744 } 3745 3746 /* 3747 * uhci_create_isoc_transfer_wrapper: 3748 * Create a Transaction Wrapper (TW) for isoc transfer. 3749 * This involves the allocating of DMA resources. 3750 * 3751 * For isoc transfers, one isoc transfer includes multiple packets 3752 * and each packet may have a different length. So each packet is 3753 * transfered by one TD. We only know the individual packet length 3754 * won't exceed 1023 bytes, but we don't know exactly the lengths. 3755 * It is hard to make one physically discontiguous DMA buffer which 3756 * can fit in all the TDs like what can be done to the ctrl/bulk/ 3757 * intr transfers. It is also undesirable to make one physically 3758 * contiguous DMA buffer for all the packets, since this may easily 3759 * fail when the system is in low memory. So an individual DMA 3760 * buffer is allocated for an individual isoc packet and each DMA 3761 * buffer is physically contiguous. An extra structure is allocated 3762 * to save the multiple DMA handles. 3763 */ 3764 static uhci_trans_wrapper_t * 3765 uhci_create_isoc_transfer_wrapper( 3766 uhci_state_t *uhcip, 3767 uhci_pipe_private_t *pp, 3768 usb_isoc_req_t *req, 3769 size_t length, 3770 usb_flags_t usb_flags) 3771 { 3772 int result; 3773 size_t real_length, strtlen, xfer_size; 3774 uhci_trans_wrapper_t *tw; 3775 ddi_device_acc_attr_t dev_attr; 3776 ddi_dma_attr_t dma_attr; 3777 int kmem_flag; 3778 int (*dmamem_wait)(caddr_t); 3779 uint_t i, j, ccount; 3780 usb_isoc_req_t *tmp_req = req; 3781 3782 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 3783 3784 if (UHCI_XFER_TYPE(&pp->pp_pipe_handle->p_ep) != USB_EP_ATTR_ISOCH) { 3785 3786 return (NULL); 3787 } 3788 3789 if ((req == NULL) && (UHCI_XFER_DIR(&pp->pp_pipe_handle->p_ep) == 3790 USB_EP_DIR_IN)) { 3791 tmp_req = (usb_isoc_req_t *)pp->pp_client_periodic_in_reqp; 3792 } 3793 3794 if (tmp_req == NULL) { 3795 3796 return (NULL); 3797 } 3798 3799 3800 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3801 "uhci_create_isoc_transfer_wrapper: length = 0x%lx flags = 0x%x", 3802 length, usb_flags); 3803 3804 /* SLEEP flag should not be used in interrupt context */ 3805 if (servicing_interrupt()) { 3806 kmem_flag = KM_NOSLEEP; 3807 dmamem_wait = DDI_DMA_DONTWAIT; 3808 } else { 3809 kmem_flag = KM_SLEEP; 3810 dmamem_wait = DDI_DMA_SLEEP; 3811 } 3812 3813 /* Allocate space for the transfer wrapper */ 3814 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), kmem_flag)) == 3815 NULL) { 3816 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3817 "uhci_create_isoc_transfer_wrapper: kmem_alloc failed"); 3818 3819 return (NULL); 3820 } 3821 3822 /* Allocate space for the isoc buffer handles */ 3823 strtlen = sizeof (uhci_isoc_buf_t) * tmp_req->isoc_pkts_count; 3824 if ((tw->tw_isoc_bufs = kmem_zalloc(strtlen, kmem_flag)) == NULL) { 3825 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3826 "uhci_create_isoc_transfer_wrapper: kmem_alloc " 3827 "isoc buffer failed"); 3828 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 3829 3830 return (NULL); 3831 } 3832 3833 bcopy(&uhcip->uhci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t)); 3834 dma_attr.dma_attr_sgllen = 1; 3835 3836 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 3837 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 3838 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 3839 3840 /* Store the transfer length */ 3841 tw->tw_length = length; 3842 3843 for (i = 0; i < tmp_req->isoc_pkts_count; i++) { 3844 tw->tw_isoc_bufs[i].index = i; 3845 3846 /* Allocate the DMA handle */ 3847 if ((result = ddi_dma_alloc_handle(uhcip->uhci_dip, &dma_attr, 3848 dmamem_wait, 0, &tw->tw_isoc_bufs[i].dma_handle)) != 3849 DDI_SUCCESS) { 3850 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3851 "uhci_create_isoc_transfer_wrapper: " 3852 "Alloc handle %d failed", i); 3853 3854 for (j = 0; j < i; j++) { 3855 result = ddi_dma_unbind_handle( 3856 tw->tw_isoc_bufs[j].dma_handle); 3857 ASSERT(result == USB_SUCCESS); 3858 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 3859 mem_handle); 3860 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 3861 dma_handle); 3862 } 3863 kmem_free(tw->tw_isoc_bufs, strtlen); 3864 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 3865 3866 return (NULL); 3867 } 3868 3869 /* Allocate the memory */ 3870 xfer_size = tmp_req->isoc_pkt_descr[i].isoc_pkt_length; 3871 if ((result = ddi_dma_mem_alloc(tw->tw_isoc_bufs[i].dma_handle, 3872 xfer_size, &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, 3873 NULL, (caddr_t *)&tw->tw_isoc_bufs[i].buf_addr, 3874 &real_length, &tw->tw_isoc_bufs[i].mem_handle)) != 3875 DDI_SUCCESS) { 3876 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3877 "uhci_create_isoc_transfer_wrapper: " 3878 "dma_mem_alloc %d fail", i); 3879 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 3880 3881 for (j = 0; j < i; j++) { 3882 result = ddi_dma_unbind_handle( 3883 tw->tw_isoc_bufs[j].dma_handle); 3884 ASSERT(result == USB_SUCCESS); 3885 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 3886 mem_handle); 3887 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 3888 dma_handle); 3889 } 3890 kmem_free(tw->tw_isoc_bufs, strtlen); 3891 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 3892 3893 return (NULL); 3894 } 3895 3896 ASSERT(real_length >= xfer_size); 3897 3898 /* Bind the handle */ 3899 result = ddi_dma_addr_bind_handle( 3900 tw->tw_isoc_bufs[i].dma_handle, NULL, 3901 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, real_length, 3902 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, dmamem_wait, NULL, 3903 &tw->tw_isoc_bufs[i].cookie, &ccount); 3904 3905 if ((result == DDI_DMA_MAPPED) && (ccount == 1)) { 3906 tw->tw_isoc_bufs[i].length = xfer_size; 3907 3908 continue; 3909 } else { 3910 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3911 "uhci_create_isoc_transfer_wrapper: " 3912 "Bind handle %d failed", i); 3913 if (result == DDI_DMA_MAPPED) { 3914 result = ddi_dma_unbind_handle( 3915 tw->tw_isoc_bufs[i].dma_handle); 3916 ASSERT(result == USB_SUCCESS); 3917 } 3918 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle); 3919 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle); 3920 3921 for (j = 0; j < i; j++) { 3922 result = ddi_dma_unbind_handle( 3923 tw->tw_isoc_bufs[j].dma_handle); 3924 ASSERT(result == USB_SUCCESS); 3925 ddi_dma_mem_free(&tw->tw_isoc_bufs[j]. 3926 mem_handle); 3927 ddi_dma_free_handle(&tw->tw_isoc_bufs[j]. 3928 dma_handle); 3929 } 3930 kmem_free(tw->tw_isoc_bufs, strtlen); 3931 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 3932 3933 return (NULL); 3934 } 3935 } 3936 3937 tw->tw_ncookies = tmp_req->isoc_pkts_count; 3938 tw->tw_isoc_strtlen = strtlen; 3939 3940 /* 3941 * Only allow one wrapper to be added at a time. Insert the 3942 * new transaction wrapper into the list for this pipe. 3943 */ 3944 if (pp->pp_tw_head == NULL) { 3945 pp->pp_tw_head = tw; 3946 pp->pp_tw_tail = tw; 3947 } else { 3948 pp->pp_tw_tail->tw_next = tw; 3949 pp->pp_tw_tail = tw; 3950 ASSERT(tw->tw_next == NULL); 3951 } 3952 3953 /* Store a back pointer to the pipe private structure */ 3954 tw->tw_pipe_private = pp; 3955 3956 /* Store the transfer type - synchronous or asynchronous */ 3957 tw->tw_flags = usb_flags; 3958 3959 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 3960 "uhci_create_isoc_transfer_wrapper: tw = 0x%p, ncookies = %u", 3961 tw, tw->tw_ncookies); 3962 3963 return (tw); 3964 } 3965 3966 /* 3967 * uhci_insert_isoc_td: 3968 * - Create transfer wrapper 3969 * - Allocate memory for the isoc td's 3970 * - Fill up all the TD's and submit to the HC 3971 * - Update all the linked lists 3972 */ 3973 int 3974 uhci_insert_isoc_td( 3975 uhci_state_t *uhcip, 3976 usba_pipe_handle_data_t *ph, 3977 usb_isoc_req_t *isoc_req, 3978 size_t length, 3979 usb_flags_t flags) 3980 { 3981 int rval = USB_SUCCESS; 3982 int error; 3983 uint_t ddic; 3984 uint32_t i, j, index; 3985 uint32_t bytes_to_xfer; 3986 uint32_t expired_frames = 0; 3987 usb_frame_number_t start_frame, end_frame, current_frame; 3988 uhci_td_t *td_ptr; 3989 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 3990 uhci_trans_wrapper_t *tw; 3991 uhci_bulk_isoc_xfer_t *isoc_xfer_info; 3992 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 3993 3994 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 3995 "uhci_insert_isoc_td: ph = 0x%p isoc req = %p length = %lu", 3996 ph, (void *)isoc_req, length); 3997 3998 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 3999 4000 /* Allocate a transfer wrapper */ 4001 if ((tw = uhci_create_isoc_transfer_wrapper(uhcip, pp, isoc_req, 4002 length, flags)) == NULL) { 4003 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4004 "uhci_insert_isoc_td: TW allocation failed"); 4005 4006 return (USB_NO_RESOURCES); 4007 } 4008 4009 /* Save current isochronous request pointer */ 4010 tw->tw_curr_xfer_reqp = (usb_opaque_t)isoc_req; 4011 4012 /* 4013 * Initialize the transfer wrapper. These values are useful 4014 * for sending back the reply. 4015 */ 4016 tw->tw_handle_td = uhci_handle_isoc_td; 4017 tw->tw_handle_callback_value = NULL; 4018 tw->tw_direction = (UHCI_XFER_DIR(&ph->p_ep) == USB_EP_DIR_OUT) ? 4019 PID_OUT : PID_IN; 4020 4021 /* 4022 * If the transfer isoc send, then copy the data from the request 4023 * to the transfer wrapper. 4024 */ 4025 if ((tw->tw_direction == PID_OUT) && length) { 4026 uchar_t *p; 4027 4028 ASSERT(isoc_req->isoc_data != NULL); 4029 p = isoc_req->isoc_data->b_rptr; 4030 4031 /* Copy the data into the message */ 4032 for (i = 0; i < isoc_req->isoc_pkts_count; i++) { 4033 ddi_rep_put8(tw->tw_isoc_bufs[i].mem_handle, 4034 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr, 4035 isoc_req->isoc_pkt_descr[i].isoc_pkt_length, 4036 DDI_DEV_AUTOINCR); 4037 p += isoc_req->isoc_pkt_descr[i].isoc_pkt_length; 4038 } 4039 } 4040 4041 if (tw->tw_direction == PID_IN) { 4042 if ((rval = uhci_allocate_periodic_in_resource(uhcip, pp, tw, 4043 flags)) != USB_SUCCESS) { 4044 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4045 "uhci_insert_isoc_td: isoc_req_t alloc failed"); 4046 uhci_deallocate_tw(uhcip, pp, tw); 4047 4048 return (rval); 4049 } 4050 4051 isoc_req = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 4052 } 4053 4054 tw->tw_isoc_req = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp; 4055 4056 /* Get the pointer to the isoc_xfer_info structure */ 4057 isoc_xfer_info = (uhci_bulk_isoc_xfer_t *)&tw->tw_xfer_info; 4058 isoc_xfer_info->num_tds = isoc_req->isoc_pkts_count; 4059 4060 /* 4061 * Allocate memory for isoc tds 4062 */ 4063 if ((rval = uhci_alloc_bulk_isoc_tds(uhcip, isoc_req->isoc_pkts_count, 4064 isoc_xfer_info)) != USB_SUCCESS) { 4065 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4066 "uhci_alloc_bulk_isoc_td: Memory allocation failure"); 4067 4068 if (tw->tw_direction == PID_IN) { 4069 uhci_deallocate_periodic_in_resource(uhcip, pp, tw); 4070 } 4071 uhci_deallocate_tw(uhcip, pp, tw); 4072 4073 return (rval); 4074 } 4075 4076 /* 4077 * Get the isoc td pool address, buffer address and 4078 * max packet size that the device supports. 4079 */ 4080 td_pool_ptr = &isoc_xfer_info->td_pools[0]; 4081 td_ptr = (uhci_td_t *)td_pool_ptr->pool_addr; 4082 index = 0; 4083 4084 /* 4085 * Fill up the isoc tds 4086 */ 4087 USB_DPRINTF_L3(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4088 "uhci_insert_isoc_td : isoc pkts %d", isoc_req->isoc_pkts_count); 4089 4090 for (i = 0; i < isoc_xfer_info->num_pools; i++) { 4091 for (j = 0; j < td_pool_ptr->num_tds; j++) { 4092 bytes_to_xfer = 4093 isoc_req->isoc_pkt_descr[index].isoc_pkt_length; 4094 4095 uhci_fill_in_bulk_isoc_td(uhcip, &td_ptr[j], 4096 (uhci_td_t *)NULL, HC_END_OF_LIST, ph, index, 4097 bytes_to_xfer, tw); 4098 td_ptr[j].isoc_pkt_index = index; 4099 index++; 4100 } 4101 4102 if (i < (isoc_xfer_info->num_pools - 1)) { 4103 td_pool_ptr = &isoc_xfer_info->td_pools[i + 1]; 4104 td_ptr = (uhci_td_t *)td_pool_ptr->pool_addr; 4105 } 4106 } 4107 4108 /* 4109 * Get the starting frame number. 4110 * The client drivers sets the flag USB_ATTRS_ISOC_XFER_ASAP to inform 4111 * the HCD to care of starting frame number. 4112 * 4113 * Following code is very time critical. So, perform atomic execution. 4114 */ 4115 ddic = ddi_enter_critical(); 4116 current_frame = uhci_get_sw_frame_number(uhcip); 4117 4118 if (isoc_req->isoc_attributes & USB_ATTRS_ISOC_START_FRAME) { 4119 start_frame = isoc_req->isoc_frame_no; 4120 end_frame = start_frame + isoc_req->isoc_pkts_count; 4121 4122 /* Check available frames */ 4123 if ((end_frame - current_frame) < UHCI_MAX_ISOC_FRAMES) { 4124 if (current_frame > start_frame) { 4125 if ((current_frame + FRNUM_OFFSET) < 4126 end_frame) { 4127 expired_frames = current_frame + 4128 FRNUM_OFFSET - start_frame; 4129 start_frame = current_frame + 4130 FRNUM_OFFSET; 4131 } else { 4132 rval = USB_INVALID_START_FRAME; 4133 } 4134 } 4135 } else { 4136 rval = USB_INVALID_START_FRAME; 4137 } 4138 4139 } else if (isoc_req->isoc_attributes & USB_ATTRS_ISOC_XFER_ASAP) { 4140 start_frame = pp->pp_frame_num; 4141 4142 if (start_frame == INVALID_FRNUM) { 4143 start_frame = current_frame + FRNUM_OFFSET; 4144 } else if (current_frame > start_frame) { 4145 start_frame = current_frame + FRNUM_OFFSET; 4146 } 4147 4148 end_frame = start_frame + isoc_req->isoc_pkts_count; 4149 isoc_req->isoc_frame_no = start_frame; 4150 4151 } 4152 4153 if (rval != USB_SUCCESS) { 4154 4155 /* Exit the critical */ 4156 ddi_exit_critical(ddic); 4157 4158 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4159 "uhci_insert_isoc_td: Invalid starting frame number"); 4160 4161 if (tw->tw_direction == PID_IN) { 4162 uhci_deallocate_periodic_in_resource(uhcip, pp, tw); 4163 } 4164 4165 while (tw->tw_hctd_head) { 4166 uhci_delete_td(uhcip, tw->tw_hctd_head); 4167 } 4168 4169 for (i = 0; i < isoc_xfer_info->num_pools; i++) { 4170 td_pool_ptr = &isoc_xfer_info->td_pools[i]; 4171 error = ddi_dma_unbind_handle(td_pool_ptr->dma_handle); 4172 ASSERT(error == DDI_SUCCESS); 4173 ddi_dma_mem_free(&td_pool_ptr->mem_handle); 4174 ddi_dma_free_handle(&td_pool_ptr->dma_handle); 4175 } 4176 kmem_free(isoc_xfer_info->td_pools, 4177 (sizeof (uhci_bulk_isoc_td_pool_t) * 4178 isoc_xfer_info->num_pools)); 4179 4180 uhci_deallocate_tw(uhcip, pp, tw); 4181 4182 return (rval); 4183 } 4184 4185 for (i = 0; i < expired_frames; i++) { 4186 isoc_req->isoc_pkt_descr[i].isoc_pkt_status = 4187 USB_CR_NOT_ACCESSED; 4188 isoc_req->isoc_pkt_descr[i].isoc_pkt_actual_length = 4189 isoc_req->isoc_pkt_descr[i].isoc_pkt_length; 4190 uhci_get_isoc_td_by_index(uhcip, isoc_xfer_info, i, 4191 &td_ptr, &td_pool_ptr); 4192 uhci_delete_td(uhcip, td_ptr); 4193 --isoc_xfer_info->num_tds; 4194 } 4195 4196 /* 4197 * Add the TD's to the HC list 4198 */ 4199 start_frame = (start_frame & 0x3ff); 4200 for (; i < isoc_req->isoc_pkts_count; i++) { 4201 uhci_get_isoc_td_by_index(uhcip, isoc_xfer_info, i, 4202 &td_ptr, &td_pool_ptr); 4203 if (uhcip->uhci_isoc_q_tailp[start_frame]) { 4204 td_ptr->isoc_prev = 4205 uhcip->uhci_isoc_q_tailp[start_frame]; 4206 td_ptr->isoc_next = NULL; 4207 td_ptr->link_ptr = 4208 uhcip->uhci_isoc_q_tailp[start_frame]->link_ptr; 4209 uhcip->uhci_isoc_q_tailp[start_frame]->isoc_next = 4210 td_ptr; 4211 SetTD32(uhcip, 4212 uhcip->uhci_isoc_q_tailp[start_frame]->link_ptr, 4213 ISOCTD_PADDR(td_pool_ptr, td_ptr)); 4214 uhcip->uhci_isoc_q_tailp[start_frame] = td_ptr; 4215 } else { 4216 uhcip->uhci_isoc_q_tailp[start_frame] = td_ptr; 4217 td_ptr->isoc_next = NULL; 4218 td_ptr->isoc_prev = NULL; 4219 SetTD32(uhcip, td_ptr->link_ptr, 4220 GetFL32(uhcip, 4221 uhcip->uhci_frame_lst_tablep[start_frame])); 4222 SetFL32(uhcip, 4223 uhcip->uhci_frame_lst_tablep[start_frame], 4224 ISOCTD_PADDR(td_pool_ptr, td_ptr)); 4225 } 4226 td_ptr->starting_frame = start_frame; 4227 4228 if (++start_frame == NUM_FRAME_LST_ENTRIES) 4229 start_frame = 0; 4230 } 4231 4232 ddi_exit_critical(ddic); 4233 pp->pp_frame_num = end_frame; 4234 4235 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4236 "uhci_insert_isoc_td: current frame number 0x%llx, pipe frame num" 4237 " 0x%llx", current_frame, pp->pp_frame_num); 4238 4239 return (rval); 4240 } 4241 4242 4243 /* 4244 * uhci_get_isoc_td_by_index: 4245 * Obtain the addresses of the TD pool and the TD at the index. 4246 * 4247 * tdpp - pointer to the address of the TD at the isoc packet index 4248 * td_pool_pp - pointer to the address of the TD pool containing 4249 * the specified TD 4250 */ 4251 /* ARGSUSED */ 4252 static void 4253 uhci_get_isoc_td_by_index( 4254 uhci_state_t *uhcip, 4255 uhci_bulk_isoc_xfer_t *info, 4256 uint_t index, 4257 uhci_td_t **tdpp, 4258 uhci_bulk_isoc_td_pool_t **td_pool_pp) 4259 { 4260 uint_t i = 0, j = 0; 4261 uhci_td_t *td_ptr; 4262 4263 while (j < info->num_pools) { 4264 if ((i + info->td_pools[j].num_tds) <= index) { 4265 i += info->td_pools[j].num_tds; 4266 j++; 4267 } else { 4268 i = index - i; 4269 4270 break; 4271 } 4272 } 4273 4274 ASSERT(j < info->num_pools); 4275 *td_pool_pp = &info->td_pools[j]; 4276 td_ptr = (uhci_td_t *)((*td_pool_pp)->pool_addr); 4277 *tdpp = &td_ptr[i]; 4278 } 4279 4280 4281 /* 4282 * uhci_handle_isoc_td: 4283 * Handles the completed isoc tds 4284 */ 4285 void 4286 uhci_handle_isoc_td(uhci_state_t *uhcip, uhci_td_t *td) 4287 { 4288 uint_t rval, i; 4289 uint32_t pkt_index = td->isoc_pkt_index; 4290 usb_cr_t cr; 4291 uhci_trans_wrapper_t *tw = td->tw; 4292 usb_isoc_req_t *isoc_req = (usb_isoc_req_t *)tw->tw_isoc_req; 4293 uhci_pipe_private_t *pp = tw->tw_pipe_private; 4294 uhci_bulk_isoc_xfer_t *isoc_xfer_info = &tw->tw_xfer_info; 4295 usba_pipe_handle_data_t *usb_pp; 4296 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 4297 4298 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4299 "uhci_handle_isoc_td: td = 0x%p, pp = 0x%p, tw = 0x%p, req = 0x%p, " 4300 "index = %x", td, pp, tw, isoc_req, pkt_index); 4301 4302 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4303 4304 usb_pp = pp->pp_pipe_handle; 4305 4306 /* 4307 * Check whether there are any errors occurred. If so, update error 4308 * count and return it to the upper.But never return a non zero 4309 * completion reason. 4310 */ 4311 cr = USB_CR_OK; 4312 if (GetTD_status(uhcip, td) & TD_STATUS_MASK) { 4313 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4314 "uhci_handle_isoc_td: Error Occurred: TD Status = %x", 4315 GetTD_status(uhcip, td)); 4316 isoc_req->isoc_error_count++; 4317 } 4318 4319 if (isoc_req != NULL) { 4320 isoc_req->isoc_pkt_descr[pkt_index].isoc_pkt_status = cr; 4321 isoc_req->isoc_pkt_descr[pkt_index].isoc_pkt_actual_length = 4322 (GetTD_alen(uhcip, td) == ZERO_LENGTH) ? 0 : 4323 GetTD_alen(uhcip, td) + 1; 4324 } 4325 4326 uhci_delete_isoc_td(uhcip, td); 4327 4328 if (--isoc_xfer_info->num_tds != 0) { 4329 USB_DPRINTF_L3(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4330 "uhci_handle_isoc_td: Number of TDs %d", 4331 isoc_xfer_info->num_tds); 4332 4333 return; 4334 } 4335 4336 tw->tw_claim = UHCI_INTR_HDLR_CLAIMED; 4337 if (tw->tw_direction == PID_IN) { 4338 uhci_sendup_td_message(uhcip, cr, tw); 4339 4340 if ((uhci_handle_isoc_receive(uhcip, pp, tw)) != USB_SUCCESS) { 4341 USB_DPRINTF_L3(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4342 "uhci_handle_isoc_td: Drop message"); 4343 } 4344 4345 } else { 4346 /* update kstats only for OUT. sendup_td_msg() does it for IN */ 4347 uhci_do_byte_stats(uhcip, tw->tw_length, 4348 usb_pp->p_ep.bmAttributes, usb_pp->p_ep.bEndpointAddress); 4349 4350 uhci_hcdi_callback(uhcip, pp, usb_pp, tw, USB_CR_OK); 4351 } 4352 4353 for (i = 0; i < isoc_xfer_info->num_pools; i++) { 4354 td_pool_ptr = &isoc_xfer_info->td_pools[i]; 4355 rval = ddi_dma_unbind_handle(td_pool_ptr->dma_handle); 4356 ASSERT(rval == DDI_SUCCESS); 4357 ddi_dma_mem_free(&td_pool_ptr->mem_handle); 4358 ddi_dma_free_handle(&td_pool_ptr->dma_handle); 4359 } 4360 kmem_free(isoc_xfer_info->td_pools, 4361 (sizeof (uhci_bulk_isoc_td_pool_t) * 4362 isoc_xfer_info->num_pools)); 4363 uhci_deallocate_tw(uhcip, pp, tw); 4364 } 4365 4366 4367 /* 4368 * uhci_handle_isoc_receive: 4369 * - Sends the isoc data to the client 4370 * - Inserts another isoc receive request 4371 */ 4372 static int 4373 uhci_handle_isoc_receive( 4374 uhci_state_t *uhcip, 4375 uhci_pipe_private_t *pp, 4376 uhci_trans_wrapper_t *tw) 4377 { 4378 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4379 "uhci_handle_isoc_receive: tw = 0x%p", tw); 4380 4381 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4382 4383 /* 4384 * -- check for pipe state being polling before 4385 * inserting a new request. Check when is TD 4386 * de-allocation being done? (so we can reuse the same TD) 4387 */ 4388 if (uhci_start_isoc_receive_polling(uhcip, 4389 pp->pp_pipe_handle, (usb_isoc_req_t *)tw->tw_curr_xfer_reqp, 4390 0) != USB_SUCCESS) { 4391 USB_DPRINTF_L2(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4392 "uhci_handle_isoc_receive: receive polling failed"); 4393 4394 return (USB_FAILURE); 4395 } 4396 4397 return (USB_SUCCESS); 4398 } 4399 4400 4401 /* 4402 * uhci_delete_isoc_td: 4403 * - Delete from the outstanding command queue 4404 * - Delete from the tw queue 4405 * - Delete from the isoc queue 4406 * - Delete from the HOST CONTROLLER list 4407 */ 4408 static void 4409 uhci_delete_isoc_td(uhci_state_t *uhcip, uhci_td_t *td) 4410 { 4411 uint32_t starting_frame = td->starting_frame; 4412 4413 if ((td->isoc_next == NULL) && (td->isoc_prev == NULL)) { 4414 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[starting_frame], 4415 GetTD32(uhcip, td->link_ptr)); 4416 uhcip->uhci_isoc_q_tailp[starting_frame] = 0; 4417 } else if (td->isoc_next == NULL) { 4418 td->isoc_prev->link_ptr = td->link_ptr; 4419 td->isoc_prev->isoc_next = NULL; 4420 uhcip->uhci_isoc_q_tailp[starting_frame] = td->isoc_prev; 4421 } else if (td->isoc_prev == NULL) { 4422 td->isoc_next->isoc_prev = NULL; 4423 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[starting_frame], 4424 GetTD32(uhcip, td->link_ptr)); 4425 } else { 4426 td->isoc_prev->isoc_next = td->isoc_next; 4427 td->isoc_next->isoc_prev = td->isoc_prev; 4428 td->isoc_prev->link_ptr = td->link_ptr; 4429 } 4430 4431 uhci_delete_td(uhcip, td); 4432 } 4433 4434 4435 /* 4436 * uhci_send_isoc_receive 4437 * - Allocates usb_isoc_request 4438 * - Updates the isoc request 4439 * - Inserts the isoc td's into the HC processing list. 4440 */ 4441 int 4442 uhci_start_isoc_receive_polling( 4443 uhci_state_t *uhcip, 4444 usba_pipe_handle_data_t *ph, 4445 usb_isoc_req_t *isoc_req, 4446 usb_flags_t usb_flags) 4447 { 4448 int ii, error; 4449 size_t max_isoc_xfer_size, length, isoc_pkts_length; 4450 ushort_t isoc_pkt_count; 4451 uhci_pipe_private_t *pp = (uhci_pipe_private_t *)ph->p_hcd_private; 4452 usb_isoc_pkt_descr_t *isoc_pkt_descr; 4453 4454 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4455 "uhci_start_isoc_receive_polling: usb_flags = %x", usb_flags); 4456 4457 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4458 4459 max_isoc_xfer_size = ph->p_ep.wMaxPacketSize * UHCI_MAX_ISOC_PKTS; 4460 4461 if (isoc_req) { 4462 isoc_pkt_descr = isoc_req->isoc_pkt_descr; 4463 isoc_pkt_count = isoc_req->isoc_pkts_count; 4464 isoc_pkts_length = isoc_req->isoc_pkts_length; 4465 } else { 4466 isoc_pkt_descr = ((usb_isoc_req_t *) 4467 pp->pp_client_periodic_in_reqp)->isoc_pkt_descr; 4468 isoc_pkt_count = ((usb_isoc_req_t *) 4469 pp->pp_client_periodic_in_reqp)->isoc_pkts_count; 4470 isoc_pkts_length = ((usb_isoc_req_t *) 4471 pp->pp_client_periodic_in_reqp)->isoc_pkts_length; 4472 } 4473 4474 for (ii = 0, length = 0; ii < isoc_pkt_count; ii++) { 4475 length += isoc_pkt_descr->isoc_pkt_length; 4476 isoc_pkt_descr++; 4477 } 4478 4479 if ((isoc_pkts_length) && (isoc_pkts_length != length)) { 4480 4481 USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 4482 "uhci_start_isoc_receive_polling: isoc_pkts_length 0x%x " 4483 "is not equal to the sum of all pkt lengths 0x%x in " 4484 "an isoc request", isoc_pkts_length, length); 4485 4486 return (USB_FAILURE); 4487 } 4488 4489 /* Check the size of isochronous request */ 4490 if (length > max_isoc_xfer_size) { 4491 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4492 "uhci_start_isoc_receive_polling: " 4493 "Max isoc request size = %lx, Given isoc req size = %lx", 4494 max_isoc_xfer_size, length); 4495 4496 return (USB_FAILURE); 4497 } 4498 4499 /* Add the TD into the Host Controller's isoc list */ 4500 error = uhci_insert_isoc_td(uhcip, ph, isoc_req, length, usb_flags); 4501 4502 return (error); 4503 } 4504 4505 4506 /* 4507 * uhci_remove_isoc_tds_tws 4508 * This routine scans the pipe and removes all the td's 4509 * and transfer wrappers and deallocates the memory 4510 * associated with those td's and tw's. 4511 */ 4512 void 4513 uhci_remove_isoc_tds_tws(uhci_state_t *uhcip, uhci_pipe_private_t *pp) 4514 { 4515 uint_t rval, i; 4516 uhci_td_t *tmp_td, *td_head; 4517 usb_isoc_req_t *isoc_req; 4518 uhci_trans_wrapper_t *tmp_tw, *tw_head; 4519 uhci_bulk_isoc_xfer_t *isoc_xfer_info; 4520 uhci_bulk_isoc_td_pool_t *td_pool_ptr; 4521 4522 USB_DPRINTF_L4(PRINT_MASK_ISOC, uhcip->uhci_log_hdl, 4523 "uhci_remove_isoc_tds_tws: pp = %p", (void *)pp); 4524 4525 tw_head = pp->pp_tw_head; 4526 while (tw_head) { 4527 tmp_tw = tw_head; 4528 tw_head = tw_head->tw_next; 4529 td_head = tmp_tw->tw_hctd_head; 4530 if (tmp_tw->tw_direction == PID_IN) { 4531 uhci_deallocate_periodic_in_resource(uhcip, pp, 4532 tmp_tw); 4533 } else if (tmp_tw->tw_direction == PID_OUT) { 4534 uhci_hcdi_callback(uhcip, pp, pp->pp_pipe_handle, 4535 tmp_tw, USB_CR_FLUSHED); 4536 } 4537 4538 while (td_head) { 4539 tmp_td = td_head; 4540 td_head = td_head->tw_td_next; 4541 uhci_delete_isoc_td(uhcip, tmp_td); 4542 } 4543 4544 isoc_req = (usb_isoc_req_t *)tmp_tw->tw_isoc_req; 4545 if (isoc_req) { 4546 usb_free_isoc_req(isoc_req); 4547 } 4548 4549 ASSERT(tmp_tw->tw_hctd_head == NULL); 4550 4551 if (tmp_tw->tw_xfer_info.td_pools) { 4552 isoc_xfer_info = 4553 (uhci_bulk_isoc_xfer_t *)&tmp_tw->tw_xfer_info; 4554 for (i = 0; i < isoc_xfer_info->num_pools; i++) { 4555 td_pool_ptr = &isoc_xfer_info->td_pools[i]; 4556 rval = ddi_dma_unbind_handle( 4557 td_pool_ptr->dma_handle); 4558 ASSERT(rval == DDI_SUCCESS); 4559 ddi_dma_mem_free(&td_pool_ptr->mem_handle); 4560 ddi_dma_free_handle(&td_pool_ptr->dma_handle); 4561 } 4562 kmem_free(isoc_xfer_info->td_pools, 4563 (sizeof (uhci_bulk_isoc_td_pool_t) * 4564 isoc_xfer_info->num_pools)); 4565 } 4566 4567 uhci_deallocate_tw(uhcip, pp, tmp_tw); 4568 } 4569 } 4570 4571 4572 /* 4573 * uhci_isoc_update_sw_frame_number() 4574 * to avoid code duplication, call uhci_get_sw_frame_number() 4575 */ 4576 void 4577 uhci_isoc_update_sw_frame_number(uhci_state_t *uhcip) 4578 { 4579 (void) uhci_get_sw_frame_number(uhcip); 4580 } 4581 4582 4583 /* 4584 * uhci_get_sw_frame_number: 4585 * Hold the uhci_int_mutex before calling this routine. 4586 */ 4587 uint64_t 4588 uhci_get_sw_frame_number(uhci_state_t *uhcip) 4589 { 4590 uint64_t sw_frnum, hw_frnum, current_frnum; 4591 4592 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4593 4594 sw_frnum = uhcip->uhci_sw_frnum; 4595 hw_frnum = Get_OpReg16(FRNUM); 4596 4597 /* 4598 * Check bit 10 in the software counter and hardware frame counter. 4599 * If both are same, then don't increment the software frame counter 4600 * (Bit 10 of hw frame counter toggle for every 1024 frames) 4601 * The lower 11 bits of software counter contains the hardware frame 4602 * counter value. The MSB (bit 10) of software counter is incremented 4603 * for every 1024 frames either here or in get frame number routine. 4604 */ 4605 if ((sw_frnum & UHCI_BIT_10_MASK) == (hw_frnum & UHCI_BIT_10_MASK)) { 4606 /* The MSB of hw counter did not toggle */ 4607 current_frnum = ((sw_frnum & (SW_FRNUM_MASK)) | hw_frnum); 4608 } else { 4609 /* 4610 * The hw counter wrapped around. And the interrupt handler 4611 * did not get a chance to update the sw frame counter. 4612 * So, update the sw frame counter and return correct frame no. 4613 */ 4614 sw_frnum >>= UHCI_SIZE_OF_HW_FRNUM - 1; 4615 current_frnum = 4616 ((++sw_frnum << (UHCI_SIZE_OF_HW_FRNUM - 1)) | hw_frnum); 4617 } 4618 uhcip->uhci_sw_frnum = current_frnum; 4619 4620 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 4621 "uhci_get_sw_frame_number: sw=%ld hd=%ld", 4622 uhcip->uhci_sw_frnum, hw_frnum); 4623 4624 return (current_frnum); 4625 } 4626 4627 4628 /* 4629 * uhci_cmd_timeout_hdlr: 4630 * This routine will get called for every second. It checks for 4631 * timed out control commands/bulk commands. Timeout any commands 4632 * that exceeds the time out period specified by the pipe policy. 4633 */ 4634 void 4635 uhci_cmd_timeout_hdlr(void *arg) 4636 { 4637 uint_t flag = B_FALSE; 4638 uhci_td_t *head, *tmp_td; 4639 uhci_state_t *uhcip = (uhci_state_t *)arg; 4640 uhci_pipe_private_t *pp; 4641 4642 /* 4643 * Check whether any of the control xfers are timed out. 4644 * If so, complete those commands with time out as reason. 4645 */ 4646 mutex_enter(&uhcip->uhci_int_mutex); 4647 head = uhcip->uhci_outst_tds_head; 4648 4649 while (head) { 4650 /* 4651 * If timeout out is zero, then dont timeout command. 4652 */ 4653 if (head->tw->tw_timeout_cnt == 0) { 4654 head = head->outst_td_next; 4655 continue; 4656 } 4657 4658 if (!(head->tw->tw_flags & TW_TIMEOUT_FLAG)) { 4659 head->tw->tw_flags |= TW_TIMEOUT_FLAG; 4660 --head->tw->tw_timeout_cnt; 4661 } 4662 4663 /* only do it for bulk and control TDs */ 4664 if ((head->tw->tw_timeout_cnt == 0) && 4665 (head->tw->tw_handle_td != uhci_handle_isoc_td)) { 4666 4667 USB_DPRINTF_L3(PRINT_MASK_ATTA, uhcip->uhci_log_hdl, 4668 "Command timed out: td = %p", (void *)head); 4669 4670 head->tw->tw_claim = UHCI_TIMEOUT_HDLR_CLAIMED; 4671 4672 /* 4673 * Check finally whether the command completed 4674 */ 4675 if (GetTD_status(uhcip, head) & UHCI_TD_ACTIVE) { 4676 SetTD32(uhcip, head->link_ptr, 4677 GetTD32(uhcip, head->link_ptr) | 4678 HC_END_OF_LIST); 4679 pp = head->tw->tw_pipe_private; 4680 SetQH32(uhcip, pp->pp_qh->element_ptr, 4681 GetQH32(uhcip, pp->pp_qh->element_ptr) | 4682 HC_END_OF_LIST); 4683 } 4684 4685 flag = B_TRUE; 4686 } 4687 4688 head = head->outst_td_next; 4689 } 4690 4691 if (flag) { 4692 (void) uhci_wait_for_sof(uhcip); 4693 } 4694 4695 head = uhcip->uhci_outst_tds_head; 4696 while (head) { 4697 if (head->tw->tw_flags & TW_TIMEOUT_FLAG) { 4698 head->tw->tw_flags &= ~TW_TIMEOUT_FLAG; 4699 } 4700 if (head->tw->tw_claim == UHCI_TIMEOUT_HDLR_CLAIMED) { 4701 head->tw->tw_claim = UHCI_NOT_CLAIMED; 4702 tmp_td = head->tw->tw_hctd_head; 4703 while (tmp_td) { 4704 SetTD_status(uhcip, tmp_td, 4705 UHCI_TD_CRC_TIMEOUT); 4706 tmp_td = tmp_td->tw_td_next; 4707 } 4708 } 4709 head = head->outst_td_next; 4710 } 4711 4712 /* 4713 * Process the td which was completed before shifting from normal 4714 * mode to polled mode 4715 */ 4716 if (uhcip->uhci_polled_flag == UHCI_POLLED_FLAG_TRUE) { 4717 uhci_process_submitted_td_queue(uhcip); 4718 uhcip->uhci_polled_flag = UHCI_POLLED_FLAG_FALSE; 4719 } else if (flag) { 4720 /* Process the completed/timed out commands */ 4721 uhci_process_submitted_td_queue(uhcip); 4722 } 4723 4724 /* Re-register the control/bulk/intr commands' timeout handler */ 4725 if (uhcip->uhci_cmd_timeout_id) { 4726 uhcip->uhci_cmd_timeout_id = timeout(uhci_cmd_timeout_hdlr, 4727 (void *)uhcip, UHCI_ONE_SECOND); 4728 } 4729 4730 mutex_exit(&uhcip->uhci_int_mutex); 4731 } 4732 4733 4734 /* 4735 * uhci_wait_for_sof: 4736 * Wait for the start of the next frame (implying any changes made in the 4737 * lattice have now taken effect). 4738 * To be sure this is the case, we wait for the completion of the current 4739 * frame (which might have already been pending), then another complete 4740 * frame to ensure everything has taken effect. 4741 */ 4742 int 4743 uhci_wait_for_sof(uhci_state_t *uhcip) 4744 { 4745 int n; 4746 ushort_t cmd_reg; 4747 usb_frame_number_t before_frame_number, after_frame_number; 4748 clock_t time, rval; 4749 USB_DPRINTF_L4(PRINT_MASK_LISTS, uhcip->uhci_log_hdl, 4750 "uhci_wait_for_sof: uhcip = %p", uhcip); 4751 4752 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4753 before_frame_number = uhci_get_sw_frame_number(uhcip); 4754 for (n = 0; n < MAX_SOF_WAIT_COUNT; n++) { 4755 SetTD_ioc(uhcip, uhcip->uhci_sof_td, 1); 4756 uhcip->uhci_cv_signal = B_TRUE; 4757 4758 time = ddi_get_lbolt() + UHCI_ONE_SECOND; 4759 rval = cv_timedwait(&uhcip->uhci_cv_SOF, 4760 &uhcip->uhci_int_mutex, time); 4761 4762 after_frame_number = uhci_get_sw_frame_number(uhcip); 4763 if ((rval == -1) && 4764 (after_frame_number <= before_frame_number)) { 4765 cmd_reg = Get_OpReg16(USBCMD); 4766 Set_OpReg16(USBCMD, (cmd_reg | USBCMD_REG_HC_RUN)); 4767 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 4768 after_frame_number = uhci_get_sw_frame_number(uhcip); 4769 } 4770 before_frame_number = after_frame_number; 4771 } 4772 4773 SetTD_ioc(uhcip, uhcip->uhci_sof_td, 0); 4774 4775 return (uhcip->uhci_cv_signal ? USB_FAILURE : USB_SUCCESS); 4776 4777 } 4778 4779 /* 4780 * uhci_allocate_periodic_in_resource: 4781 * Allocate interrupt/isochronous request structure for the 4782 * interrupt/isochronous IN transfer. 4783 */ 4784 int 4785 uhci_allocate_periodic_in_resource( 4786 uhci_state_t *uhcip, 4787 uhci_pipe_private_t *pp, 4788 uhci_trans_wrapper_t *tw, 4789 usb_flags_t flags) 4790 { 4791 size_t length = 0; 4792 usb_opaque_t client_periodic_in_reqp; 4793 usb_intr_req_t *cur_intr_req; 4794 usb_isoc_req_t *curr_isoc_reqp; 4795 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 4796 4797 USB_DPRINTF_L4(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4798 "uhci_allocate_periodic_in_resource:\n\t" 4799 "ph = 0x%p, pp = 0x%p, tw = 0x%p, flags = 0x%x", ph, pp, tw, flags); 4800 4801 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4802 4803 /* Check the current periodic in request pointer */ 4804 if (tw->tw_curr_xfer_reqp) { 4805 USB_DPRINTF_L2(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4806 "uhci_allocate_periodic_in_resource: Interrupt " 4807 "request structure already exists: " 4808 "allocation failed"); 4809 4810 return (USB_SUCCESS); 4811 } 4812 4813 /* Get the client periodic in request pointer */ 4814 client_periodic_in_reqp = pp->pp_client_periodic_in_reqp; 4815 4816 /* 4817 * If it a periodic IN request and periodic request is NULL, 4818 * allocate corresponding usb periodic IN request for the 4819 * current periodic polling request and copy the information 4820 * from the saved periodic request structure. 4821 */ 4822 if (UHCI_XFER_TYPE(&ph->p_ep) == USB_EP_ATTR_INTR) { 4823 /* Get the interrupt transfer length */ 4824 length = ((usb_intr_req_t *)client_periodic_in_reqp)-> 4825 intr_len; 4826 4827 cur_intr_req = usba_hcdi_dup_intr_req(ph->p_dip, 4828 (usb_intr_req_t *)client_periodic_in_reqp, length, flags); 4829 if (cur_intr_req == NULL) { 4830 USB_DPRINTF_L2(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4831 "uhci_allocate_periodic_in_resource: Interrupt " 4832 "request structure allocation failed"); 4833 4834 return (USB_NO_RESOURCES); 4835 } 4836 4837 /* Check and save the timeout value */ 4838 tw->tw_timeout_cnt = (cur_intr_req->intr_attributes & 4839 USB_ATTRS_ONE_XFER) ? cur_intr_req->intr_timeout: 0; 4840 tw->tw_curr_xfer_reqp = (usb_opaque_t)cur_intr_req; 4841 tw->tw_length = cur_intr_req->intr_len; 4842 } else { 4843 ASSERT(client_periodic_in_reqp != NULL); 4844 4845 if ((curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip, 4846 (usb_isoc_req_t *)client_periodic_in_reqp, flags)) == 4847 NULL) { 4848 USB_DPRINTF_L2(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4849 "uhci_allocate_periodic_in_resource: Isochronous " 4850 "request structure allocation failed"); 4851 4852 return (USB_NO_RESOURCES); 4853 } 4854 4855 /* 4856 * Save the client's isochronous request pointer and 4857 * length of isochronous transfer in transfer wrapper. 4858 * The dup'ed request is saved in pp_client_periodic_in_reqp 4859 */ 4860 tw->tw_curr_xfer_reqp = 4861 (usb_opaque_t)pp->pp_client_periodic_in_reqp; 4862 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp; 4863 } 4864 4865 mutex_enter(&ph->p_mutex); 4866 ph->p_req_count++; 4867 mutex_exit(&ph->p_mutex); 4868 4869 return (USB_SUCCESS); 4870 } 4871 4872 4873 /* 4874 * uhci_deallocate_periodic_in_resource: 4875 * Deallocate interrupt/isochronous request structure for the 4876 * interrupt/isochronous IN transfer. 4877 */ 4878 void 4879 uhci_deallocate_periodic_in_resource( 4880 uhci_state_t *uhcip, 4881 uhci_pipe_private_t *pp, 4882 uhci_trans_wrapper_t *tw) 4883 { 4884 usb_opaque_t curr_xfer_reqp; 4885 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle; 4886 4887 USB_DPRINTF_L4(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4888 "uhci_deallocate_periodic_in_resource: " 4889 "pp = 0x%p tw = 0x%p", pp, tw); 4890 4891 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4892 4893 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 4894 if (curr_xfer_reqp) { 4895 /* 4896 * Reset periodic in request usb isoch 4897 * packet request pointers to null. 4898 */ 4899 tw->tw_curr_xfer_reqp = NULL; 4900 tw->tw_isoc_req = NULL; 4901 4902 mutex_enter(&ph->p_mutex); 4903 ph->p_req_count--; 4904 mutex_exit(&ph->p_mutex); 4905 4906 /* 4907 * Free pre-allocated interrupt or isochronous requests. 4908 */ 4909 switch (UHCI_XFER_TYPE(&ph->p_ep)) { 4910 case USB_EP_ATTR_INTR: 4911 usb_free_intr_req((usb_intr_req_t *)curr_xfer_reqp); 4912 break; 4913 case USB_EP_ATTR_ISOCH: 4914 usb_free_isoc_req((usb_isoc_req_t *)curr_xfer_reqp); 4915 break; 4916 } 4917 } 4918 } 4919 4920 4921 /* 4922 * uhci_hcdi_callback() 4923 * convenience wrapper around usba_hcdi_callback() 4924 */ 4925 void 4926 uhci_hcdi_callback(uhci_state_t *uhcip, uhci_pipe_private_t *pp, 4927 usba_pipe_handle_data_t *ph, uhci_trans_wrapper_t *tw, usb_cr_t cr) 4928 { 4929 usb_opaque_t curr_xfer_reqp; 4930 4931 USB_DPRINTF_L4(PRINT_MASK_HCDI, uhcip->uhci_log_hdl, 4932 "uhci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x", ph, tw, cr); 4933 4934 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 4935 4936 if (tw && tw->tw_curr_xfer_reqp) { 4937 curr_xfer_reqp = tw->tw_curr_xfer_reqp; 4938 tw->tw_curr_xfer_reqp = NULL; 4939 tw->tw_isoc_req = NULL; 4940 } else { 4941 ASSERT(pp->pp_client_periodic_in_reqp != NULL); 4942 4943 curr_xfer_reqp = pp->pp_client_periodic_in_reqp; 4944 pp->pp_client_periodic_in_reqp = NULL; 4945 } 4946 4947 ASSERT(curr_xfer_reqp != NULL); 4948 4949 mutex_exit(&uhcip->uhci_int_mutex); 4950 usba_hcdi_cb(ph, curr_xfer_reqp, cr); 4951 mutex_enter(&uhcip->uhci_int_mutex); 4952 } 4953 4954 4955 #ifdef DEBUG 4956 static void 4957 uhci_print_td(uhci_state_t *uhcip, uhci_td_t *td) 4958 { 4959 uint_t *ptr = (uint_t *)td; 4960 4961 #ifndef lint 4962 _NOTE(NO_COMPETING_THREADS_NOW); 4963 #endif 4964 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4965 "\tDWORD 1 0x%x\t DWORD 2 0x%x", ptr[0], ptr[1]); 4966 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4967 "\tDWORD 3 0x%x\t DWORD 4 0x%x", ptr[2], ptr[3]); 4968 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4969 "\tBytes xfered = %d", td->tw->tw_bytes_xfered); 4970 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4971 "\tBytes Pending = %d", td->tw->tw_bytes_pending); 4972 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4973 "Queue Head Details:"); 4974 uhci_print_qh(uhcip, td->tw->tw_pipe_private->pp_qh); 4975 4976 #ifndef lint 4977 _NOTE(COMPETING_THREADS_NOW); 4978 #endif 4979 } 4980 4981 4982 static void 4983 uhci_print_qh(uhci_state_t *uhcip, queue_head_t *qh) 4984 { 4985 uint_t *ptr = (uint_t *)qh; 4986 4987 USB_DPRINTF_L3(PRINT_MASK_DUMPING, uhcip->uhci_log_hdl, 4988 "\tLink Ptr = %x Element Ptr = %x", ptr[0], ptr[1]); 4989 } 4990 #endif 4991