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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * This module contains the specific uhci code used in POLLED mode. 31 */ 32 #include <sys/usb/hcd/uhci/uhcid.h> 33 #include <sys/usb/hcd/uhci/uhcipolled.h> 34 35 #ifndef __sparc 36 extern void invalidate_cache(); 37 #endif 38 /* 39 * Internal Function Prototypes 40 */ 41 /* Polled initialization routine */ 42 static int uhci_polled_init(usba_pipe_handle_data_t *, uhci_state_t *, 43 usb_console_info_impl_t *); 44 45 /* Polled fini routine */ 46 static int uhci_polled_fini(uhci_polled_t *, uhci_state_t *); 47 48 /* Polled save state routine */ 49 static void uhci_polled_save_state(uhci_polled_t *); 50 51 /* Polled restore state routine */ 52 static void uhci_polled_restore_state(uhci_polled_t *); 53 54 /* Polled read routines */ 55 static int uhci_polled_insert_td_on_qh(uhci_polled_t *, 56 usba_pipe_handle_data_t *); 57 static uhci_trans_wrapper_t 58 *uhci_polled_create_tw(uhci_state_t *); 59 60 61 /* 62 * POLLED entry points 63 * 64 * These functions are entry points into the POLLED code. 65 */ 66 67 /* 68 * uhci_hcdi_polled_input_init: 69 * This is the initialization routine for handling the USB keyboard 70 * in POLLED mode. This routine is not called from POLLED mode, so 71 * it is OK to acquire mutexes. 72 */ 73 int 74 uhci_hcdi_polled_input_init(usba_pipe_handle_data_t *ph, 75 uchar_t **polled_buf, 76 usb_console_info_impl_t *console_input_info) 77 { 78 int ret; 79 uhci_polled_t *uhci_polledp; 80 uhci_state_t *uhcip; 81 82 uhcip = uhci_obtain_state(ph->p_usba_device->usb_root_hub_dip); 83 84 /* 85 * Grab the uhci_int_mutex so that things don't change on us 86 * if an interrupt comes in. 87 */ 88 mutex_enter(&uhcip->uhci_int_mutex); 89 ret = uhci_polled_init(ph, uhcip, console_input_info); 90 if (ret != USB_SUCCESS) { 91 mutex_exit(&uhcip->uhci_int_mutex); 92 93 return (ret); 94 } 95 96 uhci_polledp = (uhci_polled_t *)console_input_info->uci_private; 97 /* 98 * Mark the structure so that if we are using it, we don't free 99 * the structures if one of them is unplugged. 100 */ 101 uhci_polledp->uhci_polled_flags |= POLLED_INPUT_MODE; 102 103 /* 104 * This is the buffer we will copy characters into. It will be 105 * copied into at this layer, so we need to keep track of it. 106 */ 107 uhci_polledp->uhci_polled_buf = 108 (uchar_t *)kmem_zalloc(POLLED_RAW_BUF_SIZE, KM_SLEEP); 109 110 *polled_buf = uhci_polledp->uhci_polled_buf; 111 112 mutex_exit(&uhcip->uhci_int_mutex); 113 return (USB_SUCCESS); 114 } 115 116 117 /* 118 * uhci_hcdi_polled_input_fini: 119 */ 120 int 121 uhci_hcdi_polled_input_fini(usb_console_info_impl_t *info) 122 { 123 int ret; 124 uhci_state_t *uhcip; 125 uhci_polled_t *uhci_polledp; 126 127 uhci_polledp = (uhci_polled_t *)info->uci_private; 128 uhcip = uhci_polledp->uhci_polled_uhcip; 129 mutex_enter(&uhcip->uhci_int_mutex); 130 131 /* Free the buffer that we copied data into */ 132 kmem_free(uhci_polledp->uhci_polled_buf, POLLED_RAW_BUF_SIZE); 133 ret = uhci_polled_fini(uhci_polledp, uhcip); 134 info->uci_private = NULL; 135 mutex_exit(&uhcip->uhci_int_mutex); 136 137 return (ret); 138 } 139 140 141 /* 142 * uhci_hcdi_polled_input_enter: 143 * This is where we enter into POLLED mode. This routine sets up 144 * everything so that calls to uhci_hcdi_polled_read will return 145 * characters. 146 */ 147 int 148 uhci_hcdi_polled_input_enter(usb_console_info_impl_t *info) 149 { 150 uhci_polled_t *uhci_polledp; 151 152 uhci_polledp = (uhci_polled_t *)info->uci_private; 153 uhci_polledp->uhci_polled_entry++; 154 155 /* 156 * If the controller is already switched over, just return 157 */ 158 if (uhci_polledp->uhci_polled_entry > 1) { 159 160 return (USB_SUCCESS); 161 } 162 163 uhci_polled_save_state(uhci_polledp); 164 uhci_polledp->uhci_polled_flags |= POLLED_INPUT_MODE_INUSE; 165 166 return (USB_SUCCESS); 167 } 168 169 170 /* 171 * uhci_hcdi_polled_input_exit: 172 * This is where we exit POLLED mode. This routine restores 173 * everything that is needed to continue operation. 174 */ 175 int 176 uhci_hcdi_polled_input_exit(usb_console_info_impl_t *info) 177 { 178 uhci_polled_t *uhci_polledp; 179 180 uhci_polledp = (uhci_polled_t *)info->uci_private; 181 uhci_polledp->uhci_polled_entry--; 182 183 /* 184 * If there are still outstanding "enters", just return 185 */ 186 if (uhci_polledp->uhci_polled_entry > 0) { 187 188 return (USB_SUCCESS); 189 } 190 191 uhci_polledp->uhci_polled_flags &= ~POLLED_INPUT_MODE_INUSE; 192 uhci_polled_restore_state(uhci_polledp); 193 194 return (USB_SUCCESS); 195 } 196 197 198 /* 199 * uhci_hcdi_polled_read: 200 * Get a key character 201 */ 202 int 203 uhci_hcdi_polled_read(usb_console_info_impl_t *info, uint_t *num_characters) 204 { 205 uhci_state_t *uhcip; 206 uhci_polled_t *uhci_polledp; 207 uhci_td_t *td; 208 uhci_trans_wrapper_t *tw; 209 ushort_t intr_status; 210 211 uhci_polledp = (uhci_polled_t *)info->uci_private; 212 uhcip = uhci_polledp->uhci_polled_uhcip; 213 214 /* 215 * This is a temporary work around for halt problem. The upper 216 * layer code does not call the right sequence of entry points 217 * points for reading a character in a polled mode. Once the 218 * upper layer code is fixed, the following code (two lines) 219 * must be removed. 220 */ 221 if (uhci_polledp->uhci_polled_entry == 0) { 222 if (uhci_hcdi_polled_input_enter(info) != USB_SUCCESS) { 223 cmn_err(CE_WARN, "Entering Polled Mode failed"); 224 } 225 } 226 227 #ifndef lint 228 _NOTE(NO_COMPETING_THREADS_NOW); 229 #endif 230 #ifndef __sparc 231 invalidate_cache(); 232 #endif 233 234 td = uhci_polledp->uhci_polled_td; 235 236 /* 237 * Check to see if there are any TD's on the done head. 238 */ 239 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 240 *num_characters = 0; 241 } else { 242 243 /* 244 * If the TD does not complete, retry. 245 */ 246 if ((GetTD_status(uhcip, td) & TD_STATUS_MASK) || 247 (GetTD_alen(uhcip, td) == ZERO_LENGTH)) { 248 *num_characters = 0; 249 SetTD_alen(uhcip, td, 0); 250 } else { 251 *num_characters = GetTD_alen(uhcip, td) + 1; 252 253 tw = td->tw; 254 255 /* Copy the data into the message */ 256 ddi_rep_get8(tw->tw_accesshandle, 257 (uint8_t *)uhci_polledp->uhci_polled_buf, 258 (uint8_t *)td->tw->tw_buf, 259 *num_characters, 260 DDI_DEV_AUTOINCR); 261 } 262 263 /* 264 * Insert the td again into the lattice. 265 */ 266 SetTD_dtogg(uhcip, td, GetTD_dtogg(uhcip, td) == 0 ? 1 : 0); 267 268 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 269 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, 270 TD_PADDR(td)); 271 272 /* Clear the interrupt status register */ 273 intr_status = Get_OpReg16(USBSTS); 274 Set_OpReg16(USBSTS, intr_status); 275 } 276 277 #ifndef lint 278 _NOTE(COMPETING_THREADS_NOW); 279 #endif 280 281 return (USB_SUCCESS); 282 } 283 284 285 /* 286 * uhci_polled_init: 287 * Initialize generic information that is needed to provide USB/POLLED 288 * support. 289 */ 290 static int 291 uhci_polled_init(usba_pipe_handle_data_t *ph, 292 uhci_state_t *uhcip, 293 usb_console_info_impl_t *console_info) 294 { 295 uhci_polled_t *uhci_polledp; 296 297 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 298 299 /* 300 * If the structure has already been initialized, then we don't 301 * need to redo it. 302 */ 303 if (console_info->uci_private != NULL) { 304 305 return (USB_SUCCESS); 306 } 307 308 /* Allocate and intitialize a polled mode state structure */ 309 uhci_polledp = (uhci_polled_t *)kmem_zalloc(sizeof (uhci_polled_t), 310 KM_SLEEP); 311 312 /* 313 * Keep a copy of normal mode state structure and pipe handle. 314 */ 315 uhci_polledp->uhci_polled_uhcip = uhcip; 316 uhci_polledp->uhci_polled_ph = ph; 317 318 /* 319 * Allocate a queue head for the device. This queue head wiil be 320 * put in action when we switch to polled mode in _enter point. 321 */ 322 uhci_polledp->uhci_polled_qh = uhci_alloc_queue_head(uhcip); 323 324 if (uhci_polledp->uhci_polled_qh == NULL) { 325 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 326 327 return (USB_NO_RESOURCES); 328 } 329 330 /* 331 * Insert a TD onto the queue head. 332 */ 333 if ((uhci_polled_insert_td_on_qh(uhci_polledp, 334 uhci_polledp->uhci_polled_ph)) != USB_SUCCESS) { 335 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 336 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 337 338 return (USB_NO_RESOURCES); 339 } 340 341 console_info->uci_private = (usb_console_info_private_t)uhci_polledp; 342 343 return (USB_SUCCESS); 344 } 345 346 347 /* 348 * uhci_polled_fini: 349 */ 350 static int 351 uhci_polled_fini(uhci_polled_t *uhci_polledp, uhci_state_t *uhcip) 352 { 353 uhci_td_t *td = uhci_polledp->uhci_polled_td; 354 355 ASSERT(mutex_owned(&uhcip->uhci_int_mutex)); 356 357 /* 358 * Free the transfer wrapper 359 */ 360 uhci_free_tw(uhcip, td->tw); 361 362 /* 363 * Free the queue head and transfer descriptor allocated. 364 */ 365 uhci_polledp->uhci_polled_qh->qh_flag = QUEUE_HEAD_FLAG_FREE; 366 uhci_polledp->uhci_polled_td->flag = TD_FLAG_FREE; 367 368 /* 369 * Deallocate the memory for the polled mode state structure. 370 */ 371 kmem_free(uhci_polledp, sizeof (uhci_polled_t)); 372 373 return (USB_SUCCESS); 374 } 375 376 377 /* 378 * uhci_polled_save_state: 379 */ 380 static void 381 uhci_polled_save_state(uhci_polled_t *uhci_polledp) 382 { 383 int i; 384 uhci_td_t *td, *polled_td; 385 uhci_state_t *uhcip; 386 usba_pipe_handle_data_t *ph; 387 388 #ifndef lint 389 _NOTE(NO_COMPETING_THREADS_NOW); 390 #endif 391 392 /* 393 * If either of these two flags are set, then we have already 394 * saved off the state information and setup the controller. 395 */ 396 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 397 #ifndef lint 398 _NOTE(COMPETING_THREADS_NOW); 399 #endif 400 401 return; 402 } 403 404 uhcip = uhci_polledp->uhci_polled_uhcip; 405 406 /* 407 * Check if the number of keyboard reaches the max number we can 408 * support in polled mode 409 */ 410 if (++ uhcip->uhci_polled_count > MAX_NUM_FOR_KEYBORAD) { 411 #ifndef lint 412 _NOTE(COMPETING_THREADS_NOW); 413 #endif 414 return; 415 } 416 417 /* 418 * Get the normal mode usb pipe handle. 419 */ 420 ph = (usba_pipe_handle_data_t *)uhci_polledp->uhci_polled_ph; 421 /* 422 * Only the first keyboard enter disable the interrutps, stop the 423 * host controller processing and initialize the interrupt table. 424 */ 425 if (uhcip->uhci_polled_count == 1) { 426 /* 427 * Disable interrupts to prevent the interrupt handler getting 428 * called while we are switing to POLLed mode. 429 */ 430 431 Set_OpReg16(USBINTR, DISABLE_ALL_INTRS); 432 433 /* 434 * Stop the HC controller from processing TD's 435 */ 436 Set_OpReg16(USBCMD, 0); 437 438 /* 439 * Save the current interrupt lattice and replace this lattice 440 * with an lattice used in POLLED mode. We will restore lattice 441 * back when we exit from the POLLED mode. 442 */ 443 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 444 uhcip->uhci_polled_save_IntTble[i] = 445 uhcip->uhci_frame_lst_tablep[i]; 446 } 447 448 /* 449 * Zero out the entire interrupt lattice tree. 450 */ 451 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 452 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 453 HC_END_OF_LIST); 454 } 455 } 456 457 /* 458 * Now, add the endpoint to the lattice that we will hang our 459 * TD's off of. We (assume always) need to poll this device at 460 * every 8 ms. 461 */ 462 for (i = uhcip->uhci_polled_count - 1; i < NUM_FRAME_LST_ENTRIES; 463 i += MIN_LOW_SPEED_POLL_INTERVAL) { 464 SetFL32(uhcip, uhcip->uhci_frame_lst_tablep[i], 465 QH_PADDR(uhci_polledp->uhci_polled_qh) | HC_QUEUE_HEAD); 466 } 467 468 /* 469 * Adjust the data toggle 470 */ 471 td = uhcip->uhci_outst_tds_head; 472 while (td != NULL) { 473 if (td->tw->tw_pipe_private->pp_pipe_handle == ph) { 474 polled_td = uhci_polledp->uhci_polled_td; 475 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 476 SetTD_dtogg(uhcip, polled_td, 477 GetTD_dtogg(uhcip, td)); 478 } else { 479 SetTD_dtogg(uhcip, polled_td, 480 (GetTD_dtogg(uhcip, td) ^ 1)); 481 uhcip->uhci_polled_flag = 482 UHCI_POLLED_FLAG_TD_COMPL; 483 } 484 break; 485 } 486 td = td->outst_td_next; 487 } 488 /* 489 * Only the first keyboard enter reset the frame number and start 490 * the host controler processing. 491 */ 492 if (uhcip->uhci_polled_count == 1) { 493 /* Set the frame number to zero */ 494 Set_OpReg16(FRNUM, 0); 495 496 /* 497 * Start the Host controller processing 498 */ 499 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 500 USBCMD_REG_CONFIG_FLAG)); 501 } 502 503 #ifndef lint 504 _NOTE(COMPETING_THREADS_NOW); 505 #endif 506 } 507 508 509 /* 510 * uhci_polled_restore_state: 511 */ 512 static void 513 uhci_polled_restore_state(uhci_polled_t *uhci_polledp) 514 { 515 int i; 516 ushort_t real_data_toggle; 517 uhci_td_t *td, *polled_td; 518 uhci_state_t *uhcip; 519 uhci_pipe_private_t *pp; 520 521 #ifndef lint 522 _NOTE(NO_COMPETING_THREADS_NOW); 523 #endif 524 /* 525 * If this flags is set, then we are still using this structure, 526 * so don't restore any controller state information yet. 527 */ 528 if (uhci_polledp->uhci_polled_flags & POLLED_INPUT_MODE_INUSE) { 529 #ifndef lint 530 _NOTE(COMPETING_THREADS_NOW); 531 #endif 532 return; 533 } 534 535 uhcip = uhci_polledp->uhci_polled_uhcip; 536 uhcip->uhci_polled_count --; 537 538 /* Just first leave keyboard entry turn off the controller */ 539 if (Get_OpReg16(USBCMD)) { 540 Set_OpReg16(USBCMD, 0x0); 541 } 542 /* Only the last leave keyboard entry restore the interrupt table */ 543 if (uhcip->uhci_polled_count == 0) { 544 /* 545 * Replace the lattice 546 */ 547 for (i = 0; i < NUM_FRAME_LST_ENTRIES; i++) { 548 uhcip->uhci_frame_lst_tablep[i] = 549 uhcip->uhci_polled_save_IntTble[i]; 550 } 551 } 552 553 /* 554 * Adjust data toggle 555 */ 556 pp = (uhci_pipe_private_t *) 557 uhci_polledp->uhci_polled_ph->p_hcd_private; 558 559 polled_td = uhci_polledp->uhci_polled_td; 560 real_data_toggle = (GetTD_status(uhcip, polled_td) & UHCI_TD_ACTIVE) ? 561 GetTD_dtogg(uhcip, polled_td) : 562 !GetTD_dtogg(uhcip, polled_td); 563 564 td = uhcip->uhci_outst_tds_head; 565 while (td != NULL) { 566 if (td->tw->tw_pipe_private->pp_pipe_handle == 567 uhci_polledp->uhci_polled_ph) { 568 if (GetTD_status(uhcip, td) & UHCI_TD_ACTIVE) { 569 SetTD_dtogg(uhcip, td, real_data_toggle); 570 pp->pp_data_toggle = 571 (real_data_toggle == 0) ? 1 : 0; 572 } else { 573 pp->pp_data_toggle = real_data_toggle; 574 } 575 } 576 td = td->outst_td_next; 577 } 578 579 /* 580 * Only the last leave keyboard entry enable the interrupts, 581 * start Host controller processing. 582 */ 583 if (uhcip->uhci_polled_count == 0) { 584 Set_OpReg16(USBINTR, ENABLE_ALL_INTRS); 585 Set_OpReg16(USBCMD, (USBCMD_REG_HC_RUN | USBCMD_REG_MAXPKT_64 | 586 USBCMD_REG_CONFIG_FLAG)); 587 if (uhcip->uhci_polled_flag == UHCI_POLLED_FLAG_TD_COMPL) { 588 uhcip->uhci_polled_flag = UHCI_POLLED_FLAG_TRUE; 589 } 590 } 591 592 #ifndef lint 593 _NOTE(COMPETING_THREADS_NOW); 594 #endif 595 } 596 597 598 /* 599 * uhci_polled_insert_td: 600 * Initializes the transfer descriptor for polling and inserts on the 601 * polled queue head. This will be put in action when entered in to 602 * polled mode. 603 */ 604 static int 605 uhci_polled_insert_td_on_qh(uhci_polled_t *uhci_polledp, 606 usba_pipe_handle_data_t *ph) 607 { 608 uhci_td_t *td; 609 uhci_state_t *uhcip = uhci_polledp->uhci_polled_uhcip; 610 usb_ep_descr_t *eptd; 611 uhci_trans_wrapper_t *tw; 612 613 /* Create the transfer wrapper */ 614 if ((tw = uhci_polled_create_tw(uhci_polledp->uhci_polled_uhcip)) == 615 NULL) { 616 617 return (USB_FAILURE); 618 } 619 620 /* Use the dummy TD allocated for the queue head */ 621 td = uhci_polledp->uhci_polled_qh->td_tailp; 622 bzero((char *)td, sizeof (uhci_td_t)); 623 624 uhci_polledp->uhci_polled_td = td; 625 td->tw = tw; 626 td->flag = TD_FLAG_BUSY; 627 SetTD32(uhcip, td->link_ptr, HC_END_OF_LIST); 628 629 mutex_enter(&ph->p_usba_device->usb_mutex); 630 eptd = &ph->p_ep; 631 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) { 632 SetTD_ls(uhcip, td, LOW_SPEED_DEVICE); 633 } 634 635 SetTD_c_err(uhcip, td, UHCI_MAX_ERR_COUNT); 636 SetTD_mlen(uhcip, td, 0x7); 637 SetTD_devaddr(uhcip, td, ph->p_usba_device->usb_addr); 638 SetTD_endpt(uhcip, td, eptd->bEndpointAddress & END_POINT_ADDRESS_MASK); 639 SetTD_PID(uhcip, td, PID_IN); 640 SetTD32(uhcip, td->buffer_address, tw->tw_cookie.dmac_address); 641 SetTD_ioc(uhcip, td, INTERRUPT_ON_COMPLETION); 642 SetTD_status(uhcip, td, UHCI_TD_ACTIVE); 643 mutex_exit(&ph->p_usba_device->usb_mutex); 644 645 SetQH32(uhcip, uhci_polledp->uhci_polled_qh->element_ptr, TD_PADDR(td)); 646 647 return (USB_SUCCESS); 648 } 649 650 651 /* 652 * uhci_polled_create_wrapper_t: 653 * Creates the transfer wrapper used in polled mode. 654 */ 655 static uhci_trans_wrapper_t * 656 uhci_polled_create_tw(uhci_state_t *uhcip) 657 { 658 uint_t result, ccount; 659 size_t real_length; 660 uhci_trans_wrapper_t *tw; 661 ddi_device_acc_attr_t dev_attr; 662 663 /* Allocate space for the transfer wrapper */ 664 if ((tw = kmem_zalloc(sizeof (uhci_trans_wrapper_t), KM_NOSLEEP)) == 665 NULL) { 666 667 return (NULL); 668 } 669 670 tw->tw_length = POLLED_RAW_BUF_SIZE; 671 672 /* Allocate the DMA handle */ 673 if ((result = ddi_dma_alloc_handle(uhcip->uhci_dip, 674 &uhcip->uhci_dma_attr, DDI_DMA_DONTWAIT, 0, &tw->tw_dmahandle)) != 675 DDI_SUCCESS) { 676 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 677 678 return (NULL); 679 } 680 681 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 682 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 683 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 684 685 /* Allocate the memory */ 686 if ((result = ddi_dma_mem_alloc(tw->tw_dmahandle, POLLED_RAW_BUF_SIZE, 687 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, 688 &tw->tw_buf, &real_length, &tw->tw_accesshandle)) != 689 DDI_SUCCESS) { 690 ddi_dma_free_handle(&tw->tw_dmahandle); 691 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 692 693 return (NULL); 694 } 695 696 /* Bind the handle */ 697 if ((result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL, 698 tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT, 699 DDI_DMA_DONTWAIT, NULL, &tw->tw_cookie, &ccount)) != 700 DDI_DMA_MAPPED) { 701 ddi_dma_mem_free(&tw->tw_accesshandle); 702 ddi_dma_free_handle(&tw->tw_dmahandle); 703 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 704 705 return (NULL); 706 } 707 708 /* The cookie count should be 1 */ 709 if (ccount != 1) { 710 result = ddi_dma_unbind_handle(tw->tw_dmahandle); 711 ASSERT(result == DDI_SUCCESS); 712 713 ddi_dma_mem_free(&tw->tw_accesshandle); 714 ddi_dma_free_handle(&tw->tw_dmahandle); 715 kmem_free(tw, sizeof (uhci_trans_wrapper_t)); 716 717 return (NULL); 718 } 719 720 return (tw); 721 } 722