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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 
  27 /*
  28  * Open Host Controller Driver (OHCI)
  29  *
  30  * The USB Open Host Controller driver is a software driver which interfaces
  31  * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller.
  32  * The interface to USB Open Host Controller is defined by the OpenHCI  Host
  33  * Controller Interface.
  34  *
  35  * NOTE:
  36  *
  37  * Currently OHCI driver does not support the following features
  38  *
  39  * - Handle request with multiple TDs under short xfer conditions except for
  40  *   bulk transfers.
  41  */
  42 #include <sys/usb/hcd/openhci/ohcid.h>
  43 
  44 #include <sys/disp.h>
  45 #include <sys/strsun.h>
  46 
  47 /* Pointer to the state structure */
  48 static void *ohci_statep;
  49 
  50 int force_ohci_off = 1;
  51 
  52 /* Number of instances */
  53 #define OHCI_INSTS      1
  54 
  55 /* Adjustable variables for the size of the pools */
  56 int ohci_ed_pool_size = OHCI_ED_POOL_SIZE;
  57 int ohci_td_pool_size = OHCI_TD_POOL_SIZE;
  58 
  59 /*
  60  * Initialize the values which are used for setting up head pointers for
  61  * the 32ms scheduling lists which starts from the HCCA.
  62  */
  63 static uchar_t ohci_index[NUM_INTR_ED_LISTS / 2] = {0x0, 0x8, 0x4, 0xc,
  64                                                 0x2, 0xa, 0x6, 0xe,
  65                                                 0x1, 0x9, 0x5, 0xd,
  66                                                 0x3, 0xb, 0x7, 0xf};
  67 /* Debugging information */
  68 uint_t ohci_errmask     = (uint_t)PRINT_MASK_ALL;
  69 uint_t ohci_errlevel    = USB_LOG_L2;
  70 uint_t ohci_instance_debug = (uint_t)-1;
  71 
  72 /*
  73  * OHCI MSI tunable:
  74  *
  75  * By default MSI is enabled on all supported platforms.
  76  */
  77 boolean_t ohci_enable_msi = B_TRUE;
  78 
  79 /*
  80  * HCDI entry points
  81  *
  82  * The Host Controller Driver Interfaces (HCDI) are the software interfaces
  83  * between the Universal Serial Bus Driver (USBA) and the Host  Controller
  84  * Driver (HCD). The HCDI interfaces or entry points are subject to change.
  85  */
  86 static int      ohci_hcdi_pipe_open(
  87                                 usba_pipe_handle_data_t *ph,
  88                                 usb_flags_t             usb_flags);
  89 static int      ohci_hcdi_pipe_close(
  90                                 usba_pipe_handle_data_t *ph,
  91                                 usb_flags_t             usb_flags);
  92 static int      ohci_hcdi_pipe_reset(
  93                                 usba_pipe_handle_data_t *ph,
  94                                 usb_flags_t             usb_flags);
  95 static void     ohci_hcdi_pipe_reset_data_toggle(
  96                                 usba_pipe_handle_data_t *ph);
  97 static int      ohci_hcdi_pipe_ctrl_xfer(
  98                                 usba_pipe_handle_data_t *ph,
  99                                 usb_ctrl_req_t          *ctrl_reqp,
 100                                 usb_flags_t             usb_flags);
 101 static int      ohci_hcdi_bulk_transfer_size(
 102                                 usba_device_t           *usba_device,
 103                                 size_t                  *size);
 104 static int      ohci_hcdi_pipe_bulk_xfer(
 105                                 usba_pipe_handle_data_t *ph,
 106                                 usb_bulk_req_t          *bulk_reqp,
 107                                 usb_flags_t             usb_flags);
 108 static int      ohci_hcdi_pipe_intr_xfer(
 109                                 usba_pipe_handle_data_t *ph,
 110                                 usb_intr_req_t          *intr_req,
 111                                 usb_flags_t             usb_flags);
 112 static int      ohci_hcdi_pipe_stop_intr_polling(
 113                                 usba_pipe_handle_data_t *ph,
 114                                 usb_flags_t             usb_flags);
 115 static int      ohci_hcdi_get_current_frame_number(
 116                                 usba_device_t           *usba_device,
 117                                 usb_frame_number_t      *frame_number);
 118 static int      ohci_hcdi_get_max_isoc_pkts(
 119                                 usba_device_t           *usba_device,
 120                                 uint_t          *max_isoc_pkts_per_request);
 121 static int      ohci_hcdi_pipe_isoc_xfer(
 122                                 usba_pipe_handle_data_t *ph,
 123                                 usb_isoc_req_t          *isoc_reqp,
 124                                 usb_flags_t             usb_flags);
 125 static int      ohci_hcdi_pipe_stop_isoc_polling(
 126                                 usba_pipe_handle_data_t *ph,
 127                                 usb_flags_t             usb_flags);
 128 
 129 /*
 130  * Internal Function Prototypes
 131  */
 132 
 133 /* Host Controller Driver (HCD) initialization functions */
 134 static void     ohci_set_dma_attributes(ohci_state_t    *ohcip);
 135 static int      ohci_allocate_pools(ohci_state_t        *ohcip);
 136 static void     ohci_decode_ddi_dma_addr_bind_handle_result(
 137                                 ohci_state_t            *ohcip,
 138                                 int                     result);
 139 static int      ohci_map_regs(ohci_state_t              *ohcip);
 140 static int      ohci_register_intrs_and_init_mutex(
 141                                 ohci_state_t            *ohcip);
 142 static int      ohci_add_intrs(ohci_state_t             *ohcip,
 143                                 int                     intr_type);
 144 static int      ohci_init_ctlr(ohci_state_t             *ohcip);
 145 static int      ohci_init_hcca(ohci_state_t             *ohcip);
 146 static void     ohci_build_interrupt_lattice(
 147                                 ohci_state_t            *ohcip);
 148 static int      ohci_take_control(ohci_state_t          *ohcip);
 149 static usba_hcdi_ops_t *ohci_alloc_hcdi_ops(
 150                                 ohci_state_t            *ohcip);
 151 
 152 /* Host Controller Driver (HCD) deinitialization functions */
 153 static int      ohci_cleanup(ohci_state_t               *ohcip);
 154 static void     ohci_rem_intrs(ohci_state_t             *ohcip);
 155 static int      ohci_cpr_suspend(ohci_state_t           *ohcip);
 156 static int      ohci_cpr_resume(ohci_state_t            *ohcip);
 157 
 158 /* Bandwidth Allocation functions */
 159 static int      ohci_allocate_bandwidth(ohci_state_t    *ohcip,
 160                                 usba_pipe_handle_data_t *ph,
 161                                 uint_t                  *node);
 162 static void     ohci_deallocate_bandwidth(ohci_state_t  *ohcip,
 163                                 usba_pipe_handle_data_t *ph);
 164 static int      ohci_compute_total_bandwidth(
 165                                 usb_ep_descr_t          *endpoint,
 166                                 usb_port_status_t       port_status,
 167                                 uint_t                  *bandwidth);
 168 static int      ohci_adjust_polling_interval(
 169                                 ohci_state_t            *ohcip,
 170                                 usb_ep_descr_t          *endpoint,
 171                                 usb_port_status_t       port_status);
 172 static uint_t   ohci_lattice_height(uint_t              interval);
 173 static uint_t   ohci_lattice_parent(uint_t              node);
 174 static uint_t   ohci_leftmost_leaf(uint_t               node,
 175                                 uint_t                  height);
 176 static uint_t   ohci_hcca_intr_index(
 177                                 uint_t                  node);
 178 static uint_t   ohci_hcca_leaf_index(
 179                                 uint_t                  leaf);
 180 static uint_t   ohci_pow_2(uint_t x);
 181 static uint_t   ohci_log_2(uint_t x);
 182 
 183 /* Endpoint Descriptor (ED) related functions */
 184 static uint_t   ohci_unpack_endpoint(ohci_state_t       *ohcip,
 185                                 usba_pipe_handle_data_t *ph);
 186 static void     ohci_insert_ed(ohci_state_t             *ohcip,
 187                                 usba_pipe_handle_data_t *ph);
 188 static void     ohci_insert_ctrl_ed(
 189                                 ohci_state_t            *ohcip,
 190                                 ohci_pipe_private_t     *pp);
 191 static void     ohci_insert_bulk_ed(
 192                                 ohci_state_t            *ohcip,
 193                                 ohci_pipe_private_t     *pp);
 194 static void     ohci_insert_intr_ed(
 195                                 ohci_state_t            *ohcip,
 196                                 ohci_pipe_private_t     *pp);
 197 static void     ohci_insert_isoc_ed(
 198                                 ohci_state_t            *ohcip,
 199                                 ohci_pipe_private_t     *pp);
 200 static void     ohci_modify_sKip_bit(ohci_state_t       *ohcip,
 201                                 ohci_pipe_private_t     *pp,
 202                                 skip_bit_t              action,
 203                                 usb_flags_t             flag);
 204 static void     ohci_remove_ed(ohci_state_t             *ohcip,
 205                                 ohci_pipe_private_t     *pp);
 206 static void     ohci_remove_ctrl_ed(
 207                                 ohci_state_t            *ohcip,
 208                                 ohci_pipe_private_t     *pp);
 209 static void     ohci_remove_bulk_ed(
 210                                 ohci_state_t            *ohcip,
 211                                 ohci_pipe_private_t     *pp);
 212 static void     ohci_remove_periodic_ed(
 213                                 ohci_state_t            *ohcip,
 214                                 ohci_pipe_private_t     *pp);
 215 static void     ohci_insert_ed_on_reclaim_list(
 216                                 ohci_state_t            *ohcip,
 217                                 ohci_pipe_private_t     *pp);
 218 static void     ohci_detach_ed_from_list(
 219                                 ohci_state_t            *ohcip,
 220                                 ohci_ed_t               *ept,
 221                                 uint_t                  ept_type);
 222 static ohci_ed_t *ohci_ed_iommu_to_cpu(
 223                                 ohci_state_t            *ohcip,
 224                                 uintptr_t               addr);
 225 
 226 /* Transfer Descriptor (TD) related functions */
 227 static int      ohci_initialize_dummy(ohci_state_t      *ohcip,
 228                                 ohci_ed_t               *ept);
 229 static ohci_trans_wrapper_t *ohci_allocate_ctrl_resources(
 230                                 ohci_state_t            *ohcip,
 231                                 ohci_pipe_private_t     *pp,
 232                                 usb_ctrl_req_t          *ctrl_reqp,
 233                                 usb_flags_t             usb_flags);
 234 static void     ohci_insert_ctrl_req(
 235                                 ohci_state_t            *ohcip,
 236                                 usba_pipe_handle_data_t *ph,
 237                                 usb_ctrl_req_t          *ctrl_reqp,
 238                                 ohci_trans_wrapper_t    *tw,
 239                                 usb_flags_t             usb_flags);
 240 static ohci_trans_wrapper_t *ohci_allocate_bulk_resources(
 241                                 ohci_state_t            *ohcip,
 242                                 ohci_pipe_private_t     *pp,
 243                                 usb_bulk_req_t          *bulk_reqp,
 244                                 usb_flags_t             usb_flags);
 245 static void     ohci_insert_bulk_req(ohci_state_t       *ohcip,
 246                                 usba_pipe_handle_data_t *ph,
 247                                 usb_bulk_req_t          *bulk_reqp,
 248                                 ohci_trans_wrapper_t    *tw,
 249                                 usb_flags_t             flags);
 250 static int      ohci_start_pipe_polling(ohci_state_t    *ohcip,
 251                                 usba_pipe_handle_data_t *ph,
 252                                 usb_flags_t             flags);
 253 static void     ohci_set_periodic_pipe_polling(
 254                                 ohci_state_t            *ohcip,
 255                                 usba_pipe_handle_data_t *ph);
 256 static ohci_trans_wrapper_t *ohci_allocate_intr_resources(
 257                                 ohci_state_t            *ohcip,
 258                                 usba_pipe_handle_data_t *ph,
 259                                 usb_intr_req_t          *intr_reqp,
 260                                 usb_flags_t             usb_flags);
 261 static void     ohci_insert_intr_req(ohci_state_t       *ohcip,
 262                                 ohci_pipe_private_t     *pp,
 263                                 ohci_trans_wrapper_t    *tw,
 264                                 usb_flags_t             flags);
 265 static int      ohci_stop_periodic_pipe_polling(
 266                                 ohci_state_t            *ohcip,
 267                                 usba_pipe_handle_data_t *ph,
 268                                 usb_flags_t             flags);
 269 static ohci_trans_wrapper_t *ohci_allocate_isoc_resources(
 270                                 ohci_state_t            *ohcip,
 271                                 usba_pipe_handle_data_t *ph,
 272                                 usb_isoc_req_t          *isoc_reqp,
 273                                 usb_flags_t             usb_flags);
 274 static int      ohci_insert_isoc_req(ohci_state_t       *ohcip,
 275                                 ohci_pipe_private_t     *pp,
 276                                 ohci_trans_wrapper_t    *tw,
 277                                 uint_t                  flags);
 278 static int      ohci_insert_hc_td(ohci_state_t          *ohcip,
 279                                 uint_t                  hctd_ctrl,
 280                                 uint32_t                hctd_dma_offs,
 281                                 size_t                  hctd_length,
 282                                 uint32_t                hctd_ctrl_phase,
 283                                 ohci_pipe_private_t     *pp,
 284                                 ohci_trans_wrapper_t    *tw);
 285 static ohci_td_t *ohci_allocate_td_from_pool(
 286                                 ohci_state_t            *ohcip);
 287 static void     ohci_fill_in_td(ohci_state_t            *ohcip,
 288                                 ohci_td_t               *td,
 289                                 ohci_td_t               *new_dummy,
 290                                 uint_t                  hctd_ctrl,
 291                                 uint32_t                hctd_dma_offs,
 292                                 size_t                  hctd_length,
 293                                 uint32_t                hctd_ctrl_phase,
 294                                 ohci_pipe_private_t     *pp,
 295                                 ohci_trans_wrapper_t    *tw);
 296 static void     ohci_init_itd(
 297                                 ohci_state_t            *ohcip,
 298                                 ohci_trans_wrapper_t    *tw,
 299                                 uint_t                  hctd_ctrl,
 300                                 uint32_t                index,
 301                                 ohci_td_t               *td);
 302 static int      ohci_insert_td_with_frame_number(
 303                                 ohci_state_t            *ohcip,
 304                                 ohci_pipe_private_t     *pp,
 305                                 ohci_trans_wrapper_t    *tw,
 306                                 ohci_td_t               *current_td,
 307                                 ohci_td_t               *dummy_td);
 308 static void     ohci_insert_td_on_tw(ohci_state_t       *ohcip,
 309                                 ohci_trans_wrapper_t    *tw,
 310                                 ohci_td_t               *td);
 311 static void     ohci_done_list_tds(ohci_state_t         *ohcip,
 312                                 usba_pipe_handle_data_t *ph);
 313 
 314 /* Transfer Wrapper (TW) functions */
 315 static ohci_trans_wrapper_t  *ohci_create_transfer_wrapper(
 316                                 ohci_state_t            *ohcip,
 317                                 ohci_pipe_private_t     *pp,
 318                                 size_t                  length,
 319                                 uint_t                  usb_flags);
 320 static ohci_trans_wrapper_t  *ohci_create_isoc_transfer_wrapper(
 321                                 ohci_state_t            *ohcip,
 322                                 ohci_pipe_private_t     *pp,
 323                                 size_t                  length,
 324                                 usb_isoc_pkt_descr_t    *descr,
 325                                 ushort_t                pkt_count,
 326                                 size_t                  td_count,
 327                                 uint_t                  usb_flags);
 328 int     ohci_allocate_tds_for_tw(
 329                                 ohci_state_t            *ohcip,
 330                                 ohci_trans_wrapper_t    *tw,
 331                                 size_t                  td_count);
 332 static ohci_trans_wrapper_t  *ohci_allocate_tw_resources(
 333                                 ohci_state_t            *ohcip,
 334                                 ohci_pipe_private_t     *pp,
 335                                 size_t                  length,
 336                                 usb_flags_t             usb_flags,
 337                                 size_t                  td_count);
 338 static void     ohci_free_tw_tds_resources(
 339                                 ohci_state_t            *ohcip,
 340                                 ohci_trans_wrapper_t    *tw);
 341 static void     ohci_start_xfer_timer(
 342                                 ohci_state_t            *ohcip,
 343                                 ohci_pipe_private_t     *pp,
 344                                 ohci_trans_wrapper_t    *tw);
 345 static void     ohci_stop_xfer_timer(
 346                                 ohci_state_t            *ohcip,
 347                                 ohci_trans_wrapper_t    *tw,
 348                                 uint_t                  flag);
 349 static void     ohci_xfer_timeout_handler(void          *arg);
 350 static void     ohci_remove_tw_from_timeout_list(
 351                                 ohci_state_t            *ohcip,
 352                                 ohci_trans_wrapper_t    *tw);
 353 static void     ohci_start_timer(ohci_state_t           *ohcip);
 354 static void     ohci_free_dma_resources(ohci_state_t    *ohcip,
 355                                 usba_pipe_handle_data_t *ph);
 356 static void     ohci_free_tw(ohci_state_t               *ohcip,
 357                                 ohci_trans_wrapper_t    *tw);
 358 static int      ohci_tw_rebind_cookie(
 359                                 ohci_state_t            *ohcip,
 360                                 ohci_pipe_private_t     *pp,
 361                                 ohci_trans_wrapper_t    *tw);
 362 
 363 /* Interrupt Handling functions */
 364 static uint_t   ohci_intr(caddr_t                       arg1,
 365                                 caddr_t                 arg2);
 366 static void     ohci_handle_missed_intr(
 367                                 ohci_state_t            *ohcip);
 368 static void     ohci_handle_ue(ohci_state_t             *ohcip);
 369 static void     ohci_handle_endpoint_reclaimation(
 370                                 ohci_state_t            *ohcip);
 371 static void     ohci_traverse_done_list(
 372                                 ohci_state_t            *ohcip,
 373                                 ohci_td_t               *head_done_list);
 374 static ohci_td_t *ohci_reverse_done_list(
 375                                 ohci_state_t            *ohcip,
 376                                 ohci_td_t               *head_done_list);
 377 static usb_cr_t ohci_parse_error(ohci_state_t           *ohcip,
 378                                 ohci_td_t               *td);
 379 static void     ohci_parse_isoc_error(
 380                                 ohci_state_t            *ohcip,
 381                                 ohci_pipe_private_t     *pp,
 382                                 ohci_trans_wrapper_t    *tw,
 383                                 ohci_td_t               *td);
 384 static usb_cr_t ohci_check_for_error(
 385                                 ohci_state_t            *ohcip,
 386                                 ohci_pipe_private_t     *pp,
 387                                 ohci_trans_wrapper_t    *tw,
 388                                 ohci_td_t               *td,
 389                                 uint_t                  ctrl);
 390 static void     ohci_handle_error(
 391                                 ohci_state_t            *ohcip,
 392                                 ohci_td_t               *td,
 393                                 usb_cr_t                error);
 394 static int      ohci_cleanup_data_underrun(
 395                                 ohci_state_t            *ohcip,
 396                                 ohci_pipe_private_t     *pp,
 397                                 ohci_trans_wrapper_t    *tw,
 398                                 ohci_td_t               *td);
 399 static void     ohci_handle_normal_td(
 400                                 ohci_state_t            *ohcip,
 401                                 ohci_td_t               *td,
 402                                 ohci_trans_wrapper_t    *tw);
 403 static void     ohci_handle_ctrl_td(ohci_state_t        *ohcip,
 404                                 ohci_pipe_private_t     *pp,
 405                                 ohci_trans_wrapper_t    *tw,
 406                                 ohci_td_t               *td,
 407                                 void                    *);
 408 static void     ohci_handle_bulk_td(ohci_state_t        *ohcip,
 409                                 ohci_pipe_private_t     *pp,
 410                                 ohci_trans_wrapper_t    *tw,
 411                                 ohci_td_t               *td,
 412                                 void                    *);
 413 static void     ohci_handle_intr_td(ohci_state_t        *ohcip,
 414                                 ohci_pipe_private_t     *pp,
 415                                 ohci_trans_wrapper_t    *tw,
 416                                 ohci_td_t               *td,
 417                                 void                    *);
 418 static void     ohci_handle_one_xfer_completion(
 419                                 ohci_state_t            *ohcip,
 420                                 ohci_trans_wrapper_t    *tw);
 421 static void     ohci_handle_isoc_td(ohci_state_t        *ohcip,
 422                                 ohci_pipe_private_t     *pp,
 423                                 ohci_trans_wrapper_t    *tw,
 424                                 ohci_td_t               *td,
 425                                 void                    *);
 426 static void     ohci_sendup_td_message(
 427                                 ohci_state_t            *ohcip,
 428                                 ohci_pipe_private_t     *pp,
 429                                 ohci_trans_wrapper_t    *tw,
 430                                 ohci_td_t               *td,
 431                                 usb_cr_t                error);
 432 static int      ohci_check_done_head(
 433                                 ohci_state_t *ohcip,
 434                                 ohci_td_t               *done_head);
 435 
 436 /* Miscillaneous functions */
 437 static void     ohci_cpr_cleanup(
 438                                 ohci_state_t            *ohcip);
 439 static usb_req_attrs_t ohci_get_xfer_attrs(ohci_state_t *ohcip,
 440                                 ohci_pipe_private_t     *pp,
 441                                 ohci_trans_wrapper_t    *tw);
 442 static int      ohci_allocate_periodic_in_resource(
 443                                 ohci_state_t            *ohcip,
 444                                 ohci_pipe_private_t     *pp,
 445                                 ohci_trans_wrapper_t    *tw,
 446                                 usb_flags_t             flags);
 447 static int      ohci_wait_for_sof(
 448                                 ohci_state_t            *ohcip);
 449 static void     ohci_pipe_cleanup(
 450                                 ohci_state_t            *ohcip,
 451                                 usba_pipe_handle_data_t *ph);
 452 static void     ohci_wait_for_transfers_completion(
 453                                 ohci_state_t            *ohcip,
 454                                 ohci_pipe_private_t     *pp);
 455 static void     ohci_check_for_transfers_completion(
 456                                 ohci_state_t            *ohcip,
 457                                 ohci_pipe_private_t     *pp);
 458 static void     ohci_save_data_toggle(ohci_state_t      *ohcip,
 459                                 usba_pipe_handle_data_t *ph);
 460 static void     ohci_restore_data_toggle(ohci_state_t   *ohcip,
 461                                 usba_pipe_handle_data_t *ph);
 462 static void     ohci_deallocate_periodic_in_resource(
 463                                 ohci_state_t            *ohcip,
 464                                 ohci_pipe_private_t     *pp,
 465                                 ohci_trans_wrapper_t    *tw);
 466 static void     ohci_do_client_periodic_in_req_callback(
 467                                 ohci_state_t            *ohcip,
 468                                 ohci_pipe_private_t     *pp,
 469                                 usb_cr_t                completion_reason);
 470 static void     ohci_hcdi_callback(
 471                                 usba_pipe_handle_data_t *ph,
 472                                 ohci_trans_wrapper_t    *tw,
 473                                 usb_cr_t                completion_reason);
 474 
 475 /* Kstat Support */
 476 static void     ohci_create_stats(ohci_state_t          *ohcip);
 477 static void     ohci_destroy_stats(ohci_state_t         *ohcip);
 478 static void     ohci_do_byte_stats(
 479                                 ohci_state_t            *ohcip,
 480                                 size_t                  len,
 481                                 uint8_t                 attr,
 482                                 uint8_t                 addr);
 483 static void     ohci_do_intrs_stats(
 484                                 ohci_state_t            *ohcip,
 485                                 int                     val);
 486 static void     ohci_print_op_regs(ohci_state_t         *ohcip);
 487 static void     ohci_print_ed(ohci_state_t              *ohcip,
 488                                 ohci_ed_t               *ed);
 489 static void     ohci_print_td(ohci_state_t              *ohcip,
 490                                 ohci_td_t               *td);
 491 
 492 /* extern */
 493 int usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level);
 494 
 495 /*
 496  * Device operations (dev_ops) entries function prototypes.
 497  *
 498  * We use the hub cbops since all nexus ioctl operations defined so far will
 499  * be executed by the root hub. The following are the Host Controller Driver
 500  * (HCD) entry points.
 501  *
 502  * the open/close/ioctl functions call the corresponding usba_hubdi_*
 503  * calls after looking up the dip thru the dev_t.
 504  */
 505 static int      ohci_open(dev_t *devp, int flags, int otyp, cred_t *credp);
 506 static int      ohci_close(dev_t dev, int flag, int otyp, cred_t *credp);
 507 static int      ohci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
 508                                 cred_t *credp, int *rvalp);
 509 
 510 static int      ohci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 511 static int      ohci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
 512 static int      ohci_quiesce(dev_info_t *dip);
 513 
 514 static int      ohci_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
 515                                 void *arg, void **result);
 516 
 517 static struct cb_ops ohci_cb_ops = {
 518         ohci_open,                      /* Open */
 519         ohci_close,                     /* Close */
 520         nodev,                          /* Strategy */
 521         nodev,                          /* Print */
 522         nodev,                          /* Dump */
 523         nodev,                          /* Read */
 524         nodev,                          /* Write */
 525         ohci_ioctl,                     /* Ioctl */
 526         nodev,                          /* Devmap */
 527         nodev,                          /* Mmap */
 528         nodev,                          /* Segmap */
 529         nochpoll,                       /* Poll */
 530         ddi_prop_op,                    /* cb_prop_op */
 531         NULL,                           /* Streamtab */
 532         D_MP                            /* Driver compatibility flag */
 533 };
 534 
 535 static struct dev_ops ohci_ops = {
 536         DEVO_REV,                       /* Devo_rev */
 537         0,                              /* Refcnt */
 538         ohci_info,                      /* Info */
 539         nulldev,                        /* Identify */
 540         nulldev,                        /* Probe */
 541         ohci_attach,                    /* Attach */
 542         ohci_detach,                    /* Detach */
 543         nodev,                          /* Reset */
 544         &ohci_cb_ops,                       /* Driver operations */
 545         &usba_hubdi_busops,         /* Bus operations */
 546         usba_hubdi_root_hub_power,      /* Power */
 547         ohci_quiesce,                   /* Quiesce */
 548 };
 549 
 550 /*
 551  * The USBA library must be loaded for this driver.
 552  */
 553 static struct modldrv modldrv = {
 554         &mod_driverops,     /* Type of module. This one is a driver */
 555         "USB OpenHCI Driver", /* Name of the module. */
 556         &ohci_ops,          /* Driver ops */
 557 };
 558 
 559 static struct modlinkage modlinkage = {
 560         MODREV_1, (void *)&modldrv, NULL
 561 };
 562 
 563 
 564 int
 565 _init(void)
 566 {
 567         int error;
 568 
 569         /* Initialize the soft state structures */
 570         if ((error = ddi_soft_state_init(&ohci_statep, sizeof (ohci_state_t),
 571             OHCI_INSTS)) != 0) {
 572                 return (error);
 573         }
 574 
 575         /* Install the loadable module */
 576         if ((error = mod_install(&modlinkage)) != 0) {
 577                 ddi_soft_state_fini(&ohci_statep);
 578         }
 579 
 580         return (error);
 581 }
 582 
 583 
 584 int
 585 _info(struct modinfo *modinfop)
 586 {
 587         return (mod_info(&modlinkage, modinfop));
 588 }
 589 
 590 
 591 int
 592 _fini(void)
 593 {
 594         int error;
 595 
 596         if ((error = mod_remove(&modlinkage)) == 0) {
 597                 /* Release per module resources */
 598                 ddi_soft_state_fini(&ohci_statep);
 599         }
 600 
 601         return (error);
 602 }
 603 
 604 
 605 /*
 606  * Host Controller Driver (HCD) entry points
 607  */
 608 
 609 /*
 610  * ohci_attach:
 611  */
 612 static int
 613 ohci_attach(dev_info_t          *dip,
 614         ddi_attach_cmd_t        cmd)
 615 {
 616         int                     instance;
 617         ohci_state_t            *ohcip = NULL;
 618         usba_hcdi_register_args_t hcdi_args;
 619 
 620         switch (cmd) {
 621         case DDI_ATTACH:
 622                 break;
 623         case DDI_RESUME:
 624                 ohcip = ohci_obtain_state(dip);
 625 
 626                 return (ohci_cpr_resume(ohcip));
 627         default:
 628                 return (DDI_FAILURE);
 629         }
 630 
 631         /* Get the instance and create soft state */
 632         instance = ddi_get_instance(dip);
 633 
 634         if (ddi_soft_state_zalloc(ohci_statep, instance) != 0) {
 635 
 636                 return (DDI_FAILURE);
 637         }
 638 
 639         ohcip = ddi_get_soft_state(ohci_statep, instance);
 640         if (ohcip == NULL) {
 641 
 642                 return (DDI_FAILURE);
 643         }
 644 
 645         ohcip->ohci_flags = OHCI_ATTACH;
 646 
 647         ohcip->ohci_log_hdl = usb_alloc_log_hdl(dip, "ohci", &ohci_errlevel,
 648             &ohci_errmask, &ohci_instance_debug, 0);
 649 
 650         ohcip->ohci_flags |= OHCI_ZALLOC;
 651 
 652         /* Set host controller soft state to initilization */
 653         ohcip->ohci_hc_soft_state = OHCI_CTLR_INIT_STATE;
 654 
 655         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
 656             "ohcip = 0x%p", (void *)ohcip);
 657 
 658         /* Initialize the DMA attributes */
 659         ohci_set_dma_attributes(ohcip);
 660 
 661         /* Save the dip and instance */
 662         ohcip->ohci_dip = dip;
 663         ohcip->ohci_instance = instance;
 664 
 665         /* Initialize the kstat structures */
 666         ohci_create_stats(ohcip);
 667 
 668         /* Create the td and ed pools */
 669         if (ohci_allocate_pools(ohcip) != DDI_SUCCESS) {
 670                 (void) ohci_cleanup(ohcip);
 671 
 672                 return (DDI_FAILURE);
 673         }
 674 
 675         /* Map the registers */
 676         if (ohci_map_regs(ohcip) != DDI_SUCCESS) {
 677                 (void) ohci_cleanup(ohcip);
 678 
 679                 return (DDI_FAILURE);
 680         }
 681 
 682         /* Get the ohci chip vendor and device id */
 683         ohcip->ohci_vendor_id = pci_config_get16(
 684             ohcip->ohci_config_handle, PCI_CONF_VENID);
 685         ohcip->ohci_device_id = pci_config_get16(
 686             ohcip->ohci_config_handle, PCI_CONF_DEVID);
 687         ohcip->ohci_rev_id = pci_config_get8(
 688             ohcip->ohci_config_handle, PCI_CONF_REVID);
 689 
 690         /* Register interrupts */
 691         if (ohci_register_intrs_and_init_mutex(ohcip) != DDI_SUCCESS) {
 692                 (void) ohci_cleanup(ohcip);
 693 
 694                 return (DDI_FAILURE);
 695         }
 696 
 697         mutex_enter(&ohcip->ohci_int_mutex);
 698 
 699         /* Initialize the controller */
 700         if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) {
 701                 mutex_exit(&ohcip->ohci_int_mutex);
 702                 (void) ohci_cleanup(ohcip);
 703 
 704                 return (DDI_FAILURE);
 705         }
 706 
 707         /*
 708          * At this point, the hardware wiil be okay.
 709          * Initialize the usba_hcdi structure
 710          */
 711         ohcip->ohci_hcdi_ops = ohci_alloc_hcdi_ops(ohcip);
 712 
 713         mutex_exit(&ohcip->ohci_int_mutex);
 714 
 715         /*
 716          * Make this HCD instance known to USBA
 717          * (dma_attr must be passed for USBA busctl's)
 718          */
 719         hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION;
 720         hcdi_args.usba_hcdi_register_dip = dip;
 721         hcdi_args.usba_hcdi_register_ops = ohcip->ohci_hcdi_ops;
 722         hcdi_args.usba_hcdi_register_dma_attr = &ohcip->ohci_dma_attr;
 723 
 724         /*
 725          * Priority and iblock_cookie are one and the same
 726          * (However, retaining hcdi_soft_iblock_cookie for now
 727          * assigning it w/ priority. In future all iblock_cookie
 728          * could just go)
 729          */
 730         hcdi_args.usba_hcdi_register_iblock_cookie =
 731             (ddi_iblock_cookie_t)(uintptr_t)ohcip->ohci_intr_pri;
 732 
 733         if (usba_hcdi_register(&hcdi_args, 0) != DDI_SUCCESS) {
 734                 (void) ohci_cleanup(ohcip);
 735 
 736                 return (DDI_FAILURE);
 737         }
 738         ohcip->ohci_flags |= OHCI_USBAREG;
 739 
 740         mutex_enter(&ohcip->ohci_int_mutex);
 741 
 742         if ((ohci_init_root_hub(ohcip)) != USB_SUCCESS) {
 743                 mutex_exit(&ohcip->ohci_int_mutex);
 744                 (void) ohci_cleanup(ohcip);
 745 
 746                 return (DDI_FAILURE);
 747         }
 748 
 749         mutex_exit(&ohcip->ohci_int_mutex);
 750 
 751         /* Finally load the root hub driver */
 752         if (ohci_load_root_hub_driver(ohcip) != USB_SUCCESS) {
 753                 (void) ohci_cleanup(ohcip);
 754 
 755                 return (DDI_FAILURE);
 756         }
 757         ohcip->ohci_flags |= OHCI_RHREG;
 758 
 759         /* Display information in the banner */
 760         ddi_report_dev(dip);
 761 
 762         mutex_enter(&ohcip->ohci_int_mutex);
 763 
 764         /* Reset the ohci initilization flag */
 765         ohcip->ohci_flags &= ~OHCI_ATTACH;
 766 
 767         /* Print the Host Control's Operational registers */
 768         ohci_print_op_regs(ohcip);
 769 
 770         /* For RIO we need to call pci_report_pmcap */
 771         if (OHCI_IS_RIO(ohcip)) {
 772 
 773                 (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000);
 774         }
 775 
 776         mutex_exit(&ohcip->ohci_int_mutex);
 777 
 778         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
 779             "ohci_attach: dip = 0x%p done", (void *)dip);
 780 
 781         return (DDI_SUCCESS);
 782 }
 783 
 784 
 785 /*
 786  * ohci_detach:
 787  */
 788 int
 789 ohci_detach(dev_info_t          *dip,
 790         ddi_detach_cmd_t        cmd)
 791 {
 792         ohci_state_t            *ohcip = ohci_obtain_state(dip);
 793 
 794         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_detach:");
 795 
 796         switch (cmd) {
 797         case DDI_DETACH:
 798 
 799                 return (ohci_cleanup(ohcip));
 800 
 801         case DDI_SUSPEND:
 802 
 803                 return (ohci_cpr_suspend(ohcip));
 804         default:
 805 
 806                 return (DDI_FAILURE);
 807         }
 808 }
 809 
 810 
 811 /*
 812  * ohci_info:
 813  */
 814 /* ARGSUSED */
 815 static int
 816 ohci_info(dev_info_t            *dip,
 817         ddi_info_cmd_t          infocmd,
 818         void                    *arg,
 819         void                    **result)
 820 {
 821         dev_t                   dev;
 822         ohci_state_t            *ohcip;
 823         int                     instance;
 824         int                     error = DDI_FAILURE;
 825 
 826         switch (infocmd) {
 827         case DDI_INFO_DEVT2DEVINFO:
 828                 dev = (dev_t)arg;
 829                 instance = OHCI_UNIT(dev);
 830                 ohcip = ddi_get_soft_state(ohci_statep, instance);
 831                 if (ohcip != NULL) {
 832                         *result = (void *)ohcip->ohci_dip;
 833                         if (*result != NULL) {
 834                                 error = DDI_SUCCESS;
 835                         }
 836                 } else {
 837                         *result = NULL;
 838                 }
 839 
 840                 break;
 841         case DDI_INFO_DEVT2INSTANCE:
 842                 dev = (dev_t)arg;
 843                 instance = OHCI_UNIT(dev);
 844                 *result = (void *)(uintptr_t)instance;
 845                 error = DDI_SUCCESS;
 846                 break;
 847         default:
 848                 break;
 849         }
 850 
 851         return (error);
 852 }
 853 
 854 
 855 /*
 856  * cb_ops entry points
 857  */
 858 static dev_info_t *
 859 ohci_get_dip(dev_t      dev)
 860 {
 861         int             instance = OHCI_UNIT(dev);
 862         ohci_state_t    *ohcip = ddi_get_soft_state(ohci_statep, instance);
 863 
 864         if (ohcip) {
 865 
 866                 return (ohcip->ohci_dip);
 867         } else {
 868 
 869                 return (NULL);
 870         }
 871 }
 872 
 873 
 874 static int
 875 ohci_open(dev_t         *devp,
 876         int             flags,
 877         int             otyp,
 878         cred_t          *credp)
 879 {
 880         dev_info_t      *dip = ohci_get_dip(*devp);
 881 
 882         return (usba_hubdi_open(dip, devp, flags, otyp, credp));
 883 }
 884 
 885 
 886 static int
 887 ohci_close(dev_t        dev,
 888         int             flag,
 889         int             otyp,
 890         cred_t          *credp)
 891 {
 892         dev_info_t      *dip = ohci_get_dip(dev);
 893 
 894         return (usba_hubdi_close(dip, dev, flag, otyp, credp));
 895 }
 896 
 897 
 898 static int
 899 ohci_ioctl(dev_t        dev,
 900         int             cmd,
 901         intptr_t        arg,
 902         int             mode,
 903         cred_t          *credp,
 904         int             *rvalp)
 905 {
 906         dev_info_t      *dip = ohci_get_dip(dev);
 907 
 908         return (usba_hubdi_ioctl(dip,
 909             dev, cmd, arg, mode, credp, rvalp));
 910 }
 911 
 912 
 913 /*
 914  * Host Controller Driver (HCD) initialization functions
 915  */
 916 
 917 /*
 918  * ohci_set_dma_attributes:
 919  *
 920  * Set the limits in the DMA attributes structure. Most of the values used
 921  * in the  DMA limit structres are the default values as specified by  the
 922  * Writing PCI device drivers document.
 923  */
 924 static void
 925 ohci_set_dma_attributes(ohci_state_t    *ohcip)
 926 {
 927         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
 928             "ohci_set_dma_attributes:");
 929 
 930         /* Initialize the DMA attributes */
 931         ohcip->ohci_dma_attr.dma_attr_version = DMA_ATTR_V0;
 932         ohcip->ohci_dma_attr.dma_attr_addr_lo = 0x00000000ull;
 933         ohcip->ohci_dma_attr.dma_attr_addr_hi = 0xfffffffeull;
 934 
 935         /* 32 bit addressing */
 936         ohcip->ohci_dma_attr.dma_attr_count_max = OHCI_DMA_ATTR_COUNT_MAX;
 937 
 938         /* Byte alignment */
 939         ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
 940 
 941         /*
 942          * Since PCI  specification is byte alignment, the
 943          * burstsize field should be set to 1 for PCI devices.
 944          */
 945         ohcip->ohci_dma_attr.dma_attr_burstsizes = 0x1;
 946 
 947         ohcip->ohci_dma_attr.dma_attr_minxfer = 0x1;
 948         ohcip->ohci_dma_attr.dma_attr_maxxfer = OHCI_DMA_ATTR_MAX_XFER;
 949         ohcip->ohci_dma_attr.dma_attr_seg = 0xffffffffull;
 950         ohcip->ohci_dma_attr.dma_attr_sgllen = 1;
 951         ohcip->ohci_dma_attr.dma_attr_granular = OHCI_DMA_ATTR_GRANULAR;
 952         ohcip->ohci_dma_attr.dma_attr_flags = 0;
 953 }
 954 
 955 
 956 /*
 957  * ohci_allocate_pools:
 958  *
 959  * Allocate the system memory for the Endpoint Descriptor (ED) and for the
 960  * Transfer Descriptor (TD) pools. Both ED and TD structures must be aligned
 961  * to a 16 byte boundary.
 962  */
 963 static int
 964 ohci_allocate_pools(ohci_state_t        *ohcip)
 965 {
 966         ddi_device_acc_attr_t           dev_attr;
 967         size_t                          real_length;
 968         int                             result;
 969         uint_t                          ccount;
 970         int                             i;
 971 
 972         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
 973             "ohci_allocate_pools:");
 974 
 975         /* The host controller will be little endian */
 976         dev_attr.devacc_attr_version    = DDI_DEVICE_ATTR_V0;
 977         dev_attr.devacc_attr_endian_flags  = DDI_STRUCTURE_LE_ACC;
 978         dev_attr.devacc_attr_dataorder  = DDI_STRICTORDER_ACC;
 979 
 980         /* Byte alignment to TD alignment */
 981         ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_TD_ALIGNMENT;
 982 
 983         /* Allocate the TD pool DMA handle */
 984         if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr,
 985             DDI_DMA_SLEEP, 0,
 986             &ohcip->ohci_td_pool_dma_handle) != DDI_SUCCESS) {
 987 
 988                 return (DDI_FAILURE);
 989         }
 990 
 991         /* Allocate the memory for the TD pool */
 992         if (ddi_dma_mem_alloc(ohcip->ohci_td_pool_dma_handle,
 993             ohci_td_pool_size * sizeof (ohci_td_t),
 994             &dev_attr,
 995             DDI_DMA_CONSISTENT,
 996             DDI_DMA_SLEEP,
 997             0,
 998             (caddr_t *)&ohcip->ohci_td_pool_addr,
 999             &real_length,
1000             &ohcip->ohci_td_pool_mem_handle)) {
1001 
1002                 return (DDI_FAILURE);
1003         }
1004 
1005         /* Map the TD pool into the I/O address space */
1006         result = ddi_dma_addr_bind_handle(
1007             ohcip->ohci_td_pool_dma_handle,
1008             NULL,
1009             (caddr_t)ohcip->ohci_td_pool_addr,
1010             real_length,
1011             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1012             DDI_DMA_SLEEP,
1013             NULL,
1014             &ohcip->ohci_td_pool_cookie,
1015             &ccount);
1016 
1017         bzero((void *)ohcip->ohci_td_pool_addr,
1018             ohci_td_pool_size * sizeof (ohci_td_t));
1019 
1020         /* Process the result */
1021         if (result == DDI_DMA_MAPPED) {
1022                 /* The cookie count should be 1 */
1023                 if (ccount != 1) {
1024                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1025                             "ohci_allocate_pools: More than 1 cookie");
1026 
1027                         return (DDI_FAILURE);
1028                 }
1029         } else {
1030                 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1031                     "ohci_allocate_pools: Result = %d", result);
1032 
1033                 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1034 
1035                 return (DDI_FAILURE);
1036         }
1037 
1038         /*
1039          * DMA addresses for TD pools are bound
1040          */
1041         ohcip->ohci_dma_addr_bind_flag |= OHCI_TD_POOL_BOUND;
1042 
1043         /* Initialize the TD pool */
1044         for (i = 0; i < ohci_td_pool_size; i ++) {
1045                 Set_TD(ohcip->ohci_td_pool_addr[i].hctd_state, HC_TD_FREE);
1046         }
1047 
1048         /* Byte alignment to ED alignment */
1049         ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ED_ALIGNMENT;
1050 
1051         /* Allocate the ED pool DMA handle */
1052         if (ddi_dma_alloc_handle(ohcip->ohci_dip,
1053             &ohcip->ohci_dma_attr,
1054             DDI_DMA_SLEEP,
1055             0,
1056             &ohcip->ohci_ed_pool_dma_handle) != DDI_SUCCESS) {
1057 
1058                 return (DDI_FAILURE);
1059         }
1060 
1061         /* Allocate the memory for the ED pool */
1062         if (ddi_dma_mem_alloc(ohcip->ohci_ed_pool_dma_handle,
1063             ohci_ed_pool_size * sizeof (ohci_ed_t),
1064             &dev_attr,
1065             DDI_DMA_CONSISTENT,
1066             DDI_DMA_SLEEP,
1067             0,
1068             (caddr_t *)&ohcip->ohci_ed_pool_addr,
1069             &real_length,
1070             &ohcip->ohci_ed_pool_mem_handle) != DDI_SUCCESS) {
1071 
1072                 return (DDI_FAILURE);
1073         }
1074 
1075         result = ddi_dma_addr_bind_handle(ohcip->ohci_ed_pool_dma_handle,
1076             NULL,
1077             (caddr_t)ohcip->ohci_ed_pool_addr,
1078             real_length,
1079             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1080             DDI_DMA_SLEEP,
1081             NULL,
1082             &ohcip->ohci_ed_pool_cookie,
1083             &ccount);
1084 
1085         bzero((void *)ohcip->ohci_ed_pool_addr,
1086             ohci_ed_pool_size * sizeof (ohci_ed_t));
1087 
1088         /* Process the result */
1089         if (result == DDI_DMA_MAPPED) {
1090                 /* The cookie count should be 1 */
1091                 if (ccount != 1) {
1092                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1093                             "ohci_allocate_pools: More than 1 cookie");
1094 
1095                         return (DDI_FAILURE);
1096                 }
1097         } else {
1098                 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1099 
1100                 return (DDI_FAILURE);
1101         }
1102 
1103         /*
1104          * DMA addresses for ED pools are bound
1105          */
1106         ohcip->ohci_dma_addr_bind_flag |= OHCI_ED_POOL_BOUND;
1107 
1108         /* Initialize the ED pool */
1109         for (i = 0; i < ohci_ed_pool_size; i ++) {
1110                 Set_ED(ohcip->ohci_ed_pool_addr[i].hced_state, HC_EPT_FREE);
1111         }
1112 
1113         return (DDI_SUCCESS);
1114 }
1115 
1116 
1117 /*
1118  * ohci_decode_ddi_dma_addr_bind_handle_result:
1119  *
1120  * Process the return values of ddi_dma_addr_bind_handle()
1121  */
1122 static void
1123 ohci_decode_ddi_dma_addr_bind_handle_result(
1124         ohci_state_t    *ohcip,
1125         int             result)
1126 {
1127         USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
1128             "ohci_decode_ddi_dma_addr_bind_handle_result:");
1129 
1130         switch (result) {
1131         case DDI_DMA_PARTIAL_MAP:
1132                 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1133                     "Partial transfers not allowed");
1134                 break;
1135         case DDI_DMA_INUSE:
1136                 USB_DPRINTF_L2(PRINT_MASK_ALL,  ohcip->ohci_log_hdl,
1137                     "Handle is in use");
1138                 break;
1139         case DDI_DMA_NORESOURCES:
1140                 USB_DPRINTF_L2(PRINT_MASK_ALL,  ohcip->ohci_log_hdl,
1141                     "No resources");
1142                 break;
1143         case DDI_DMA_NOMAPPING:
1144                 USB_DPRINTF_L2(PRINT_MASK_ALL,  ohcip->ohci_log_hdl,
1145                     "No mapping");
1146                 break;
1147         case DDI_DMA_TOOBIG:
1148                 USB_DPRINTF_L2(PRINT_MASK_ALL,  ohcip->ohci_log_hdl,
1149                     "Object is too big");
1150                 break;
1151         default:
1152                 USB_DPRINTF_L2(PRINT_MASK_ALL,  ohcip->ohci_log_hdl,
1153                     "Unknown dma error");
1154         }
1155 }
1156 
1157 
1158 /*
1159  * ohci_map_regs:
1160  *
1161  * The Host Controller (HC) contains a set of on-chip operational registers
1162  * and which should be mapped into a non-cacheable portion of the  system
1163  * addressable space.
1164  */
1165 static int
1166 ohci_map_regs(ohci_state_t      *ohcip)
1167 {
1168         ddi_device_acc_attr_t   attr;
1169         uint16_t                cmd_reg;
1170 
1171         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_map_regs:");
1172 
1173         /* The host controller will be little endian */
1174         attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1175         attr.devacc_attr_endian_flags  = DDI_STRUCTURE_LE_ACC;
1176         attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1177 
1178         /* Map in operational registers */
1179         if (ddi_regs_map_setup(ohcip->ohci_dip, 1,
1180             (caddr_t *)&ohcip->ohci_regsp, 0,
1181             sizeof (ohci_regs_t), &attr,
1182             &ohcip->ohci_regs_handle) != DDI_SUCCESS) {
1183 
1184                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1185                     "ohci_map_regs: Map setup error");
1186 
1187                 return (DDI_FAILURE);
1188         }
1189 
1190         if (pci_config_setup(ohcip->ohci_dip,
1191             &ohcip->ohci_config_handle) != DDI_SUCCESS) {
1192 
1193                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1194                     "ohci_map_regs: Config error");
1195 
1196                 return (DDI_FAILURE);
1197         }
1198 
1199         /* Make sure Memory Access Enable and Master Enable are set */
1200         cmd_reg = pci_config_get16(ohcip->ohci_config_handle, PCI_CONF_COMM);
1201 
1202         if (!(cmd_reg & PCI_COMM_MAE)) {
1203 
1204                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1205                     "ohci_map_regs: Memory base address access disabled");
1206 
1207                 return (DDI_FAILURE);
1208         }
1209 
1210         cmd_reg |= (PCI_COMM_MAE | PCI_COMM_ME);
1211 
1212         pci_config_put16(ohcip->ohci_config_handle, PCI_CONF_COMM, cmd_reg);
1213 
1214         return (DDI_SUCCESS);
1215 }
1216 
1217 /*
1218  * The following simulated polling is for debugging purposes only.
1219  * It is activated on x86 by setting usb-polling=true in GRUB or ohci.conf.
1220  */
1221 static int
1222 ohci_is_polled(dev_info_t *dip)
1223 {
1224         int ret;
1225         char *propval;
1226 
1227         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
1228             "usb-polling", &propval) != DDI_SUCCESS)
1229 
1230                 return (0);
1231 
1232         ret = (strcmp(propval, "true") == 0);
1233         ddi_prop_free(propval);
1234 
1235         return (ret);
1236 }
1237 
1238 static void
1239 ohci_poll_intr(void *arg)
1240 {
1241         /* poll every millisecond */
1242         for (;;) {
1243                 (void) ohci_intr(arg, NULL);
1244                 delay(drv_usectohz(1000));
1245         }
1246 }
1247 
1248 /*
1249  * ohci_register_intrs_and_init_mutex:
1250  *
1251  * Register interrupts and initialize each mutex and condition variables
1252  */
1253 static int
1254 ohci_register_intrs_and_init_mutex(ohci_state_t *ohcip)
1255 {
1256         int     intr_types;
1257 
1258         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1259             "ohci_register_intrs_and_init_mutex:");
1260 
1261         /*
1262          * Sometimes the OHCI controller of ULI1575 southbridge
1263          * could not receive SOF intrs when enable MSI. Hence
1264          * MSI is disabled for this chip.
1265          */
1266         if ((ohcip->ohci_vendor_id == PCI_ULI1575_VENID) &&
1267             (ohcip->ohci_device_id == PCI_ULI1575_DEVID)) {
1268                 ohcip->ohci_msi_enabled = B_FALSE;
1269         } else {
1270                 ohcip->ohci_msi_enabled = ohci_enable_msi;
1271         }
1272 
1273         if (ohci_is_polled(ohcip->ohci_dip)) {
1274                 extern pri_t maxclsyspri;
1275 
1276                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1277                     "ohci_register_intrs_and_init_mutex: "
1278                     "running in simulated polled mode");
1279 
1280                 (void) thread_create(NULL, 0, ohci_poll_intr, ohcip, 0, &p0,
1281                     TS_RUN, maxclsyspri);
1282 
1283                 goto skip_intr;
1284         }
1285 
1286         /* Get supported interrupt types */
1287         if (ddi_intr_get_supported_types(ohcip->ohci_dip,
1288             &intr_types) != DDI_SUCCESS) {
1289                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1290                     "ohci_register_intrs_and_init_mutex: "
1291                     "ddi_intr_get_supported_types failed");
1292 
1293                 return (DDI_FAILURE);
1294         }
1295 
1296         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1297             "ohci_register_intrs_and_init_mutex: "
1298             "supported interrupt types 0x%x", intr_types);
1299 
1300         if ((intr_types & DDI_INTR_TYPE_MSI) && ohcip->ohci_msi_enabled) {
1301                 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_MSI)
1302                     != DDI_SUCCESS) {
1303                         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1304                             "ohci_register_intrs_and_init_mutex: MSI "
1305                             "registration failed, trying FIXED interrupt \n");
1306                 } else {
1307                         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1308                             "ohci_register_intrs_and_init_mutex: "
1309                             "Using MSI interrupt type\n");
1310 
1311                         ohcip->ohci_intr_type = DDI_INTR_TYPE_MSI;
1312                         ohcip->ohci_flags |= OHCI_INTR;
1313                 }
1314         }
1315 
1316         if ((!(ohcip->ohci_flags & OHCI_INTR)) &&
1317             (intr_types & DDI_INTR_TYPE_FIXED)) {
1318                 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_FIXED)
1319                     != DDI_SUCCESS) {
1320                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1321                             "ohci_register_intrs_and_init_mutex: "
1322                             "FIXED interrupt registration failed\n");
1323 
1324                         return (DDI_FAILURE);
1325                 }
1326 
1327                 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1328                     "ohci_register_intrs_and_init_mutex: "
1329                     "Using FIXED interrupt type\n");
1330 
1331                 ohcip->ohci_intr_type = DDI_INTR_TYPE_FIXED;
1332                 ohcip->ohci_flags |= OHCI_INTR;
1333         }
1334 
1335 skip_intr:
1336         /* Create prototype for SOF condition variable */
1337         cv_init(&ohcip->ohci_SOF_cv, NULL, CV_DRIVER, NULL);
1338 
1339         /* Semaphore to serialize opens and closes */
1340         sema_init(&ohcip->ohci_ocsem, 1, NULL, SEMA_DRIVER, NULL);
1341 
1342         return (DDI_SUCCESS);
1343 }
1344 
1345 
1346 /*
1347  * ohci_add_intrs:
1348  *
1349  * Register FIXED or MSI interrupts.
1350  */
1351 static int
1352 ohci_add_intrs(ohci_state_t     *ohcip,
1353                 int             intr_type)
1354 {
1355         int     actual, avail, intr_size, count = 0;
1356         int     i, flag, ret;
1357 
1358         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1359             "ohci_add_intrs: interrupt type 0x%x", intr_type);
1360 
1361         /* Get number of interrupts */
1362         ret = ddi_intr_get_nintrs(ohcip->ohci_dip, intr_type, &count);
1363         if ((ret != DDI_SUCCESS) || (count == 0)) {
1364                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1365                     "ohci_add_intrs: ddi_intr_get_nintrs() failure, "
1366                     "ret: %d, count: %d", ret, count);
1367 
1368                 return (DDI_FAILURE);
1369         }
1370 
1371         /* Get number of available interrupts */
1372         ret = ddi_intr_get_navail(ohcip->ohci_dip, intr_type, &avail);
1373         if ((ret != DDI_SUCCESS) || (avail == 0)) {
1374                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1375                     "ohci_add_intrs: ddi_intr_get_navail() failure, "
1376                     "ret: %d, count: %d", ret, count);
1377 
1378                 return (DDI_FAILURE);
1379         }
1380 
1381         if (avail < count) {
1382                 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1383                     "ohci_add_intrs: ohci_add_intrs: nintrs () "
1384                     "returned %d, navail returned %d\n", count, avail);
1385         }
1386 
1387         /* Allocate an array of interrupt handles */
1388         intr_size = count * sizeof (ddi_intr_handle_t);
1389         ohcip->ohci_htable = kmem_zalloc(intr_size, KM_SLEEP);
1390 
1391         flag = (intr_type == DDI_INTR_TYPE_MSI) ?
1392             DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL;
1393 
1394         /* call ddi_intr_alloc() */
1395         ret = ddi_intr_alloc(ohcip->ohci_dip, ohcip->ohci_htable,
1396             intr_type, 0, count, &actual, flag);
1397 
1398         if ((ret != DDI_SUCCESS) || (actual == 0)) {
1399                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1400                     "ohci_add_intrs: ddi_intr_alloc() failed %d", ret);
1401 
1402                 kmem_free(ohcip->ohci_htable, intr_size);
1403 
1404                 return (DDI_FAILURE);
1405         }
1406 
1407         if (actual < count) {
1408                 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1409                     "ohci_add_intrs: Requested: %d, Received: %d\n",
1410                     count, actual);
1411 
1412                 for (i = 0; i < actual; i++)
1413                         (void) ddi_intr_free(ohcip->ohci_htable[i]);
1414 
1415                 kmem_free(ohcip->ohci_htable, intr_size);
1416 
1417                 return (DDI_FAILURE);
1418         }
1419 
1420         ohcip->ohci_intr_cnt = actual;
1421 
1422         if ((ret = ddi_intr_get_pri(ohcip->ohci_htable[0],
1423             &ohcip->ohci_intr_pri)) != DDI_SUCCESS) {
1424                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1425                     "ohci_add_intrs: ddi_intr_get_pri() failed %d", ret);
1426 
1427                 for (i = 0; i < actual; i++)
1428                         (void) ddi_intr_free(ohcip->ohci_htable[i]);
1429 
1430                 kmem_free(ohcip->ohci_htable, intr_size);
1431 
1432                 return (DDI_FAILURE);
1433         }
1434 
1435         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1436             "ohci_add_intrs: Supported Interrupt priority 0x%x",
1437             ohcip->ohci_intr_pri);
1438 
1439         /* Test for high level mutex */
1440         if (ohcip->ohci_intr_pri >= ddi_intr_get_hilevel_pri()) {
1441                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1442                     "ohci_add_intrs: Hi level interrupt not supported");
1443 
1444                 for (i = 0; i < actual; i++)
1445                         (void) ddi_intr_free(ohcip->ohci_htable[i]);
1446 
1447                 kmem_free(ohcip->ohci_htable, intr_size);
1448 
1449                 return (DDI_FAILURE);
1450         }
1451 
1452         /* Initialize the mutex */
1453         mutex_init(&ohcip->ohci_int_mutex, NULL, MUTEX_DRIVER,
1454             DDI_INTR_PRI(ohcip->ohci_intr_pri));
1455 
1456         /* Call ddi_intr_add_handler() */
1457         for (i = 0; i < actual; i++) {
1458                 if ((ret = ddi_intr_add_handler(ohcip->ohci_htable[i],
1459                     ohci_intr, (caddr_t)ohcip,
1460                     (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
1461                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1462                             "ohci_add_intrs: ddi_intr_add_handler() "
1463                             "failed %d", ret);
1464 
1465                         for (i = 0; i < actual; i++)
1466                                 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1467 
1468                         mutex_destroy(&ohcip->ohci_int_mutex);
1469                         kmem_free(ohcip->ohci_htable, intr_size);
1470 
1471                         return (DDI_FAILURE);
1472                 }
1473         }
1474 
1475         if ((ret = ddi_intr_get_cap(ohcip->ohci_htable[0],
1476             &ohcip->ohci_intr_cap)) != DDI_SUCCESS) {
1477                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1478                     "ohci_add_intrs: ddi_intr_get_cap() failed %d", ret);
1479 
1480                 for (i = 0; i < actual; i++) {
1481                         (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]);
1482                         (void) ddi_intr_free(ohcip->ohci_htable[i]);
1483                 }
1484 
1485                 mutex_destroy(&ohcip->ohci_int_mutex);
1486                 kmem_free(ohcip->ohci_htable, intr_size);
1487 
1488                 return (DDI_FAILURE);
1489         }
1490 
1491         /* Enable all interrupts */
1492         if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) {
1493                 /* Call ddi_intr_block_enable() for MSI interrupts */
1494                 (void) ddi_intr_block_enable(ohcip->ohci_htable,
1495                     ohcip->ohci_intr_cnt);
1496         } else {
1497                 /* Call ddi_intr_enable for MSI or FIXED interrupts */
1498                 for (i = 0; i < ohcip->ohci_intr_cnt; i++)
1499                         (void) ddi_intr_enable(ohcip->ohci_htable[i]);
1500         }
1501 
1502         return (DDI_SUCCESS);
1503 }
1504 
1505 
1506 /*
1507  * ohci_init_ctlr:
1508  *
1509  * Initialize the Host Controller (HC).
1510  */
1511 static int
1512 ohci_init_ctlr(ohci_state_t     *ohcip)
1513 {
1514         int                     revision, curr_control, max_packet = 0;
1515         clock_t                 sof_time_wait;
1516         int                     retry = 0;
1517         int                     ohci_frame_interval;
1518 
1519         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_ctlr:");
1520 
1521         if (ohci_take_control(ohcip) != DDI_SUCCESS) {
1522                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1523                     "ohci_init_ctlr: ohci_take_control failed\n");
1524 
1525                 return (DDI_FAILURE);
1526         }
1527 
1528         /*
1529          * Soft reset the host controller.
1530          *
1531          * On soft reset, the ohci host controller moves to the
1532          * USB Suspend state in which most of the ohci operational
1533          * registers are reset except stated ones. The soft reset
1534          * doesn't cause a reset to the ohci root hub and even no
1535          * subsequent reset signaling should be asserterd to its
1536          * down stream.
1537          */
1538         Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
1539 
1540         mutex_exit(&ohcip->ohci_int_mutex);
1541         /* Wait 10ms for reset to complete */
1542         delay(drv_usectohz(OHCI_RESET_TIMEWAIT));
1543         mutex_enter(&ohcip->ohci_int_mutex);
1544 
1545         /*
1546          * Do hard reset the host controller.
1547          *
1548          * Now perform USB reset in order to reset the ohci root
1549          * hub.
1550          */
1551         Set_OpReg(hcr_control, HCR_CONTROL_RESET);
1552 
1553         /*
1554          * According to Section 5.1.2.3 of the specification, the
1555          * host controller will go into suspend state immediately
1556          * after the reset.
1557          */
1558 
1559         /* Verify the version number */
1560         revision = Get_OpReg(hcr_revision);
1561 
1562         if ((revision & HCR_REVISION_MASK) != HCR_REVISION_1_0) {
1563 
1564                 return (DDI_FAILURE);
1565         }
1566 
1567         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1568             "ohci_init_ctlr: Revision verified");
1569 
1570         /* hcca area need not be initialized on resume */
1571         if (ohcip->ohci_hc_soft_state == OHCI_CTLR_INIT_STATE) {
1572 
1573                 /* Initialize the hcca area */
1574                 if (ohci_init_hcca(ohcip) != DDI_SUCCESS) {
1575 
1576                         return (DDI_FAILURE);
1577                 }
1578         }
1579 
1580         /*
1581          * Workaround for ULI1575 chipset. Following OHCI Operational Memory
1582          * Registers are not cleared to their default value on reset.
1583          * Explicitly set the registers to default value.
1584          */
1585         if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
1586             ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
1587                 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
1588                 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
1589                 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
1590                 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
1591                 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
1592                 Set_OpReg(hcr_frame_interval, HCR_FRAME_INTERVAL_DEFAULT);
1593                 Set_OpReg(hcr_periodic_strt, HCR_PERIODIC_START_DEFAULT);
1594         }
1595 
1596         /* Set the HcHCCA to the physical address of the HCCA block */
1597         Set_OpReg(hcr_HCCA, (uint_t)ohcip->ohci_hcca_cookie.dmac_address);
1598 
1599         /*
1600          * Set HcInterruptEnable to enable all interrupts except Root
1601          * Hub Status change and SOF interrupts.
1602          */
1603         Set_OpReg(hcr_intr_enable, HCR_INTR_SO | HCR_INTR_WDH |
1604             HCR_INTR_RD | HCR_INTR_UE | HCR_INTR_FNO | HCR_INTR_MIE);
1605 
1606         /*
1607          * For non-periodic transfers, reserve atleast for one low-speed
1608          * device transaction. According to USB Bandwidth Analysis white
1609          * paper and also as per OHCI Specification 1.0a, section 7.3.5,
1610          * page 123, one low-speed transaction takes 0x628h full speed
1611          * bits (197 bytes), which comes to around 13% of USB frame time.
1612          *
1613          * The periodic transfers will get around 87% of USB frame time.
1614          */
1615         Set_OpReg(hcr_periodic_strt,
1616             ((PERIODIC_XFER_STARTS * BITS_PER_BYTE) - 1));
1617 
1618         /* Save the contents of the Frame Interval Registers */
1619         ohcip->ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1620 
1621         /*
1622          * Initialize the FSLargestDataPacket value in the frame interval
1623          * register. The controller compares the value of MaxPacketSize to
1624          * this value to see if the entire packet may be sent out before
1625          * the EOF.
1626          */
1627         max_packet = ((((ohcip->ohci_frame_interval -
1628             MAX_OVERHEAD) * 6) / 7) << HCR_FRME_FSMPS_SHFT);
1629 
1630         Set_OpReg(hcr_frame_interval,
1631             (max_packet | ohcip->ohci_frame_interval));
1632 
1633         /*
1634          * Sometimes the HcFmInterval register in OHCI controller does not
1635          * maintain its value after the first write. This problem is found
1636          * on ULI M1575 South Bridge. To workaround the hardware problem,
1637          * check the value after write and retry if the last write failed.
1638          */
1639         if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
1640             ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
1641                 ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1642                 while ((ohci_frame_interval != (max_packet |
1643                     ohcip->ohci_frame_interval))) {
1644                         if (retry >= 10) {
1645                                 USB_DPRINTF_L1(PRINT_MASK_ATTA,
1646                                     ohcip->ohci_log_hdl, "Failed to program"
1647                                     " Frame Interval Register.");
1648 
1649                                 return (DDI_FAILURE);
1650                         }
1651                         retry++;
1652                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1653                             "ohci_init_ctlr: Failed to program Frame"
1654                             " Interval Register, retry=%d", retry);
1655                         Set_OpReg(hcr_frame_interval,
1656                             (max_packet | ohcip->ohci_frame_interval));
1657                         ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1658                 }
1659         }
1660 
1661         /* Begin sending SOFs */
1662         curr_control = Get_OpReg(hcr_control);
1663 
1664         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1665             "ohci_init_ctlr: curr_control=0x%x", curr_control);
1666 
1667         /* Set the state to operational */
1668         curr_control = (curr_control &
1669             (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT;
1670 
1671         Set_OpReg(hcr_control, curr_control);
1672 
1673         ASSERT((Get_OpReg(hcr_control) &
1674             HCR_CONTROL_HCFS) == HCR_CONTROL_OPERAT);
1675 
1676         /* Set host controller soft state to operational */
1677         ohcip->ohci_hc_soft_state = OHCI_CTLR_OPERATIONAL_STATE;
1678 
1679         /* Get the number of clock ticks to wait */
1680         sof_time_wait = drv_sectohz(OHCI_MAX_SOF_TIMEWAIT);
1681 
1682         /* Clear ohci_sof_flag indicating waiting for SOF interrupt */
1683         ohcip->ohci_sof_flag = B_FALSE;
1684 
1685         /* Enable the SOF interrupt */
1686         Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
1687 
1688         ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF);
1689 
1690         (void) cv_reltimedwait(&ohcip->ohci_SOF_cv,
1691             &ohcip->ohci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
1692 
1693         /* Wait for the SOF or timeout event */
1694         if (ohcip->ohci_sof_flag == B_FALSE) {
1695 
1696                 /* Set host controller soft state to error */
1697                 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE;
1698 
1699                 USB_DPRINTF_L0(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1700                     "No SOF interrupts have been received, this USB OHCI host"
1701                     "controller is unusable");
1702                 return (DDI_FAILURE);
1703         }
1704 
1705         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1706             "ohci_init_ctlr: SOF's have started");
1707 
1708         return (DDI_SUCCESS);
1709 }
1710 
1711 
1712 /*
1713  * ohci_init_hcca:
1714  *
1715  * Allocate the system memory and initialize Host Controller Communication
1716  * Area (HCCA). The HCCA structure must be aligned to a 256-byte boundary.
1717  */
1718 static int
1719 ohci_init_hcca(ohci_state_t     *ohcip)
1720 {
1721         ddi_device_acc_attr_t   dev_attr;
1722         size_t                  real_length;
1723         uint_t                  mask, ccount;
1724         int                     result;
1725         uintptr_t               addr;
1726 
1727         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
1728 
1729         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_hcca:");
1730 
1731         /* The host controller will be little endian */
1732         dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1733         dev_attr.devacc_attr_endian_flags  = DDI_STRUCTURE_LE_ACC;
1734         dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1735 
1736         /* Byte alignment to HCCA alignment */
1737         ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_HCCA_ALIGNMENT;
1738 
1739         /* Create space for the HCCA block */
1740         if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr,
1741             DDI_DMA_SLEEP,
1742             0,
1743             &ohcip->ohci_hcca_dma_handle)
1744             != DDI_SUCCESS) {
1745 
1746                 return (DDI_FAILURE);
1747         }
1748 
1749         if (ddi_dma_mem_alloc(ohcip->ohci_hcca_dma_handle,
1750             2 * sizeof (ohci_hcca_t),
1751             &dev_attr,
1752             DDI_DMA_CONSISTENT,
1753             DDI_DMA_SLEEP,
1754             0,
1755             (caddr_t *)&ohcip->ohci_hccap,
1756             &real_length,
1757             &ohcip->ohci_hcca_mem_handle)) {
1758 
1759                 return (DDI_FAILURE);
1760         }
1761 
1762         bzero((void *)ohcip->ohci_hccap, real_length);
1763 
1764         /* Figure out the alignment requirements */
1765         Set_OpReg(hcr_HCCA, 0xFFFFFFFF);
1766 
1767         /*
1768          * Read the hcr_HCCA register until
1769          * contenets are non-zero.
1770          */
1771         mask = Get_OpReg(hcr_HCCA);
1772 
1773         mutex_exit(&ohcip->ohci_int_mutex);
1774         while (mask == 0) {
1775                 delay(drv_usectohz(OHCI_TIMEWAIT));
1776                 mask = Get_OpReg(hcr_HCCA);
1777         }
1778         mutex_enter(&ohcip->ohci_int_mutex);
1779 
1780         ASSERT(mask != 0);
1781 
1782         addr = (uintptr_t)ohcip->ohci_hccap;
1783 
1784         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1785             "ohci_init_hcca: addr=0x%lx, mask=0x%x", addr, mask);
1786 
1787         while (addr & (~mask)) {
1788                 addr++;
1789         }
1790 
1791         ohcip->ohci_hccap = (ohci_hcca_t *)addr;
1792 
1793         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1794             "ohci_init_hcca: Real length %lu", real_length);
1795 
1796         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1797             "ohci_init_hcca: virtual hcca 0x%p", (void *)ohcip->ohci_hccap);
1798 
1799         /* Map the whole HCCA into the I/O address space */
1800         result = ddi_dma_addr_bind_handle(ohcip->ohci_hcca_dma_handle,
1801             NULL,
1802             (caddr_t)ohcip->ohci_hccap,
1803             real_length,
1804             DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1805             DDI_DMA_SLEEP, NULL,
1806             &ohcip->ohci_hcca_cookie,
1807             &ccount);
1808 
1809         if (result == DDI_DMA_MAPPED) {
1810                 /* The cookie count should be 1 */
1811                 if (ccount != 1) {
1812                         USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1813                             "ohci_init_hcca: More than 1 cookie");
1814 
1815                         return (DDI_FAILURE);
1816                 }
1817         } else {
1818                 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1819 
1820                 return (DDI_FAILURE);
1821         }
1822 
1823         /*
1824          * DMA addresses for HCCA are bound
1825          */
1826         ohcip->ohci_dma_addr_bind_flag |= OHCI_HCCA_DMA_BOUND;
1827 
1828         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1829             "ohci_init_hcca: physical 0x%p",
1830             (void *)(uintptr_t)ohcip->ohci_hcca_cookie.dmac_address);
1831 
1832         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1833             "ohci_init_hcca: size %lu", ohcip->ohci_hcca_cookie.dmac_size);
1834 
1835         /* Initialize the interrupt lists */
1836         ohci_build_interrupt_lattice(ohcip);
1837 
1838         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1839             "ohci_init_hcca: End");
1840 
1841         return (DDI_SUCCESS);
1842 }
1843 
1844 
1845 /*
1846  * ohci_build_interrupt_lattice:
1847  *
1848  * Construct the interrupt lattice tree using static Endpoint Descriptors
1849  * (ED). This interrupt lattice tree will have total of 32 interrupt  ED
1850  * lists and the Host Controller (HC) processes one interrupt ED list in
1851  * every frame. The lower five bits of the current frame number indexes
1852  * into an array of 32 interrupt Endpoint Descriptor lists found in the
1853  * HCCA.
1854  */
1855 static void
1856 ohci_build_interrupt_lattice(ohci_state_t       *ohcip)
1857 {
1858         ohci_ed_t       *list_array = ohcip->ohci_ed_pool_addr;
1859         int             half_list = NUM_INTR_ED_LISTS / 2;
1860         ohci_hcca_t     *hccap = ohcip->ohci_hccap;
1861         uintptr_t       addr;
1862         int             i;
1863 
1864         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1865             "ohci_build_interrupt_lattice:");
1866 
1867         /*
1868          * Reserve the first 31 Endpoint Descriptor (ED) structures
1869          * in the pool as static endpoints & these are required for
1870          * constructing interrupt lattice tree.
1871          */
1872         for (i = 0; i < NUM_STATIC_NODES; i++) {
1873                 Set_ED(list_array[i].hced_ctrl, HC_EPT_sKip);
1874 
1875                 Set_ED(list_array[i].hced_state, HC_EPT_STATIC);
1876         }
1877 
1878         /* Build the interrupt lattice tree */
1879         for (i = 0; i < half_list - 1; i++) {
1880 
1881                 /*
1882                  * The next  pointer in the host controller  endpoint
1883                  * descriptor must contain an iommu address. Calculate
1884                  * the offset into the cpu address and add this to the
1885                  * starting iommu address.
1886                  */
1887                 addr = ohci_ed_cpu_to_iommu(ohcip, (ohci_ed_t *)&list_array[i]);
1888 
1889                 Set_ED(list_array[2*i + 1].hced_next, addr);
1890                 Set_ED(list_array[2*i + 2].hced_next, addr);
1891         }
1892 
1893         /*
1894          * Initialize the interrupt list in the HCCA so that it points
1895          * to the bottom of the tree.
1896          */
1897         for (i = 0; i < half_list; i++) {
1898                 addr = ohci_ed_cpu_to_iommu(ohcip,
1899                     (ohci_ed_t *)&list_array[half_list - 1 + ohci_index[i]]);
1900 
1901                 ASSERT(Get_ED(list_array[half_list - 1 +
1902                     ohci_index[i]].hced_ctrl));
1903 
1904                 ASSERT(addr != 0);
1905 
1906                 Set_HCCA(hccap->HccaIntTble[i], addr);
1907                 Set_HCCA(hccap->HccaIntTble[i + half_list], addr);
1908         }
1909 }
1910 
1911 
1912 /*
1913  * ohci_take_control:
1914  *
1915  * Take control of the host controller. OpenHCI allows for optional support
1916  * of legacy devices through the use of System Management Mode software and
1917  * system Management interrupt hardware. See section 5.1.1.3 of the OpenHCI
1918  * spec for more details.
1919  */
1920 static int
1921 ohci_take_control(ohci_state_t  *ohcip)
1922 {
1923 #if defined(__x86)
1924         uint32_t hcr_control_val;
1925         uint32_t hcr_cmd_status_val;
1926         int wait;
1927 #endif  /* __x86 */
1928 
1929         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1930             "ohci_take_control:");
1931 
1932 #if defined(__x86)
1933         /*
1934          * On x86, we must tell the BIOS we want the controller,
1935          * and wait for it to respond that we can have it.
1936          */
1937         hcr_control_val = Get_OpReg(hcr_control);
1938         if ((hcr_control_val & HCR_CONTROL_IR) == 0) {
1939                 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1940                     "ohci_take_control: InterruptRouting off\n");
1941 
1942                 return (DDI_SUCCESS);
1943         }
1944 
1945         /* attempt the OwnershipChange request */
1946         hcr_cmd_status_val = Get_OpReg(hcr_cmd_status);
1947         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1948             "ohci_take_control: hcr_cmd_status: 0x%x\n",
1949             hcr_cmd_status_val);
1950         hcr_cmd_status_val |= HCR_STATUS_OCR;
1951 
1952         Set_OpReg(hcr_cmd_status, hcr_cmd_status_val);
1953 
1954 
1955         mutex_exit(&ohcip->ohci_int_mutex);
1956         /* now wait for 5 seconds for InterruptRouting to go away */
1957         for (wait = 0; wait < 5000; wait++) {
1958                 if ((Get_OpReg(hcr_control) & HCR_CONTROL_IR) == 0)
1959                         break;
1960                 delay(drv_usectohz(1000));
1961         }
1962         mutex_enter(&ohcip->ohci_int_mutex);
1963 
1964         if (wait >= 5000) {
1965                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1966                     "ohci_take_control: couldn't take control from BIOS\n");
1967 
1968                 return (DDI_FAILURE);
1969         }
1970 #else   /* __x86 */
1971         /*
1972          * On Sparc, there won't be  special System Management Mode
1973          * hardware for legacy devices, while the x86 platforms may
1974          * have to deal with  this. This  function may be  platform
1975          * specific.
1976          *
1977          * The interrupt routing bit should not be set.
1978          */
1979         if (Get_OpReg(hcr_control) & HCR_CONTROL_IR) {
1980                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1981                     "ohci_take_control: Routing bit set");
1982 
1983                 return (DDI_FAILURE);
1984         }
1985 #endif  /* __x86 */
1986 
1987         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1988             "ohci_take_control: End");
1989 
1990         return (DDI_SUCCESS);
1991 }
1992 
1993 /*
1994  * ohci_pm_support:
1995  *      always return success since PM has been quite reliable on ohci
1996  */
1997 /*ARGSUSED*/
1998 int
1999 ohci_hcdi_pm_support(dev_info_t *dip)
2000 {
2001         return (USB_SUCCESS);
2002 }
2003 
2004 /*
2005  * ohci_alloc_hcdi_ops:
2006  *
2007  * The HCDI interfaces or entry points are the software interfaces used by
2008  * the Universal Serial Bus Driver  (USBA) to  access the services of the
2009  * Host Controller Driver (HCD).  During HCD initialization, inform  USBA
2010  * about all available HCDI interfaces or entry points.
2011  */
2012 static usba_hcdi_ops_t *
2013 ohci_alloc_hcdi_ops(ohci_state_t        *ohcip)
2014 {
2015         usba_hcdi_ops_t                 *usba_hcdi_ops;
2016 
2017         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2018             "ohci_alloc_hcdi_ops:");
2019 
2020         usba_hcdi_ops = usba_alloc_hcdi_ops();
2021 
2022         usba_hcdi_ops->usba_hcdi_ops_version = HCDI_OPS_VERSION;
2023 
2024         usba_hcdi_ops->usba_hcdi_pm_support = ohci_hcdi_pm_support;
2025         usba_hcdi_ops->usba_hcdi_pipe_open = ohci_hcdi_pipe_open;
2026         usba_hcdi_ops->usba_hcdi_pipe_close = ohci_hcdi_pipe_close;
2027 
2028         usba_hcdi_ops->usba_hcdi_pipe_reset = ohci_hcdi_pipe_reset;
2029         usba_hcdi_ops->usba_hcdi_pipe_reset_data_toggle =
2030             ohci_hcdi_pipe_reset_data_toggle;
2031 
2032         usba_hcdi_ops->usba_hcdi_pipe_ctrl_xfer = ohci_hcdi_pipe_ctrl_xfer;
2033         usba_hcdi_ops->usba_hcdi_pipe_bulk_xfer = ohci_hcdi_pipe_bulk_xfer;
2034         usba_hcdi_ops->usba_hcdi_pipe_intr_xfer = ohci_hcdi_pipe_intr_xfer;
2035         usba_hcdi_ops->usba_hcdi_pipe_isoc_xfer = ohci_hcdi_pipe_isoc_xfer;
2036 
2037         usba_hcdi_ops->usba_hcdi_bulk_transfer_size =
2038             ohci_hcdi_bulk_transfer_size;
2039 
2040         usba_hcdi_ops->usba_hcdi_pipe_stop_intr_polling =
2041             ohci_hcdi_pipe_stop_intr_polling;
2042         usba_hcdi_ops->usba_hcdi_pipe_stop_isoc_polling =
2043             ohci_hcdi_pipe_stop_isoc_polling;
2044 
2045         usba_hcdi_ops->usba_hcdi_get_current_frame_number =
2046             ohci_hcdi_get_current_frame_number;
2047         usba_hcdi_ops->usba_hcdi_get_max_isoc_pkts =
2048             ohci_hcdi_get_max_isoc_pkts;
2049         usba_hcdi_ops->usba_hcdi_console_input_init =
2050             ohci_hcdi_polled_input_init;
2051         usba_hcdi_ops->usba_hcdi_console_input_enter =
2052             ohci_hcdi_polled_input_enter;
2053         usba_hcdi_ops->usba_hcdi_console_read = ohci_hcdi_polled_read;
2054         usba_hcdi_ops->usba_hcdi_console_input_exit =
2055             ohci_hcdi_polled_input_exit;
2056         usba_hcdi_ops->usba_hcdi_console_input_fini =
2057             ohci_hcdi_polled_input_fini;
2058 
2059         usba_hcdi_ops->usba_hcdi_console_output_init =
2060             ohci_hcdi_polled_output_init;
2061         usba_hcdi_ops->usba_hcdi_console_output_enter =
2062             ohci_hcdi_polled_output_enter;
2063         usba_hcdi_ops->usba_hcdi_console_write = ohci_hcdi_polled_write;
2064         usba_hcdi_ops->usba_hcdi_console_output_exit =
2065             ohci_hcdi_polled_output_exit;
2066         usba_hcdi_ops->usba_hcdi_console_output_fini =
2067             ohci_hcdi_polled_output_fini;
2068 
2069         return (usba_hcdi_ops);
2070 }
2071 
2072 
2073 /*
2074  * Host Controller Driver (HCD) deinitialization functions
2075  */
2076 
2077 /*
2078  * ohci_cleanup:
2079  *
2080  * Cleanup on attach failure or detach
2081  */
2082 static int
2083 ohci_cleanup(ohci_state_t       *ohcip)
2084 {
2085         ohci_trans_wrapper_t    *tw;
2086         ohci_pipe_private_t     *pp;
2087         ohci_td_t               *td;
2088         int                     i, state, rval;
2089         int                     flags = ohcip->ohci_flags;
2090 
2091         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_cleanup:");
2092 
2093         if (flags & OHCI_RHREG) {
2094                 /* Unload the root hub driver */
2095                 if (ohci_unload_root_hub_driver(ohcip) != USB_SUCCESS) {
2096 
2097                         return (DDI_FAILURE);
2098                 }
2099         }
2100 
2101         if (flags & OHCI_USBAREG) {
2102                 /* Unregister this HCD instance with USBA */
2103                 usba_hcdi_unregister(ohcip->ohci_dip);
2104         }
2105 
2106         if (flags & OHCI_INTR) {
2107 
2108                 mutex_enter(&ohcip->ohci_int_mutex);
2109 
2110                 /* Disable all HC ED list processing */
2111                 Set_OpReg(hcr_control,
2112                     (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
2113                     HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
2114 
2115                 /* Disable all HC interrupts */
2116                 Set_OpReg(hcr_intr_disable,
2117                     (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE));
2118 
2119                 /* Wait for the next SOF */
2120                 (void) ohci_wait_for_sof(ohcip);
2121 
2122                 /* Disable Master and SOF interrupts */
2123                 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF));
2124 
2125                 /* Set the Host Controller Functional State to Reset */
2126                 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
2127                     (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET));
2128 
2129                 mutex_exit(&ohcip->ohci_int_mutex);
2130                 /* Wait for sometime */
2131                 delay(drv_usectohz(OHCI_TIMEWAIT));
2132                 mutex_enter(&ohcip->ohci_int_mutex);
2133 
2134                 /*
2135                  * Workaround for ULI1575 chipset. Following OHCI Operational
2136                  * Memory Registers are not cleared to their default value
2137                  * on reset. Explicitly set the registers to default value.
2138                  */
2139                 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
2140                     ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
2141                         Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
2142                         Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
2143                         Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
2144                         Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
2145                         Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
2146                         Set_OpReg(hcr_frame_interval,
2147                             HCR_FRAME_INTERVAL_DEFAULT);
2148                         Set_OpReg(hcr_periodic_strt,
2149                             HCR_PERIODIC_START_DEFAULT);
2150                 }
2151 
2152                 mutex_exit(&ohcip->ohci_int_mutex);
2153 
2154                 ohci_rem_intrs(ohcip);
2155         }
2156 
2157         /* Unmap the OHCI registers */
2158         if (ohcip->ohci_regs_handle) {
2159                 /* Reset the host controller */
2160                 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
2161 
2162                 ddi_regs_map_free(&ohcip->ohci_regs_handle);
2163         }
2164 
2165         if (ohcip->ohci_config_handle) {
2166                 pci_config_teardown(&ohcip->ohci_config_handle);
2167         }
2168 
2169         /* Free all the buffers */
2170         if (ohcip->ohci_td_pool_addr && ohcip->ohci_td_pool_mem_handle) {
2171                 for (i = 0; i < ohci_td_pool_size; i ++) {
2172                         td = &ohcip->ohci_td_pool_addr[i];
2173                         state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state);
2174 
2175                         if ((state != HC_TD_FREE) && (state != HC_TD_DUMMY) &&
2176                             (td->hctd_trans_wrapper)) {
2177 
2178                                 mutex_enter(&ohcip->ohci_int_mutex);
2179 
2180                                 tw = (ohci_trans_wrapper_t *)
2181                                     OHCI_LOOKUP_ID((uint32_t)
2182                                     Get_TD(td->hctd_trans_wrapper));
2183 
2184                                 /* Obtain the pipe private structure */
2185                                 pp = tw->tw_pipe_private;
2186 
2187                                 /* Stop the the transfer timer */
2188                                 ohci_stop_xfer_timer(ohcip, tw,
2189                                     OHCI_REMOVE_XFER_ALWAYS);
2190 
2191                                 ohci_deallocate_tw_resources(ohcip, pp, tw);
2192 
2193                                 mutex_exit(&ohcip->ohci_int_mutex);
2194                         }
2195                 }
2196 
2197                 /*
2198                  * If OHCI_TD_POOL_BOUND flag is set, then unbind
2199                  * the handle for TD pools.
2200                  */
2201                 if ((ohcip->ohci_dma_addr_bind_flag &
2202                     OHCI_TD_POOL_BOUND) == OHCI_TD_POOL_BOUND) {
2203 
2204                         rval = ddi_dma_unbind_handle(
2205                             ohcip->ohci_td_pool_dma_handle);
2206 
2207                         ASSERT(rval == DDI_SUCCESS);
2208                 }
2209                 ddi_dma_mem_free(&ohcip->ohci_td_pool_mem_handle);
2210         }
2211 
2212         /* Free the TD pool */
2213         if (ohcip->ohci_td_pool_dma_handle) {
2214                 ddi_dma_free_handle(&ohcip->ohci_td_pool_dma_handle);
2215         }
2216 
2217         if (ohcip->ohci_ed_pool_addr && ohcip->ohci_ed_pool_mem_handle) {
2218                 /*
2219                  * If OHCI_ED_POOL_BOUND flag is set, then unbind
2220                  * the handle for ED pools.
2221                  */
2222                 if ((ohcip->ohci_dma_addr_bind_flag &
2223                     OHCI_ED_POOL_BOUND) == OHCI_ED_POOL_BOUND) {
2224 
2225                         rval = ddi_dma_unbind_handle(
2226                             ohcip->ohci_ed_pool_dma_handle);
2227 
2228                         ASSERT(rval == DDI_SUCCESS);
2229                 }
2230 
2231                 ddi_dma_mem_free(&ohcip->ohci_ed_pool_mem_handle);
2232         }
2233 
2234         /* Free the ED pool */
2235         if (ohcip->ohci_ed_pool_dma_handle) {
2236                 ddi_dma_free_handle(&ohcip->ohci_ed_pool_dma_handle);
2237         }
2238 
2239         /* Free the HCCA area */
2240         if (ohcip->ohci_hccap && ohcip->ohci_hcca_mem_handle) {
2241                 /*
2242                  * If OHCI_HCCA_DMA_BOUND flag is set, then unbind
2243                  * the handle for HCCA.
2244                  */
2245                 if ((ohcip->ohci_dma_addr_bind_flag &
2246                     OHCI_HCCA_DMA_BOUND) == OHCI_HCCA_DMA_BOUND) {
2247 
2248                         rval = ddi_dma_unbind_handle(
2249                             ohcip->ohci_hcca_dma_handle);
2250 
2251                         ASSERT(rval == DDI_SUCCESS);
2252                 }
2253 
2254                 ddi_dma_mem_free(&ohcip->ohci_hcca_mem_handle);
2255         }
2256 
2257         if (ohcip->ohci_hcca_dma_handle) {
2258                 ddi_dma_free_handle(&ohcip->ohci_hcca_dma_handle);
2259         }
2260 
2261         if (flags & OHCI_INTR) {
2262 
2263                 /* Destroy the mutex */
2264                 mutex_destroy(&ohcip->ohci_int_mutex);
2265 
2266                 /* Destroy the SOF condition varibale */
2267                 cv_destroy(&ohcip->ohci_SOF_cv);
2268 
2269                 /* Destroy the serialize opens and closes semaphore */
2270                 sema_destroy(&ohcip->ohci_ocsem);
2271         }
2272 
2273         /* clean up kstat structs */
2274         ohci_destroy_stats(ohcip);
2275 
2276         /* Free ohci hcdi ops */
2277         if (ohcip->ohci_hcdi_ops) {
2278                 usba_free_hcdi_ops(ohcip->ohci_hcdi_ops);
2279         }
2280 
2281         if (flags & OHCI_ZALLOC) {
2282 
2283                 usb_free_log_hdl(ohcip->ohci_log_hdl);
2284 
2285                 /* Remove all properties that might have been created */
2286                 ddi_prop_remove_all(ohcip->ohci_dip);
2287 
2288                 /* Free the soft state */
2289                 ddi_soft_state_free(ohci_statep,
2290                     ddi_get_instance(ohcip->ohci_dip));
2291         }
2292 
2293         return (DDI_SUCCESS);
2294 }
2295 
2296 
2297 /*
2298  * ohci_rem_intrs:
2299  *
2300  * Unregister FIXED or MSI interrupts
2301  */
2302 static void
2303 ohci_rem_intrs(ohci_state_t     *ohcip)
2304 {
2305         int     i;
2306 
2307         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2308             "ohci_rem_intrs: interrupt type 0x%x", ohcip->ohci_intr_type);
2309 
2310         /* Disable all interrupts */
2311         if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) {
2312                 (void) ddi_intr_block_disable(ohcip->ohci_htable,
2313                     ohcip->ohci_intr_cnt);
2314         } else {
2315                 for (i = 0; i < ohcip->ohci_intr_cnt; i++) {
2316                         (void) ddi_intr_disable(ohcip->ohci_htable[i]);
2317                 }
2318         }
2319 
2320         /* Call ddi_intr_remove_handler() */
2321         for (i = 0; i < ohcip->ohci_intr_cnt; i++) {
2322                 (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]);
2323                 (void) ddi_intr_free(ohcip->ohci_htable[i]);
2324         }
2325 
2326         kmem_free(ohcip->ohci_htable,
2327             ohcip->ohci_intr_cnt * sizeof (ddi_intr_handle_t));
2328 }
2329 
2330 
2331 /*
2332  * ohci_cpr_suspend
2333  */
2334 static int
2335 ohci_cpr_suspend(ohci_state_t   *ohcip)
2336 {
2337         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2338             "ohci_cpr_suspend:");
2339 
2340         /* Call into the root hub and suspend it */
2341         if (usba_hubdi_detach(ohcip->ohci_dip, DDI_SUSPEND) != DDI_SUCCESS) {
2342 
2343                 return (DDI_FAILURE);
2344         }
2345 
2346         /* Only root hub's intr pipe should be open at this time */
2347         mutex_enter(&ohcip->ohci_int_mutex);
2348 
2349         if (ohcip->ohci_open_pipe_count > 1) {
2350 
2351                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2352                     "ohci_cpr_suspend: fails as open pipe count = %d",
2353                     ohcip->ohci_open_pipe_count);
2354 
2355                 mutex_exit(&ohcip->ohci_int_mutex);
2356 
2357                 return (DDI_FAILURE);
2358         }
2359 
2360         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2361             "ohci_cpr_suspend: Disable HC ED list processing");
2362 
2363         /* Disable all HC ED list processing */
2364         Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
2365             HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
2366 
2367         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2368             "ohci_cpr_suspend: Disable HC interrupts");
2369 
2370         /* Disable all HC interrupts */
2371         Set_OpReg(hcr_intr_disable, ~(HCR_INTR_MIE|HCR_INTR_SOF));
2372 
2373         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2374             "ohci_cpr_suspend: Wait for the next SOF");
2375 
2376         /* Wait for the next SOF */
2377         if (ohci_wait_for_sof(ohcip) != USB_SUCCESS) {
2378 
2379                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2380                     "ohci_cpr_suspend: ohci host controller suspend failed");
2381 
2382                 mutex_exit(&ohcip->ohci_int_mutex);
2383                 return (DDI_FAILURE);
2384         }
2385 
2386         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2387             "ohci_cpr_suspend: Disable Master interrupt");
2388 
2389         /*
2390          * Disable Master interrupt so that ohci driver don't
2391          * get any ohci interrupts.
2392          */
2393         Set_OpReg(hcr_intr_disable, HCR_INTR_MIE);
2394 
2395         /*
2396          * Suspend the ohci host controller
2397          * if usb keyboard is not connected.
2398          */
2399         if (ohcip->ohci_polled_kbd_count == 0 || force_ohci_off != 0) {
2400                 Set_OpReg(hcr_control, HCR_CONTROL_SUSPD);
2401         }
2402 
2403         /* Set host controller soft state to suspend */
2404         ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE;
2405 
2406         mutex_exit(&ohcip->ohci_int_mutex);
2407 
2408         return (DDI_SUCCESS);
2409 }
2410 
2411 
2412 /*
2413  * ohci_cpr_resume
2414  */
2415 static int
2416 ohci_cpr_resume(ohci_state_t    *ohcip)
2417 {
2418         mutex_enter(&ohcip->ohci_int_mutex);
2419 
2420         USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2421             "ohci_cpr_resume: Restart the controller");
2422 
2423         /* Cleanup ohci specific information across cpr */
2424         ohci_cpr_cleanup(ohcip);
2425 
2426         /* Restart the controller */
2427         if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) {
2428 
2429                 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2430                     "ohci_cpr_resume: ohci host controller resume failed ");
2431 
2432                 mutex_exit(&ohcip->ohci_int_mutex);
2433 
2434                 return (DDI_FAILURE);
2435         }
2436 
2437         mutex_exit(&ohcip->ohci_int_mutex);
2438 
2439         /* Now resume the root hub */
2440         if (usba_hubdi_attach(ohcip->ohci_dip, DDI_RESUME) != DDI_SUCCESS) {
2441 
2442                 return (DDI_FAILURE);
2443         }
2444 
2445         return (DDI_SUCCESS);
2446 }
2447 
2448 
2449 /*
2450  * HCDI entry points
2451  *
2452  * The Host Controller Driver Interfaces (HCDI) are the software interfaces
2453  * between the Universal Serial Bus Layer (USBA) and the Host Controller
2454  * Driver (HCD). The HCDI interfaces or entry points are subject to change.
2455  */
2456 
2457 /*
2458  * ohci_hcdi_pipe_open:
2459  *
2460  * Member of HCD Ops structure and called during client specific pipe open
2461  * Add the pipe to the data structure representing the device and allocate
2462  * bandwidth for the pipe if it is a interrupt or isochronous endpoint.
2463  */
2464 static int
2465 ohci_hcdi_pipe_open(
2466         usba_pipe_handle_data_t *ph,
2467         usb_flags_t             flags)
2468 {
2469         ohci_state_t            *ohcip = ohci_obtain_state(
2470             ph->p_usba_device->usb_root_hub_dip);
2471         usb_ep_descr_t          *epdt = &ph->p_ep;
2472         int                     rval, error = USB_SUCCESS;
2473         int                     kmflag = (flags & USB_FLAGS_SLEEP) ?
2474             KM_SLEEP : KM_NOSLEEP;
2475         uint_t                  node = 0;
2476         ohci_pipe_private_t     *pp;
2477 
2478         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2479             "ohci_hcdi_pipe_open: addr = 0x%x, ep%d",
2480             ph->p_usba_device->usb_addr,
2481             epdt->bEndpointAddress & USB_EP_NUM_MASK);
2482 
2483         sema_p(&ohcip->ohci_ocsem);
2484 
2485         mutex_enter(&ohcip->ohci_int_mutex);
2486         rval = ohci_state_is_operational(ohcip);
2487         mutex_exit(&ohcip->ohci_int_mutex);
2488 
2489         if (rval != USB_SUCCESS) {
2490                 sema_v(&ohcip->ohci_ocsem);
2491 
2492                 return (rval);
2493         }
2494 
2495         /*
2496          * Check and handle root hub pipe open.
2497          */
2498         if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2499 
2500                 mutex_enter(&ohcip->ohci_int_mutex);
2501                 error = ohci_handle_root_hub_pipe_open(ph, flags);
2502                 mutex_exit(&ohcip->ohci_int_mutex);
2503                 sema_v(&ohcip->ohci_ocsem);
2504 
2505                 return (error);
2506         }
2507 
2508         /*
2509          * Opening of other pipes excluding root hub pipe are
2510          * handled below. Check whether pipe is already opened.
2511          */
2512         if (ph->p_hcd_private) {
2513                 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2514                     "ohci_hcdi_pipe_open: Pipe is already opened");
2515 
2516                 sema_v(&ohcip->ohci_ocsem);
2517 
2518                 return (USB_FAILURE);
2519         }
2520 
2521         /*
2522          * A portion of the bandwidth is reserved for the non-periodic
2523          * transfers, i.e control and bulk transfers in each of one
2524          * millisecond frame period & usually it will be 10% of frame
2525          * period. Hence there is no need to check for the available
2526          * bandwidth before adding the control or bulk endpoints.
2527          *
2528          * There is a need to check for the available bandwidth before
2529          * adding the periodic transfers, i.e interrupt & isochronous,
2530          * since all these periodic transfers are guaranteed transfers.
2531          * Usually 90% of the total frame time is reserved for periodic
2532          * transfers.
2533          */
2534         if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2535 
2536                 mutex_enter(&ohcip->ohci_int_mutex);
2537                 mutex_enter(&ph->p_mutex);
2538 
2539                 error = ohci_allocate_bandwidth(ohcip, ph, &node);
2540 
2541                 if (error != USB_SUCCESS) {
2542 
2543                         USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2544                             "ohci_hcdi_pipe_open: Bandwidth allocation failed");
2545 
2546                         mutex_exit(&ph->p_mutex);
2547                         mutex_exit(&ohcip->ohci_int_mutex);
2548                         sema_v(&ohcip->ohci_ocsem);
2549 
2550                         return (error);
2551                 }
2552 
2553                 mutex_exit(&ph->p_mutex);
2554                 mutex_exit(&ohcip->ohci_int_mutex);
2555         }
2556 
2557         /* Create the HCD pipe private structure */
2558         pp = kmem_zalloc(sizeof (ohci_pipe_private_t), kmflag);
2559 
2560         /*
2561          * Return failure if ohci pipe private
2562          * structure allocation fails.
2563          */
2564         if (pp == NULL) {
2565 
2566                 mutex_enter(&ohcip->ohci_int_mutex);
2567 
2568                 /* Deallocate bandwidth */
2569                 if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2570 
2571                         mutex_enter(&ph->p_mutex);
2572                         ohci_deallocate_bandwidth(ohcip, ph);
2573                         mutex_exit(&ph->p_mutex);
2574                 }
2575 
2576                 mutex_exit(&ohcip->ohci_int_mutex);
2577                 sema_v(&ohcip->ohci_ocsem);
2578 
2579                 return (USB_NO_RESOURCES);
2580         }
2581 
2582         mutex_enter(&ohcip->ohci_int_mutex);
2583 
2584         /* Store the node in the interrupt lattice */
2585         pp->pp_node = node;
2586 
2587         /* Create prototype for xfer completion condition variable */
2588         cv_init(&pp->pp_xfer_cmpl_cv, NULL, CV_DRIVER, NULL);
2589 
2590         /* Set the state of pipe as idle */
2591         pp->pp_state = OHCI_PIPE_STATE_IDLE;
2592 
2593         /* Store a pointer to the pipe handle */
2594         pp->pp_pipe_handle = ph;
2595 
2596         mutex_enter(&ph->p_mutex);
2597 
2598         /* Store the pointer in the pipe handle */
2599         ph->p_hcd_private = (usb_opaque_t)pp;
2600 
2601         /* Store a copy of the pipe policy */
2602         bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t));
2603 
2604         mutex_exit(&ph->p_mutex);
2605 
2606         /* Allocate the host controller endpoint descriptor */
2607         pp->pp_ept = ohci_alloc_hc_ed(ohcip, ph);
2608 
2609         if (pp->pp_ept == NULL) {
2610                 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2611                     "ohci_hcdi_pipe_open: ED allocation failed");
2612 
2613                 mutex_enter(&ph->p_mutex);
2614 
2615                 /* Deallocate bandwidth */
2616                 if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2617 
2618                         ohci_deallocate_bandwidth(ohcip, ph);
2619                 }
2620 
2621                 /* Destroy the xfer completion condition varibale */
2622                 cv_destroy(&pp->pp_xfer_cmpl_cv);
2623 
2624                 /*
2625                  * Deallocate the hcd private portion
2626                  * of the pipe handle.
2627                  */
2628                 kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t));
2629 
2630                 /*
2631                  * Set the private structure in the
2632                  * pipe handle equal to NULL.
2633                  */
2634                 ph->p_hcd_private = NULL;
2635                 mutex_exit(&ph->p_mutex);
2636 
2637                 mutex_exit(&ohcip->ohci_int_mutex);
2638                 sema_v(&ohcip->ohci_ocsem);
2639 
2640                 return (USB_NO_RESOURCES);
2641         }
2642 
2643         /* Restore the data toggle information */
2644         ohci_restore_data_toggle(ohcip, ph);
2645 
2646         /*
2647          * Insert the endpoint onto the host controller's
2648          * appropriate endpoint list. The host controller
2649          * will not schedule this endpoint and will not have
2650          * any TD's to process.
2651          */
2652         ohci_insert_ed(ohcip, ph);
2653 
2654         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2655             "ohci_hcdi_pipe_open: ph = 0x%p", (void *)ph);
2656 
2657         ohcip->ohci_open_pipe_count++;
2658 
2659         mutex_exit(&ohcip->ohci_int_mutex);
2660 
2661         sema_v(&ohcip->ohci_ocsem);
2662 
2663         return (USB_SUCCESS);
2664 }
2665 
2666 
2667 /*
2668  * ohci_hcdi_pipe_close:
2669  *
2670  * Member of HCD Ops structure and called during the client  specific pipe
2671  * close. Remove the pipe and the data structure representing the device.
2672  * Deallocate  bandwidth for the pipe if it is a interrupt or isochronous
2673  * endpoint.
2674  */
2675 /* ARGSUSED */
2676 static int
2677 ohci_hcdi_pipe_close(
2678         usba_pipe_handle_data_t *ph,
2679         usb_flags_t             flags)
2680 {
2681         ohci_state_t            *ohcip = ohci_obtain_state(
2682             ph->p_usba_device->usb_root_hub_dip);
2683         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2684         usb_ep_descr_t          *eptd = &ph->p_ep;
2685         int                     error = USB_SUCCESS;
2686 
2687         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2688             "ohci_hcdi_pipe_close: addr = 0x%x, ep%d",
2689             ph->p_usba_device->usb_addr,
2690             eptd->bEndpointAddress & USB_EP_NUM_MASK);
2691 
2692         sema_p(&ohcip->ohci_ocsem);
2693 
2694         /* Check and handle root hub pipe close */
2695         if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2696 
2697                 mutex_enter(&ohcip->ohci_int_mutex);
2698                 error = ohci_handle_root_hub_pipe_close(ph);
2699                 mutex_exit(&ohcip->ohci_int_mutex);
2700                 sema_v(&ohcip->ohci_ocsem);
2701 
2702                 return (error);
2703         }
2704 
2705         ASSERT(ph->p_hcd_private != NULL);
2706 
2707         mutex_enter(&ohcip->ohci_int_mutex);
2708 
2709         /* Set pipe state to pipe close */
2710         pp->pp_state = OHCI_PIPE_STATE_CLOSE;
2711 
2712         ohci_pipe_cleanup(ohcip, ph);
2713 
2714         /*
2715          * Remove the endoint descriptor from Host
2716          * Controller's appropriate endpoint list.
2717          */
2718         ohci_remove_ed(ohcip, pp);
2719 
2720         /* Deallocate bandwidth */
2721         if (OHCI_PERIODIC_ENDPOINT(eptd)) {
2722 
2723                 mutex_enter(&ph->p_mutex);
2724                 ohci_deallocate_bandwidth(ohcip, ph);
2725                 mutex_exit(&ph->p_mutex);
2726         }
2727 
2728         mutex_enter(&ph->p_mutex);
2729 
2730         /* Destroy the xfer completion condition varibale */
2731         cv_destroy(&pp->pp_xfer_cmpl_cv);
2732 
2733         /*
2734          * Deallocate the hcd private portion
2735          * of the pipe handle.
2736          */
2737         kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t));
2738         ph->p_hcd_private = NULL;
2739 
2740         mutex_exit(&ph->p_mutex);
2741 
2742         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2743             "ohci_hcdi_pipe_close: ph = 0x%p", (void *)ph);
2744 
2745         ohcip->ohci_open_pipe_count--;
2746 
2747         mutex_exit(&ohcip->ohci_int_mutex);
2748         sema_v(&ohcip->ohci_ocsem);
2749 
2750         return (error);
2751 }
2752 
2753 
2754 /*
2755  * ohci_hcdi_pipe_reset:
2756  */
2757 /* ARGSUSED */
2758 static int
2759 ohci_hcdi_pipe_reset(
2760         usba_pipe_handle_data_t *ph,
2761         usb_flags_t             usb_flags)
2762 {
2763         ohci_state_t            *ohcip = ohci_obtain_state(
2764             ph->p_usba_device->usb_root_hub_dip);
2765         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2766         int                     error = USB_SUCCESS;
2767 
2768         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2769             "ohci_hcdi_pipe_reset: ph = 0x%p ", (void *)ph);
2770 
2771         /*
2772          * Check and handle root hub pipe reset.
2773          */
2774         if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2775 
2776                 error = ohci_handle_root_hub_pipe_reset(ph, usb_flags);
2777                 return (error);
2778         }
2779 
2780         mutex_enter(&ohcip->ohci_int_mutex);
2781 
2782         /* Set pipe state to pipe reset */
2783         pp->pp_state = OHCI_PIPE_STATE_RESET;
2784 
2785         ohci_pipe_cleanup(ohcip, ph);
2786 
2787         mutex_exit(&ohcip->ohci_int_mutex);
2788 
2789         return (error);
2790 }
2791 
2792 /*
2793  * ohci_hcdi_pipe_reset_data_toggle:
2794  */
2795 void
2796 ohci_hcdi_pipe_reset_data_toggle(
2797         usba_pipe_handle_data_t *ph)
2798 {
2799         ohci_state_t            *ohcip = ohci_obtain_state(
2800             ph->p_usba_device->usb_root_hub_dip);
2801         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2802 
2803         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2804             "ohci_hcdi_pipe_reset_data_toggle:");
2805 
2806         mutex_enter(&ohcip->ohci_int_mutex);
2807 
2808         mutex_enter(&ph->p_mutex);
2809         usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
2810             DATA0);
2811         mutex_exit(&ph->p_mutex);
2812 
2813         Set_ED(pp->pp_ept->hced_headp,
2814             Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry));
2815         mutex_exit(&ohcip->ohci_int_mutex);
2816 
2817 }
2818 
2819 /*
2820  * ohci_hcdi_pipe_ctrl_xfer:
2821  */
2822 static int
2823 ohci_hcdi_pipe_ctrl_xfer(
2824         usba_pipe_handle_data_t *ph,
2825         usb_ctrl_req_t          *ctrl_reqp,
2826         usb_flags_t             usb_flags)
2827 {
2828         ohci_state_t            *ohcip = ohci_obtain_state(
2829             ph->p_usba_device->usb_root_hub_dip);
2830         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2831         int                     rval;
2832         int                     error = USB_SUCCESS;
2833         ohci_trans_wrapper_t    *tw;
2834 
2835         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2836             "ohci_hcdi_pipe_ctrl_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2837             (void *)ph, (void *)ctrl_reqp, usb_flags);
2838 
2839         mutex_enter(&ohcip->ohci_int_mutex);
2840         rval = ohci_state_is_operational(ohcip);
2841         mutex_exit(&ohcip->ohci_int_mutex);
2842 
2843         if (rval != USB_SUCCESS) {
2844 
2845                 return (rval);
2846         }
2847 
2848         /*
2849          * Check and handle root hub control request.
2850          */
2851         if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2852 
2853                 error = ohci_handle_root_hub_request(ohcip, ph, ctrl_reqp);
2854 
2855                 return (error);
2856         }
2857 
2858         mutex_enter(&ohcip->ohci_int_mutex);
2859 
2860         /*
2861          *  Check whether pipe is in halted state.
2862          */
2863         if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
2864 
2865                 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2866                     "ohci_hcdi_pipe_ctrl_xfer:"
2867                     "Pipe is in error state, need pipe reset to continue");
2868 
2869                 mutex_exit(&ohcip->ohci_int_mutex);
2870 
2871                 return (USB_FAILURE);
2872         }
2873 
2874         /* Allocate a transfer wrapper */
2875         if ((tw = ohci_allocate_ctrl_resources(ohcip, pp, ctrl_reqp,
2876             usb_flags)) == NULL) {
2877 
2878                 error = USB_NO_RESOURCES;
2879         } else {
2880                 /* Insert the td's on the endpoint */
2881                 ohci_insert_ctrl_req(ohcip, ph, ctrl_reqp, tw, usb_flags);
2882         }
2883 
2884         mutex_exit(&ohcip->ohci_int_mutex);
2885 
2886         return (error);
2887 }
2888 
2889 
2890 /*
2891  * ohci_hcdi_bulk_transfer_size:
2892  *
2893  * Return maximum bulk transfer size
2894  */
2895 
2896 /* ARGSUSED */
2897 static int
2898 ohci_hcdi_bulk_transfer_size(
2899         usba_device_t   *usba_device,
2900         size_t          *size)
2901 {
2902         ohci_state_t    *ohcip = ohci_obtain_state(
2903             usba_device->usb_root_hub_dip);
2904         int             rval;
2905 
2906         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2907             "ohci_hcdi_bulk_transfer_size:");
2908 
2909         mutex_enter(&ohcip->ohci_int_mutex);
2910         rval = ohci_state_is_operational(ohcip);
2911         mutex_exit(&ohcip->ohci_int_mutex);
2912 
2913         if (rval != USB_SUCCESS) {
2914 
2915                 return (rval);
2916         }
2917 
2918         *size = OHCI_MAX_BULK_XFER_SIZE;
2919 
2920         return (USB_SUCCESS);
2921 }
2922 
2923 
2924 /*
2925  * ohci_hcdi_pipe_bulk_xfer:
2926  */
2927 static int
2928 ohci_hcdi_pipe_bulk_xfer(
2929         usba_pipe_handle_data_t *ph,
2930         usb_bulk_req_t          *bulk_reqp,
2931         usb_flags_t             usb_flags)
2932 {
2933         ohci_state_t            *ohcip = ohci_obtain_state(
2934             ph->p_usba_device->usb_root_hub_dip);
2935         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2936         int                     rval, error = USB_SUCCESS;
2937         ohci_trans_wrapper_t    *tw;
2938 
2939         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2940             "ohci_hcdi_pipe_bulk_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2941             (void *)ph, (void *)bulk_reqp, usb_flags);
2942 
2943         mutex_enter(&ohcip->ohci_int_mutex);
2944         rval = ohci_state_is_operational(ohcip);
2945 
2946         if (rval != USB_SUCCESS) {
2947                 mutex_exit(&ohcip->ohci_int_mutex);
2948 
2949                 return (rval);
2950         }
2951 
2952         /*
2953          *  Check whether pipe is in halted state.
2954          */
2955         if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
2956 
2957                 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2958                     "ohci_hcdi_pipe_bulk_xfer:"
2959                     "Pipe is in error state, need pipe reset to continue");
2960 
2961                 mutex_exit(&ohcip->ohci_int_mutex);
2962 
2963                 return (USB_FAILURE);
2964         }
2965 
2966         /* Allocate a transfer wrapper */
2967         if ((tw = ohci_allocate_bulk_resources(ohcip, pp, bulk_reqp,
2968             usb_flags)) == NULL) {
2969 
2970                 error = USB_NO_RESOURCES;
2971         } else {
2972                 /* Add the TD into the Host Controller's bulk list */
2973                 ohci_insert_bulk_req(ohcip, ph, bulk_reqp, tw, usb_flags);
2974         }
2975 
2976         mutex_exit(&ohcip->ohci_int_mutex);
2977 
2978         return (error);
2979 }
2980 
2981 
2982 /*
2983  * ohci_hcdi_pipe_intr_xfer:
2984  */
2985 static int
2986 ohci_hcdi_pipe_intr_xfer(
2987         usba_pipe_handle_data_t *ph,
2988         usb_intr_req_t          *intr_reqp,
2989         usb_flags_t             usb_flags)
2990 {
2991         ohci_state_t            *ohcip = ohci_obtain_state(
2992             ph->p_usba_device->usb_root_hub_dip);
2993         int                     pipe_dir, rval, error = USB_SUCCESS;
2994         ohci_trans_wrapper_t    *tw;
2995 
2996         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2997             "ohci_hcdi_pipe_intr_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2998             (void *)ph, (void *)intr_reqp, usb_flags);
2999 
3000         mutex_enter(&ohcip->ohci_int_mutex);
3001         rval = ohci_state_is_operational(ohcip);
3002 
3003         if (rval != USB_SUCCESS) {
3004                 mutex_exit(&ohcip->ohci_int_mutex);
3005 
3006                 return (rval);
3007         }
3008 
3009         /* Get the pipe direction */
3010         pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
3011 
3012         if (pipe_dir == USB_EP_DIR_IN) {
3013                 error = ohci_start_periodic_pipe_polling(ohcip, ph,
3014                     (usb_opaque_t)intr_reqp, usb_flags);
3015         } else {
3016                 /* Allocate transaction resources */
3017                 if ((tw = ohci_allocate_intr_resources(ohcip, ph,
3018                     intr_reqp, usb_flags)) == NULL) {
3019                         error = USB_NO_RESOURCES;
3020                 } else {
3021                         ohci_insert_intr_req(ohcip,
3022                             (ohci_pipe_private_t *)ph->p_hcd_private,
3023                             tw, usb_flags);
3024                 }
3025         }
3026 
3027         mutex_exit(&ohcip->ohci_int_mutex);
3028 
3029         return (error);
3030 }
3031 
3032 
3033 /*
3034  * ohci_hcdi_pipe_stop_intr_polling()
3035  */
3036 static int
3037 ohci_hcdi_pipe_stop_intr_polling(
3038         usba_pipe_handle_data_t *ph,
3039         usb_flags_t             flags)
3040 {
3041         ohci_state_t            *ohcip = ohci_obtain_state(
3042             ph->p_usba_device->usb_root_hub_dip);
3043         int                     error = USB_SUCCESS;
3044 
3045         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3046             "ohci_hcdi_pipe_stop_intr_polling: ph = 0x%p fl = 0x%x",
3047             (void *)ph, flags);
3048 
3049         mutex_enter(&ohcip->ohci_int_mutex);
3050 
3051         error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags);
3052 
3053         mutex_exit(&ohcip->ohci_int_mutex);
3054 
3055         return (error);
3056 }
3057 
3058 
3059 /*
3060  * ohci_hcdi_get_current_frame_number:
3061  *
3062  * Get the current usb frame number.
3063  * Return whether the request is handled successfully.
3064  */
3065 static int
3066 ohci_hcdi_get_current_frame_number(
3067         usba_device_t           *usba_device,
3068         usb_frame_number_t      *frame_number)
3069 {
3070         ohci_state_t            *ohcip = ohci_obtain_state(
3071             usba_device->usb_root_hub_dip);
3072         int                     rval;
3073 
3074         ohcip = ohci_obtain_state(usba_device->usb_root_hub_dip);
3075 
3076         mutex_enter(&ohcip->ohci_int_mutex);
3077         rval = ohci_state_is_operational(ohcip);
3078 
3079         if (rval != USB_SUCCESS) {
3080                 mutex_exit(&ohcip->ohci_int_mutex);
3081 
3082                 return (rval);
3083         }
3084 
3085         *frame_number = ohci_get_current_frame_number(ohcip);
3086 
3087         mutex_exit(&ohcip->ohci_int_mutex);
3088 
3089         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3090             "ohci_hcdi_get_current_frame_number:"
3091             "Current frame number 0x%llx", (unsigned long long)(*frame_number));
3092 
3093         return (rval);
3094 }
3095 
3096 
3097 /*
3098  * ohci_hcdi_get_max_isoc_pkts:
3099  *
3100  * Get maximum isochronous packets per usb isochronous request.
3101  * Return whether the request is handled successfully.
3102  */
3103 static int
3104 ohci_hcdi_get_max_isoc_pkts(
3105         usba_device_t   *usba_device,
3106         uint_t          *max_isoc_pkts_per_request)
3107 {
3108         ohci_state_t            *ohcip = ohci_obtain_state(
3109             usba_device->usb_root_hub_dip);
3110         int                     rval;
3111 
3112         mutex_enter(&ohcip->ohci_int_mutex);
3113         rval = ohci_state_is_operational(ohcip);
3114         mutex_exit(&ohcip->ohci_int_mutex);
3115 
3116         if (rval != USB_SUCCESS) {
3117 
3118                 return (rval);
3119         }
3120 
3121         *max_isoc_pkts_per_request = OHCI_MAX_ISOC_PKTS_PER_XFER;
3122 
3123         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3124             "ohci_hcdi_get_max_isoc_pkts: maximum isochronous"
3125             "packets per usb isochronous request = 0x%x",
3126             *max_isoc_pkts_per_request);
3127 
3128         return (rval);
3129 }
3130 
3131 
3132 /*
3133  * ohci_hcdi_pipe_isoc_xfer:
3134  */
3135 static int
3136 ohci_hcdi_pipe_isoc_xfer(
3137         usba_pipe_handle_data_t *ph,
3138         usb_isoc_req_t          *isoc_reqp,
3139         usb_flags_t             usb_flags)
3140 {
3141         ohci_state_t            *ohcip = ohci_obtain_state(
3142             ph->p_usba_device->usb_root_hub_dip);
3143         int                     error = USB_SUCCESS;
3144         int                     pipe_dir, rval;
3145         ohci_trans_wrapper_t    *tw;
3146 
3147         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3148             "ohci_hcdi_pipe_isoc_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
3149             (void *)ph, (void *)isoc_reqp, usb_flags);
3150 
3151         mutex_enter(&ohcip->ohci_int_mutex);
3152         rval = ohci_state_is_operational(ohcip);
3153 
3154         if (rval != USB_SUCCESS) {
3155                 mutex_exit(&ohcip->ohci_int_mutex);
3156 
3157                 return (rval);
3158         }
3159 
3160         /* Get the isochronous pipe direction */
3161         pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
3162 
3163         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3164             "ohci_hcdi_pipe_isoc_xfer: isoc_reqp = 0x%p, uf = 0x%x",
3165             (void *)isoc_reqp, usb_flags);
3166 
3167         if (pipe_dir == USB_EP_DIR_IN) {
3168                 error = ohci_start_periodic_pipe_polling(ohcip, ph,
3169                     (usb_opaque_t)isoc_reqp, usb_flags);
3170         } else {
3171                 /* Allocate transaction resources */
3172                 if ((tw = ohci_allocate_isoc_resources(ohcip, ph,
3173                     isoc_reqp, usb_flags)) == NULL) {
3174                         error = USB_NO_RESOURCES;
3175                 } else {
3176                         error = ohci_insert_isoc_req(ohcip,
3177                             (ohci_pipe_private_t *)ph->p_hcd_private,
3178                             tw, usb_flags);
3179                 }
3180         }
3181 
3182         mutex_exit(&ohcip->ohci_int_mutex);
3183 
3184         return (error);
3185 }
3186 
3187 
3188 /*
3189  * ohci_hcdi_pipe_stop_isoc_polling()
3190  */
3191 static int
3192 ohci_hcdi_pipe_stop_isoc_polling(
3193         usba_pipe_handle_data_t *ph,
3194         usb_flags_t             flags)
3195 {
3196         ohci_state_t            *ohcip = ohci_obtain_state(
3197             ph->p_usba_device->usb_root_hub_dip);
3198         int                     rval, error = USB_SUCCESS;
3199 
3200         USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3201             "ohci_hcdi_pipe_stop_isoc_polling: ph = 0x%p fl = 0x%x",
3202             (void *)ph, flags);
3203 
3204         mutex_enter(&ohcip->ohci_int_mutex);
3205         rval = ohci_state_is_operational(ohcip);
3206 
3207         if (rval != USB_SUCCESS) {
3208                 mutex_exit(&ohcip->ohci_int_mutex);
3209                 return (rval);
3210         }
3211 
3212         error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags);
3213 
3214         mutex_exit(&ohcip->ohci_int_mutex);
3215         return (error);
3216 }
3217 
3218 
3219 /*
3220  * Bandwidth Allocation functions
3221  */
3222 
3223 /*
3224  * ohci_allocate_bandwidth:
3225  *
3226  * Figure out whether or not this interval may be supported. Return the index
3227  * into the  lattice if it can be supported.  Return allocation failure if it
3228  * can not be supported.
3229  *
3230  * The lattice structure looks like this with the bottom leaf actually
3231  * being an array.  There is a total of 63 nodes in this tree.  The lattice tree
3232  * itself is 0 based, while the bottom leaf array is 0 based.  The 0 bucket in
3233  * the bottom leaf array is used to store the smalled allocated bandwidth of all
3234  * the leaves.
3235  *
3236  *      0
3237  *    1   2
3238  *   3 4 5 6
3239  *   ...
3240  *  (32 33 ... 62 63)     <-- last row does not exist in lattice, but an array
3241  *   0 1 2 3 ... 30 31
3242  *
3243  * We keep track of the bandwidth that each leaf uses.  First we search for the
3244  * first leaf with the smallest used bandwidth.  Based on that leaf we find the
3245  * parent node of that leaf based on the interval time.
3246  *
3247  * From the parent node, we find all the leafs of that subtree and update the
3248  * additional bandwidth needed.  In order to balance the load the leaves are not
3249  * executed directly from left to right, but scattered.  For a better picture
3250  * refer to Section 3.3.2 in the OpenHCI 1.0 spec, there should be a figure
3251  * showing the Interrupt ED Structure.
3252  */
3253 static int
3254 ohci_allocate_bandwidth(
3255         ohci_state_t            *ohcip,
3256         usba_pipe_handle_data_t *ph,
3257         uint_t                  *node)
3258 {
3259         int                     interval, error, i;
3260         uint_t                  min, min_index, height;
3261         uint_t                  leftmost, list, bandwidth;
3262         usb_ep_descr_t          *endpoint = &ph->p_ep;
3263 
3264         /* This routine is protected by the ohci_int_mutex */
3265         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3266 
3267         /*
3268          * Calculate the length in bytes of a transaction on this
3269          * periodic endpoint.
3270          */
3271         mutex_enter(&ph->p_usba_device->usb_mutex);
3272         error = ohci_compute_total_bandwidth(
3273             endpoint, ph->p_usba_device->usb_port_status, &bandwidth);
3274         mutex_exit(&ph->p_usba_device->usb_mutex);
3275 
3276         /*
3277          * If length is zero, then, it means endpoint maximum packet
3278          * supported is zero.  In that case, return failure without
3279          * allocating any bandwidth.
3280          */
3281         if (error != USB_SUCCESS) {
3282                 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3283                     "ohci_allocate_bandwidth: Periodic endpoint with "
3284                     "zero endpoint maximum packet size is not supported");
3285 
3286                 return (USB_NOT_SUPPORTED);
3287         }
3288 
3289         /*
3290          * If the length in bytes plus the allocated bandwidth exceeds
3291          * the maximum, return bandwidth allocation failure.
3292          */
3293         if ((ohcip->ohci_periodic_minimum_bandwidth + bandwidth) >
3294             (MAX_PERIODIC_BANDWIDTH)) {
3295 
3296                 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3297                     "ohci_allocate_bandwidth: Reached maximum "
3298                     "bandwidth value and cannot allocate bandwidth "
3299                     "for a given periodic endpoint");
3300 
3301                 return (USB_NO_BANDWIDTH);
3302         }
3303 
3304         /* Adjust polling interval to be a power of 2 */
3305         mutex_enter(&ph->p_usba_device->usb_mutex);
3306         interval = ohci_adjust_polling_interval(ohcip,
3307             endpoint, ph->p_usba_device->usb_port_status);
3308         mutex_exit(&ph->p_usba_device->usb_mutex);
3309 
3310         /*
3311          * If this interval can't be supported,
3312          * return allocation failure.
3313          */
3314         if (interval == USB_FAILURE) {
3315 
3316                 return (USB_FAILURE);
3317         }
3318 
3319         USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3320             "The new interval is %d", interval);
3321 
3322         /* Find the leaf with the smallest allocated bandwidth */
3323         min_index = 0;
3324         min = ohcip->ohci_periodic_bandwidth[0];
3325 
3326         for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3327                 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3328                         min_index = i;
3329                         min = ohcip->ohci_periodic_bandwidth[i];
3330                 }
3331         }
3332 
3333         USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3334             "The leaf %d for minimal bandwidth %d", min_index, min);
3335 
3336         /* Adjust min for the lattice */
3337         min_index = min_index + NUM_INTR_ED_LISTS - 1;
3338 
3339         /*
3340          * Find the index into the lattice given the
3341          * leaf with the smallest allocated bandwidth.
3342          */
3343         height = ohci_lattice_height(interval);
3344 
3345         USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3346             "The height is %d", height);
3347 
3348         *node = min_index;
3349 
3350         for (i = 0; i < height; i++) {
3351                 *node = ohci_lattice_parent(*node);
3352         }
3353 
3354         USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3355             "Real node is %d", *node);
3356 
3357         /*
3358          * Find the leftmost leaf in the subtree
3359          * specified by the node.
3360          */
3361         leftmost = ohci_leftmost_leaf(*node, height);
3362 
3363         USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3364             "Leftmost %d", leftmost);
3365 
3366         for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3367                 list = ohci_hcca_leaf_index(leftmost + i);
3368                 if ((ohcip->ohci_periodic_bandwidth[list] +
3369                     bandwidth) > MAX_PERIODIC_BANDWIDTH) {
3370 
3371                         USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3372                             "ohci_allocate_bandwidth: Reached maximum "
3373                             "bandwidth value and cannot allocate bandwidth "
3374                             "for periodic endpoint");
3375 
3376                         return (USB_NO_BANDWIDTH);
3377                 }
3378         }
3379 
3380         /*
3381          * All the leaves for this node must be updated with the bandwidth.
3382          */
3383         for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3384                 list = ohci_hcca_leaf_index(leftmost + i);
3385                 ohcip->ohci_periodic_bandwidth[list] += bandwidth;
3386         }
3387 
3388         /* Find the leaf with the smallest allocated bandwidth */
3389         min_index = 0;
3390         min = ohcip->ohci_periodic_bandwidth[0];
3391 
3392         for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3393                 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3394                         min_index = i;
3395                         min = ohcip->ohci_periodic_bandwidth[i];
3396                 }
3397         }
3398 
3399         /* Save the minimum for later use */
3400         ohcip->ohci_periodic_minimum_bandwidth = min;
3401 
3402         return (USB_SUCCESS);
3403 }
3404 
3405 
3406 /*
3407  * ohci_deallocate_bandwidth:
3408  *
3409  * Deallocate bandwidth for the given node in the lattice and the length
3410  * of transfer.
3411  */
3412 static void
3413 ohci_deallocate_bandwidth(
3414         ohci_state_t            *ohcip,
3415         usba_pipe_handle_data_t *ph)
3416 {
3417         uint_t                  min, node, bandwidth;
3418         uint_t                  height, leftmost, list;
3419         int                     i, interval;
3420         usb_ep_descr_t          *endpoint = &ph->p_ep;
3421         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
3422 
3423         /* This routine is protected by the ohci_int_mutex */
3424         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3425 
3426         /* Obtain the length */
3427         mutex_enter(&ph->p_usba_device->usb_mutex);
3428         (void) ohci_compute_total_bandwidth(
3429             endpoint, ph->p_usba_device->usb_port_status, &bandwidth);
3430         mutex_exit(&ph->p_usba_device->usb_mutex);
3431 
3432         /* Obtain the node */
3433         node = pp->pp_node;
3434 
3435         /* Adjust polling interval to be a power of 2 */
3436         mutex_enter(&ph->p_usba_device->usb_mutex);
3437         interval = ohci_adjust_polling_interval(ohcip,
3438             endpoint, ph->p_usba_device->usb_port_status);
3439         mutex_exit(&ph->p_usba_device->usb_mutex);
3440 
3441         /* Find the height in the tree */
3442         height = ohci_lattice_height(interval);
3443 
3444         /*
3445          * Find the leftmost leaf in the subtree specified by the node
3446          */
3447         leftmost = ohci_leftmost_leaf(node, height);
3448 
3449         /* Delete the bandwith from the appropriate lists */
3450         for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3451                 list = ohci_hcca_leaf_index(leftmost + i);
3452                 ohcip->ohci_periodic_bandwidth[list] -= bandwidth;
3453         }
3454 
3455         min = ohcip->ohci_periodic_bandwidth[0];
3456 
3457         /* Recompute the minimum */
3458         for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3459                 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3460                         min = ohcip->ohci_periodic_bandwidth[i];
3461                 }
3462         }
3463 
3464         /* Save the minimum for later use */
3465         ohcip->ohci_periodic_minimum_bandwidth = min;
3466 }
3467 
3468 
3469 /*
3470  * ohci_compute_total_bandwidth:
3471  *
3472  * Given a periodic endpoint (interrupt or isochronous) determine the total
3473  * bandwidth for one transaction. The OpenHCI host controller traverses the
3474  * endpoint descriptor lists on a first-come-first-serve basis. When the HC
3475  * services an endpoint, only a single transaction attempt is made. The  HC
3476  * moves to the next Endpoint Descriptor after the first transaction attempt
3477  * rather than finishing the entire Transfer Descriptor. Therefore, when  a
3478  * Transfer Descriptor is inserted into the lattice, we will only count the
3479  * number of bytes for one transaction.
3480  *
3481  * The following are the formulas used for  calculating bandwidth in  terms
3482  * bytes and it is for the single USB full speed and low speed  transaction
3483  * respectively. The protocol overheads will be different for each of  type
3484  * of USB transfer and all these formulas & protocol overheads are  derived
3485  * from the 5.9.3 section of USB Specification & with the help of Bandwidth
3486  * Analysis white paper which is posted on the USB  developer forum.
3487  *
3488  * Full-Speed:
3489  *              Protocol overhead  + ((MaxPacketSize * 7)/6 )  + Host_Delay
3490  *
3491  * Low-Speed:
3492  *              Protocol overhead  + Hub LS overhead +
3493  *                (Low-Speed clock * ((MaxPacketSize * 7)/6 )) + Host_Delay
3494  */
3495 static int
3496 ohci_compute_total_bandwidth(
3497         usb_ep_descr_t          *endpoint,
3498         usb_port_status_t       port_status,
3499         uint_t                  *bandwidth)
3500 {
3501         ushort_t                maxpacketsize = endpoint->wMaxPacketSize;
3502 
3503         /*
3504          * If endpoint maximum packet is zero, then return immediately.
3505          */
3506         if (maxpacketsize == 0) {
3507 
3508                 return (USB_NOT_SUPPORTED);
3509         }
3510 
3511         /* Add Host Controller specific delay to required bandwidth */
3512         *bandwidth = HOST_CONTROLLER_DELAY;
3513 
3514         /* Add bit-stuffing overhead */
3515         maxpacketsize = (ushort_t)((maxpacketsize * 7) / 6);
3516 
3517         /* Low Speed interrupt transaction */
3518         if (port_status == USBA_LOW_SPEED_DEV) {
3519                 /* Low Speed interrupt transaction */
3520                 *bandwidth += (LOW_SPEED_PROTO_OVERHEAD +
3521                     HUB_LOW_SPEED_PROTO_OVERHEAD +
3522                     (LOW_SPEED_CLOCK * maxpacketsize));
3523         } else {
3524                 /* Full Speed transaction */
3525                 *bandwidth += maxpacketsize;
3526 
3527                 if ((endpoint->bmAttributes &
3528                     USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) {
3529                         /* Full Speed interrupt transaction */
3530                         *bandwidth += FS_NON_ISOC_PROTO_OVERHEAD;
3531                 } else {
3532                         /* Isochronous and input transaction */
3533                         if ((endpoint->bEndpointAddress &
3534                             USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
3535                                 *bandwidth += FS_ISOC_INPUT_PROTO_OVERHEAD;
3536                         } else {
3537                                 /* Isochronous and output transaction */
3538                                 *bandwidth += FS_ISOC_OUTPUT_PROTO_OVERHEAD;
3539                         }
3540                 }
3541         }
3542 
3543         return (USB_SUCCESS);
3544 }
3545 
3546 
3547 /*
3548  * ohci_adjust_polling_interval:
3549  */
3550 static int
3551 ohci_adjust_polling_interval(
3552         ohci_state_t            *ohcip,
3553         usb_ep_descr_t          *endpoint,
3554         usb_port_status_t       port_status)
3555 {
3556         uint_t                  interval;
3557         int                     i = 0;
3558 
3559         /*
3560          * Get the polling interval from the endpoint descriptor
3561          */
3562         interval = endpoint->bInterval;
3563 
3564         /*
3565          * The bInterval value in the endpoint descriptor can range
3566          * from 1 to 255ms. The interrupt lattice has 32 leaf nodes,
3567          * and the host controller cycles through these nodes every
3568          * 32ms. The longest polling  interval that the  controller
3569          * supports is 32ms.
3570          */
3571 
3572         /*
3573          * Return an error if the polling interval is less than 1ms
3574          * and greater than 255ms
3575          */
3576         if ((interval < MIN_POLL_INTERVAL) ||
3577             (interval > MAX_POLL_INTERVAL)) {
3578 
3579                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3580                     "ohci_adjust_polling_interval: "
3581                     "Endpoint's poll interval must be between %d and %d ms",
3582                     MIN_POLL_INTERVAL, MAX_POLL_INTERVAL);
3583 
3584                 return (USB_FAILURE);
3585         }
3586 
3587         /*
3588          * According USB Specifications, a  full-speed endpoint can
3589          * specify a desired polling interval 1ms to 255ms and a low
3590          * speed  endpoints are limited to  specifying only 10ms to
3591          * 255ms. But some old keyboards & mice uses polling interval
3592          * of 8ms. For compatibility  purpose, we are using polling
3593          * interval between 8ms & 255ms for low speed endpoints. But
3594          * ohci driver will reject the any low speed endpoints which
3595          * request polling interval less than 8ms.
3596          */
3597         if ((port_status == USBA_LOW_SPEED_DEV) &&
3598             (interval < MIN_LOW_SPEED_POLL_INTERVAL)) {
3599 
3600                 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3601                     "ohci_adjust_polling_interval: "
3602                     "Low speed endpoint's poll interval of %d ms "
3603                     "is below threshold.  Rounding up to %d ms",
3604                     interval, MIN_LOW_SPEED_POLL_INTERVAL);
3605 
3606                 interval = MIN_LOW_SPEED_POLL_INTERVAL;
3607         }
3608 
3609         /*
3610          * If polling interval is greater than 32ms,
3611          * adjust polling interval equal to 32ms.
3612          */
3613         if (interval > NUM_INTR_ED_LISTS) {
3614                 interval = NUM_INTR_ED_LISTS;
3615         }
3616 
3617         /*
3618          * Find the nearest power of 2 that'sless
3619          * than interval.
3620          */
3621         while ((ohci_pow_2(i)) <= interval) {
3622                 i++;
3623         }
3624 
3625         return (ohci_pow_2((i - 1)));
3626 }
3627 
3628 
3629 /*
3630  * ohci_lattice_height:
3631  *
3632  * Given the requested bandwidth, find the height in the tree at which the
3633  * nodes for this bandwidth fall.  The height is measured as the number of
3634  * nodes from the leaf to the level specified by bandwidth The root of the
3635  * tree is at height TREE_HEIGHT.
3636  */
3637 static uint_t
3638 ohci_lattice_height(uint_t interval)
3639 {
3640         return (TREE_HEIGHT - (ohci_log_2(interval)));
3641 }
3642 
3643 
3644 /*
3645  * ohci_lattice_parent:
3646  */
3647 static uint_t
3648 ohci_lattice_parent(uint_t node)
3649 {
3650         if ((node % 2) == 0) {
3651                 return ((node/2) - 1);
3652         } else {
3653                 return ((node + 1)/2 - 1);
3654         }
3655 }
3656 
3657 
3658 /*
3659  * ohci_leftmost_leaf:
3660  *
3661  * Find the leftmost leaf in the subtree specified by the node. Height refers
3662  * to number of nodes from the bottom of the tree to the node,  including the
3663  * node.
3664  *
3665  * The formula for a zero based tree is:
3666  *     2^H * Node + 2^H - 1
3667  * The leaf of the tree is an array, convert the number for the array.
3668  *     Subtract the size of nodes not in the array
3669  *     2^H * Node + 2^H - 1 - (NUM_INTR_ED_LIST - 1) =
3670  *     2^H * Node + 2^H - NUM_INTR_ED_LIST =
3671  *     2^H * (Node + 1) - NUM_INTR_ED_LIST
3672  *         0
3673  *       1   2
3674  *      0 1 2 3
3675  */
3676 static uint_t
3677 ohci_leftmost_leaf(
3678         uint_t  node,
3679         uint_t  height)
3680 {
3681         return ((ohci_pow_2(height) * (node + 1)) - NUM_INTR_ED_LISTS);
3682 }
3683 
3684 /*
3685  * ohci_hcca_intr_index:
3686  *
3687  * Given a node in the lattice, find the index for the hcca interrupt table
3688  */
3689 static uint_t
3690 ohci_hcca_intr_index(uint_t node)
3691 {
3692         /*
3693          * Adjust the node to the array representing
3694          * the bottom of the tree.
3695          */
3696         node = node - NUM_STATIC_NODES;
3697 
3698         if ((node % 2) == 0) {
3699                 return (ohci_index[node / 2]);
3700         } else {
3701                 return (ohci_index[node / 2] + (NUM_INTR_ED_LISTS / 2));
3702         }
3703 }
3704 
3705 /*
3706  * ohci_hcca_leaf_index:
3707  *
3708  * Given a node in the bottom leaf array of the lattice, find the index
3709  * for the hcca interrupt table
3710  */
3711 static uint_t
3712 ohci_hcca_leaf_index(uint_t leaf)
3713 {
3714         if ((leaf % 2) == 0) {
3715                 return (ohci_index[leaf / 2]);
3716         } else {
3717                 return (ohci_index[leaf / 2] + (NUM_INTR_ED_LISTS / 2));
3718         }
3719 }
3720 
3721 /*
3722  * ohci_pow_2:
3723  *
3724  * Compute 2 to the power
3725  */
3726 static uint_t
3727 ohci_pow_2(uint_t x)
3728 {
3729         if (x == 0) {
3730                 return (1);
3731         } else {
3732                 return (2 << (x - 1));
3733         }
3734 }
3735 
3736 
3737 /*
3738  * ohci_log_2:
3739  *
3740  * Compute log base 2 of x
3741  */
3742 static uint_t
3743 ohci_log_2(uint_t x)
3744 {
3745         int i = 0;
3746 
3747         while (x != 1) {
3748                 x = x >> 1;
3749                 i++;
3750         }
3751 
3752         return (i);
3753 }
3754 
3755 
3756 /*
3757  * Endpoint Descriptor (ED) manipulations functions
3758  */
3759 
3760 /*
3761  * ohci_alloc_hc_ed:
3762  * NOTE: This function is also called from POLLED MODE.
3763  *
3764  * Allocate an endpoint descriptor (ED)
3765  */
3766 ohci_ed_t *
3767 ohci_alloc_hc_ed(
3768         ohci_state_t            *ohcip,
3769         usba_pipe_handle_data_t *ph)
3770 {
3771         int                     i, state;
3772         ohci_ed_t               *hc_ed;
3773 
3774         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3775             "ohci_alloc_hc_ed: ph = 0x%p", (void *)ph);
3776 
3777         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3778 
3779         /*
3780          * The first 31 endpoints in the Endpoint Descriptor (ED)
3781          * buffer pool are reserved for building interrupt lattice
3782          * tree. Search for a blank endpoint descriptor in the ED
3783          * buffer pool.
3784          */
3785         for (i = NUM_STATIC_NODES; i < ohci_ed_pool_size; i ++) {
3786                 state = Get_ED(ohcip->ohci_ed_pool_addr[i].hced_state);
3787 
3788                 if (state == HC_EPT_FREE) {
3789                         break;
3790                 }
3791         }
3792 
3793         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3794             "ohci_alloc_hc_ed: Allocated %d", i);
3795 
3796         if (i == ohci_ed_pool_size) {
3797                 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3798                     "ohci_alloc_hc_ed: ED exhausted");
3799 
3800                 return (NULL);
3801         } else {
3802 
3803                 hc_ed = &ohcip->ohci_ed_pool_addr[i];
3804 
3805                 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3806                     "ohci_alloc_hc_ed: Allocated address 0x%p", (void *)hc_ed);
3807 
3808                 ohci_print_ed(ohcip, hc_ed);
3809 
3810                 /* Unpack the endpoint descriptor into a control field */
3811                 if (ph) {
3812                         if ((ohci_initialize_dummy(ohcip,
3813                             hc_ed)) == USB_NO_RESOURCES) {
3814                                 bzero((void *)hc_ed, sizeof (ohci_ed_t));
3815                                 Set_ED(hc_ed->hced_state, HC_EPT_FREE);
3816                                 return (NULL);
3817                         }
3818 
3819                         Set_ED(hc_ed->hced_prev, NULL);
3820                         Set_ED(hc_ed->hced_next, NULL);
3821 
3822                         /* Change ED's state Active */
3823                         Set_ED(hc_ed->hced_state, HC_EPT_ACTIVE);
3824 
3825                         Set_ED(hc_ed->hced_ctrl,
3826                             ohci_unpack_endpoint(ohcip, ph));
3827                 } else {
3828                         Set_ED(hc_ed->hced_ctrl, HC_EPT_sKip);
3829 
3830                         /* Change ED's state Static */
3831                         Set_ED(hc_ed->hced_state, HC_EPT_STATIC);
3832                 }
3833 
3834                 return (hc_ed);
3835         }
3836 }
3837 
3838 
3839 /*
3840  * ohci_unpack_endpoint:
3841  *
3842  * Unpack the information in the pipe handle and create the first byte
3843  * of the Host Controller's (HC) Endpoint Descriptor (ED).
3844  */
3845 static uint_t
3846 ohci_unpack_endpoint(
3847         ohci_state_t            *ohcip,
3848         usba_pipe_handle_data_t *ph)
3849 {
3850         usb_ep_descr_t          *endpoint = &ph->p_ep;
3851         uint_t                  maxpacketsize, addr, ctrl = 0;
3852 
3853         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3854             "ohci_unpack_endpoint:");
3855 
3856         ctrl = ph->p_usba_device->usb_addr;
3857 
3858         addr = endpoint->bEndpointAddress;
3859 
3860         /* Assign the endpoint's address */
3861         ctrl = ctrl | ((addr & USB_EP_NUM_MASK) << HC_EPT_EP_SHFT);
3862 
3863         /*
3864          * Assign the direction. If the endpoint is a control endpoint,
3865          * the direction is assigned by the Transfer Descriptor (TD).
3866          */
3867         if ((endpoint->bmAttributes &
3868             USB_EP_ATTR_MASK) != USB_EP_ATTR_CONTROL) {
3869                 if (addr & USB_EP_DIR_MASK) {
3870                         /* The direction is IN */
3871                         ctrl = ctrl | HC_EPT_DF_IN;
3872                 } else {
3873                         /* The direction is OUT */
3874                         ctrl = ctrl | HC_EPT_DF_OUT;
3875                 }
3876         }
3877 
3878         /* Assign the speed */
3879         mutex_enter(&ph->p_usba_device->usb_mutex);
3880         if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) {
3881                 ctrl = ctrl | HC_EPT_Speed;
3882         }
3883         mutex_exit(&ph->p_usba_device->usb_mutex);
3884 
3885         /* Assign the format */
3886         if ((endpoint->bmAttributes &
3887             USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
3888                 ctrl = ctrl | HC_EPT_Format;
3889         }
3890 
3891         maxpacketsize = endpoint->wMaxPacketSize;
3892         maxpacketsize = maxpacketsize << HC_EPT_MAXPKTSZ;
3893         ctrl = ctrl | (maxpacketsize & HC_EPT_MPS);
3894 
3895         return (ctrl);
3896 }
3897 
3898 
3899 /*
3900  * ohci_insert_ed:
3901  *
3902  * Add the Endpoint Descriptor (ED) into the Host Controller's
3903  * (HC) appropriate endpoint list.
3904  */
3905 static void
3906 ohci_insert_ed(
3907         ohci_state_t            *ohcip,
3908         usba_pipe_handle_data_t *ph)
3909 {
3910         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
3911 
3912         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3913             "ohci_insert_ed:");
3914 
3915         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3916 
3917         switch (ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) {
3918         case USB_EP_ATTR_CONTROL:
3919                 ohci_insert_ctrl_ed(ohcip, pp);
3920                 break;
3921         case USB_EP_ATTR_BULK:
3922                 ohci_insert_bulk_ed(ohcip, pp);
3923                 break;
3924         case USB_EP_ATTR_INTR:
3925                 ohci_insert_intr_ed(ohcip, pp);
3926                 break;
3927         case USB_EP_ATTR_ISOCH:
3928                 ohci_insert_isoc_ed(ohcip, pp);
3929                 break;
3930         }
3931 }
3932 
3933 
3934 /*
3935  * ohci_insert_ctrl_ed:
3936  *
3937  * Insert a control endpoint into the Host Controller's (HC)
3938  * control endpoint list.
3939  */
3940 static void
3941 ohci_insert_ctrl_ed(
3942         ohci_state_t            *ohcip,
3943         ohci_pipe_private_t     *pp)
3944 {
3945         ohci_ed_t       *ept = pp->pp_ept;
3946         ohci_ed_t       *prev_ept;
3947 
3948         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3949             "ohci_insert_ctrl_ed:");
3950 
3951         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3952 
3953         /* Obtain a ptr to the head of the list */
3954         if (Get_OpReg(hcr_ctrl_head)) {
3955                 prev_ept = ohci_ed_iommu_to_cpu(ohcip,
3956                     Get_OpReg(hcr_ctrl_head));
3957 
3958                 /* Set up the backwards pointer */
3959                 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept));
3960         }
3961 
3962         /* The new endpoint points to the head of the list */
3963         Set_ED(ept->hced_next, Get_OpReg(hcr_ctrl_head));
3964 
3965         /* Set the head ptr to the new endpoint */
3966         Set_OpReg(hcr_ctrl_head, ohci_ed_cpu_to_iommu(ohcip, ept));
3967 
3968         /*
3969          * Enable Control list processing if control open
3970          * pipe count is zero.
3971          */
3972         if (!ohcip->ohci_open_ctrl_pipe_count) {
3973                 /* Start Control list processing */
3974                 Set_OpReg(hcr_control,
3975                     (Get_OpReg(hcr_control) | HCR_CONTROL_CLE));
3976         }
3977 
3978         ohcip->ohci_open_ctrl_pipe_count++;
3979 }
3980 
3981 
3982 /*
3983  * ohci_insert_bulk_ed:
3984  *
3985  * Insert a bulk endpoint into the Host Controller's (HC) bulk endpoint list.
3986  */
3987 static void
3988 ohci_insert_bulk_ed(
3989         ohci_state_t            *ohcip,
3990         ohci_pipe_private_t     *pp)
3991 {
3992         ohci_ed_t               *ept = pp->pp_ept;
3993         ohci_ed_t               *prev_ept;
3994 
3995         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3996             "ohci_insert_bulk_ed:");
3997 
3998         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3999 
4000         /* Obtain a ptr to the head of the Bulk list */
4001         if (Get_OpReg(hcr_bulk_head)) {
4002                 prev_ept = ohci_ed_iommu_to_cpu(ohcip,
4003                     Get_OpReg(hcr_bulk_head));
4004 
4005                 /* Set up the backwards pointer */
4006                 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept));
4007         }
4008 
4009         /* The new endpoint points to the head of the Bulk list */
4010         Set_ED(ept->hced_next, Get_OpReg(hcr_bulk_head));
4011 
4012         /* Set the Bulk head ptr to the new endpoint */
4013         Set_OpReg(hcr_bulk_head, ohci_ed_cpu_to_iommu(ohcip, ept));
4014 
4015         /*
4016          * Enable Bulk list processing if bulk open pipe
4017          * count is zero.
4018          */
4019         if (!ohcip->ohci_open_bulk_pipe_count) {
4020                 /* Start Bulk list processing */
4021                 Set_OpReg(hcr_control,
4022                     (Get_OpReg(hcr_control) | HCR_CONTROL_BLE));
4023         }
4024 
4025         ohcip->ohci_open_bulk_pipe_count++;
4026 }
4027 
4028 
4029 /*
4030  * ohci_insert_intr_ed:
4031  *
4032  * Insert a interrupt endpoint into the Host Controller's (HC) interrupt
4033  * lattice tree.
4034  */
4035 static void
4036 ohci_insert_intr_ed(
4037         ohci_state_t            *ohcip,
4038         ohci_pipe_private_t     *pp)
4039 {
4040         ohci_ed_t               *ept = pp->pp_ept;
4041         ohci_ed_t               *next_lattice_ept, *lattice_ept;
4042         uint_t                  node;
4043 
4044         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4045 
4046         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4047             "ohci_insert_intr_ed:");
4048 
4049         /*
4050          * The appropriate node was found
4051          * during the opening of the pipe.
4052          */
4053         node = pp->pp_node;
4054 
4055         if (node >= NUM_STATIC_NODES) {
4056                 /* Get the hcca interrupt table index */
4057                 node = ohci_hcca_intr_index(node);
4058 
4059                 /* Get the first endpoint on the list */
4060                 next_lattice_ept = ohci_ed_iommu_to_cpu(ohcip,
4061                     Get_HCCA(ohcip->ohci_hccap->HccaIntTble[node]));
4062 
4063                 /* Update this endpoint to point to it */
4064                 Set_ED(ept->hced_next,
4065                     ohci_ed_cpu_to_iommu(ohcip, next_lattice_ept));
4066 
4067                 /* Put this endpoint at the head of the list */
4068                 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[node],
4069                     ohci_ed_cpu_to_iommu(ohcip, ept));
4070 
4071                 /* The previous pointer is NULL */
4072                 Set_ED(ept->hced_prev, NULL);
4073 
4074                 /* Update the previous pointer of ept->hced_next */
4075                 if (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC) {
4076                         Set_ED(next_lattice_ept->hced_prev,
4077                             ohci_ed_cpu_to_iommu(ohcip, ept));
4078                 }
4079         } else {
4080                 /* Find the lattice endpoint */
4081                 lattice_ept = &ohcip->ohci_ed_pool_addr[node];
4082 
4083                 /* Find the next lattice endpoint */
4084                 next_lattice_ept = ohci_ed_iommu_to_cpu(
4085                     ohcip, Get_ED(lattice_ept->hced_next));
4086 
4087                 /*
4088                  * Update this endpoint to point to the next one in the
4089                  * lattice.
4090                  */
4091                 Set_ED(ept->hced_next, Get_ED(lattice_ept->hced_next));
4092 
4093                 /* Insert this endpoint into the lattice */
4094                 Set_ED(lattice_ept->hced_next,
4095                     ohci_ed_cpu_to_iommu(ohcip, ept));
4096 
4097                 /* Update the previous pointer */
4098                 Set_ED(ept->hced_prev,
4099                     ohci_ed_cpu_to_iommu(ohcip, lattice_ept));
4100 
4101                 /* Update the previous pointer of ept->hced_next */
4102                 if ((next_lattice_ept) &&
4103                     (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC)) {
4104 
4105                         Set_ED(next_lattice_ept->hced_prev,
4106                             ohci_ed_cpu_to_iommu(ohcip, ept));
4107                 }
4108         }
4109 
4110         /*
4111          * Enable periodic list processing if periodic (interrupt
4112          * and isochronous) open pipe count is zero.
4113          */
4114         if (!ohcip->ohci_open_periodic_pipe_count) {
4115                 ASSERT(!ohcip->ohci_open_isoch_pipe_count);
4116 
4117                 Set_OpReg(hcr_control,
4118                     (Get_OpReg(hcr_control) | HCR_CONTROL_PLE));
4119         }
4120 
4121         ohcip->ohci_open_periodic_pipe_count++;
4122 }
4123 
4124 
4125 /*
4126  * ohci_insert_isoc_ed:
4127  *
4128  * Insert a isochronous endpoint into the Host Controller's (HC) interrupt
4129  * lattice tree. A isochronous endpoint will be inserted at the end of the
4130  * 1ms interrupt endpoint list.
4131  */
4132 static void
4133 ohci_insert_isoc_ed(
4134         ohci_state_t            *ohcip,
4135         ohci_pipe_private_t     *pp)
4136 {
4137         ohci_ed_t               *next_lattice_ept, *lattice_ept;
4138         ohci_ed_t               *ept = pp->pp_ept;
4139         uint_t                  node;
4140 
4141         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4142 
4143         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4144             "ohci_insert_isoc_ed:");
4145 
4146         /*
4147          * The appropriate node was found during the opening of the pipe.
4148          * This  node must be root of the interrupt lattice tree.
4149          */
4150         node = pp->pp_node;
4151 
4152         ASSERT(node == 0);
4153 
4154         /* Find the 1ms interrupt lattice endpoint */
4155         lattice_ept = &ohcip->ohci_ed_pool_addr[node];
4156 
4157         /* Find the next lattice endpoint */
4158         next_lattice_ept = ohci_ed_iommu_to_cpu(
4159             ohcip, Get_ED(lattice_ept->hced_next));
4160 
4161         while (next_lattice_ept) {
4162                 lattice_ept = next_lattice_ept;
4163 
4164                 /* Find the next lattice endpoint */
4165                 next_lattice_ept = ohci_ed_iommu_to_cpu(
4166                     ohcip, Get_ED(lattice_ept->hced_next));
4167         }
4168 
4169         /* The next pointer is NULL */
4170         Set_ED(ept->hced_next, NULL);
4171 
4172         /* Update the previous pointer */
4173         Set_ED(ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, lattice_ept));
4174 
4175         /* Insert this endpoint into the lattice */
4176         Set_ED(lattice_ept->hced_next, ohci_ed_cpu_to_iommu(ohcip, ept));
4177 
4178         /*
4179          * Enable periodic and isoch lists processing if isoch
4180          * open pipe count is zero.
4181          */
4182         if (!ohcip->ohci_open_isoch_pipe_count) {
4183 
4184                 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) |
4185                     HCR_CONTROL_PLE | HCR_CONTROL_IE));
4186         }
4187 
4188         ohcip->ohci_open_periodic_pipe_count++;
4189         ohcip->ohci_open_isoch_pipe_count++;
4190 }
4191 
4192 
4193 /*
4194  * ohci_modify_sKip_bit:
4195  *
4196  * Modify the sKip bit on the Host Controller (HC) Endpoint Descriptor (ED).
4197  */
4198 static void
4199 ohci_modify_sKip_bit(
4200         ohci_state_t            *ohcip,
4201         ohci_pipe_private_t     *pp,
4202         skip_bit_t              action,
4203         usb_flags_t             flag)
4204 {
4205         ohci_ed_t               *ept = pp->pp_ept;
4206 
4207         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4208             "ohci_modify_sKip_bit: action = 0x%x flag = 0x%x",
4209             action, flag);
4210 
4211         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4212 
4213         if (action == CLEAR_sKip) {
4214                 /*
4215                  * If the skip bit is to be cleared, just clear it.
4216                  * there shouldn't be any race condition problems.
4217                  * If the host controller reads the bit before the
4218                  * driver has a chance to set the bit, the bit will
4219                  * be reread on the next frame.
4220                  */
4221                 Set_ED(ept->hced_ctrl, (Get_ED(ept->hced_ctrl) & ~HC_EPT_sKip));
4222         } else {
4223                 /* Sync ED and TD pool */
4224                 if (flag & OHCI_FLAGS_DMA_SYNC) {
4225                         Sync_ED_TD_Pool(ohcip);
4226                 }
4227 
4228                 /* Check Halt or Skip bit is already set */
4229                 if ((Get_ED(ept->hced_headp) & HC_EPT_Halt) ||
4230                     (Get_ED(ept->hced_ctrl) & HC_EPT_sKip)) {
4231 
4232                         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4233                             "ohci_modify_sKip_bit: "
4234                             "Halt or Skip bit is already set");
4235                 } else {
4236                         /*
4237                          * The action is to set the skip bit.  In order to
4238                          * be sure that the HCD has seen the sKip bit, wait
4239                          * for the next start of frame.
4240                          */
4241                         Set_ED(ept->hced_ctrl,
4242                             (Get_ED(ept->hced_ctrl) | HC_EPT_sKip));
4243 
4244                         if (flag & OHCI_FLAGS_SLEEP) {
4245                                 /* Wait for the next SOF */
4246                                 (void) ohci_wait_for_sof(ohcip);
4247 
4248                                 /* Sync ED and TD pool */
4249                                 if (flag & OHCI_FLAGS_DMA_SYNC) {
4250                                         Sync_ED_TD_Pool(ohcip);
4251                                 }
4252                         }
4253                 }
4254         }
4255 }
4256 
4257 
4258 /*
4259  * ohci_remove_ed:
4260  *
4261  * Remove the Endpoint Descriptor (ED) from the Host Controller's appropriate
4262  * endpoint list.
4263  */
4264 static void
4265 ohci_remove_ed(
4266         ohci_state_t            *ohcip,
4267         ohci_pipe_private_t     *pp)
4268 {
4269         uchar_t                 attributes;
4270 
4271         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4272 
4273         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4274             "ohci_remove_ed:");
4275 
4276         attributes = pp->pp_pipe_handle->p_ep.bmAttributes & USB_EP_ATTR_MASK;
4277 
4278         switch (attributes) {
4279         case USB_EP_ATTR_CONTROL:
4280                 ohci_remove_ctrl_ed(ohcip, pp);
4281                 break;
4282         case USB_EP_ATTR_BULK:
4283                 ohci_remove_bulk_ed(ohcip, pp);
4284                 break;
4285         case USB_EP_ATTR_INTR:
4286         case USB_EP_ATTR_ISOCH:
4287                 ohci_remove_periodic_ed(ohcip, pp);
4288                 break;
4289         }
4290 }
4291 
4292 
4293 /*
4294  * ohci_remove_ctrl_ed:
4295  *
4296  * Remove a control Endpoint Descriptor (ED) from the Host Controller's (HC)
4297  * control endpoint list.
4298  */
4299 static void
4300 ohci_remove_ctrl_ed(
4301         ohci_state_t            *ohcip,
4302         ohci_pipe_private_t     *pp)
4303 {
4304         ohci_ed_t               *ept = pp->pp_ept; /* ept to be removed */
4305 
4306         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4307             "ohci_remove_ctrl_ed:");
4308 
4309         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4310 
4311         /* The control list should already be stopped */
4312         ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_CLE));
4313 
4314         ohcip->ohci_open_ctrl_pipe_count--;
4315 
4316         /* Detach the endpoint from the list that it's on */
4317         ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_CONTROL);
4318 
4319         /*
4320          * If next endpoint pointed by endpoint to be removed is not NULL
4321          * then set current control pointer to the next endpoint pointed by
4322          * endpoint to be removed. Otherwise set current control pointer to
4323          * the beginning of the control list.
4324          */
4325         if (Get_ED(ept->hced_next)) {
4326                 Set_OpReg(hcr_ctrl_curr, Get_ED(ept->hced_next));
4327         } else {
4328                 Set_OpReg(hcr_ctrl_curr, Get_OpReg(hcr_ctrl_head));
4329         }
4330 
4331         if (ohcip->ohci_open_ctrl_pipe_count) {
4332                 ASSERT(Get_OpReg(hcr_ctrl_head));
4333 
4334                 /* Reenable the control list */
4335                 Set_OpReg(hcr_control,
4336                     (Get_OpReg(hcr_control) | HCR_CONTROL_CLE));
4337         }
4338 
4339         ohci_insert_ed_on_reclaim_list(ohcip, pp);
4340 }
4341 
4342 
4343 /*
4344  * ohci_remove_bulk_ed:
4345  *
4346  * Remove free the  bulk Endpoint Descriptor (ED) from the Host Controller's
4347  * (HC) bulk endpoint list.
4348  */
4349 static void
4350 ohci_remove_bulk_ed(
4351         ohci_state_t            *ohcip,
4352         ohci_pipe_private_t     *pp)
4353 {
4354         ohci_ed_t               *ept = pp->pp_ept;   /* ept to be removed */
4355 
4356         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4357             "ohci_remove_bulk_ed:");
4358 
4359         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4360 
4361         /* The bulk list should already be stopped */
4362         ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_BLE));
4363 
4364         ohcip->ohci_open_bulk_pipe_count--;
4365 
4366         /* Detach the endpoint from the bulk list */
4367         ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_BULK);
4368 
4369         /*
4370          * If next endpoint pointed by endpoint to be removed is not NULL
4371          * then set current bulk pointer to the next endpoint pointed by
4372          * endpoint to be removed. Otherwise set current bulk pointer to
4373          * the beginning of the bulk list.
4374          */
4375         if (Get_ED(ept->hced_next)) {
4376                 Set_OpReg(hcr_bulk_curr, Get_ED(ept->hced_next));
4377         } else {
4378                 Set_OpReg(hcr_bulk_curr, Get_OpReg(hcr_bulk_head));
4379         }
4380 
4381         if (ohcip->ohci_open_bulk_pipe_count) {
4382                 ASSERT(Get_OpReg(hcr_bulk_head));
4383 
4384                 /* Re-enable the bulk list */
4385                 Set_OpReg(hcr_control,
4386                     (Get_OpReg(hcr_control) | HCR_CONTROL_BLE));
4387         }
4388 
4389         ohci_insert_ed_on_reclaim_list(ohcip, pp);
4390 }
4391 
4392 
4393 /*
4394  * ohci_remove_periodic_ed:
4395  *
4396  * Set up an periodic endpoint to be removed from the Host Controller's (HC)
4397  * interrupt lattice tree. The Endpoint Descriptor (ED) will be freed in the
4398  * interrupt handler.
4399  */
4400 static void
4401 ohci_remove_periodic_ed(
4402         ohci_state_t            *ohcip,
4403         ohci_pipe_private_t     *pp)
4404 {
4405         ohci_ed_t               *ept = pp->pp_ept;   /* ept to be removed */
4406         uint_t                  ept_type;
4407 
4408         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4409             "ohci_remove_periodic_ed:");
4410 
4411         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4412 
4413         ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) ==
4414             (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
4415 
4416         ohcip->ohci_open_periodic_pipe_count--;
4417 
4418         ept_type = pp->pp_pipe_handle->
4419             p_ep.bmAttributes & USB_EP_ATTR_MASK;
4420 
4421         if (ept_type == USB_EP_ATTR_ISOCH) {
4422                 ohcip->ohci_open_isoch_pipe_count--;
4423         }
4424 
4425         /* Store the node number */
4426         Set_ED(ept->hced_node, pp->pp_node);
4427 
4428         /* Remove the endpoint from interrupt lattice tree */
4429         ohci_detach_ed_from_list(ohcip, ept, ept_type);
4430 
4431         /*
4432          * Disable isoch list processing if isoch open pipe count
4433          * is zero.
4434          */
4435         if (!ohcip->ohci_open_isoch_pipe_count) {
4436                 Set_OpReg(hcr_control,
4437                     (Get_OpReg(hcr_control) & ~(HCR_CONTROL_IE)));
4438         }
4439 
4440         /*
4441          * Disable periodic list processing if periodic (interrupt
4442          * and isochrous) open pipe count is zero.
4443          */
4444         if (!ohcip->ohci_open_periodic_pipe_count) {
4445                 ASSERT(!ohcip->ohci_open_isoch_pipe_count);
4446 
4447                 Set_OpReg(hcr_control,
4448                     (Get_OpReg(hcr_control) & ~(HCR_CONTROL_PLE)));
4449         }
4450 
4451         ohci_insert_ed_on_reclaim_list(ohcip, pp);
4452 }
4453 
4454 
4455 /*
4456  * ohci_detach_ed_from_list:
4457  *
4458  * Remove the Endpoint Descriptor (ED) from the appropriate Host Controller's
4459  * (HC) endpoint list.
4460  */
4461 static void
4462 ohci_detach_ed_from_list(
4463         ohci_state_t    *ohcip,
4464         ohci_ed_t       *ept,
4465         uint_t          ept_type)
4466 {
4467         ohci_ed_t       *prev_ept;      /* Previous endpoint */
4468         ohci_ed_t       *next_ept;      /* Endpoint after one to be removed */
4469         uint_t          node;
4470 
4471         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4472             "ohci_detach_ed_from_list:");
4473 
4474         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4475 
4476         prev_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_prev));
4477         next_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_next));
4478 
4479         /*
4480          * If there is no previous endpoint, then this
4481          * endpoint is at the head of the endpoint list.
4482          */
4483         if (prev_ept == NULL) {
4484                 if (next_ept) {
4485                         /*
4486                          * If this endpoint is the first element of the
4487                          * list and there is more  than one endpoint on
4488                          * the list then perform specific actions based
4489                          * on the type of endpoint list.
4490                          */
4491                         switch (ept_type) {
4492                         case USB_EP_ATTR_CONTROL:
4493                                 /* Set the head of list to next ept */
4494                                 Set_OpReg(hcr_ctrl_head,
4495                                     Get_ED(ept->hced_next));
4496 
4497                                 /* Clear prev ptr of  next endpoint */
4498                                 Set_ED(next_ept->hced_prev,  NULL);
4499                                 break;
4500                         case USB_EP_ATTR_BULK:
4501                                 /* Set the head of list to next ept */
4502                                 Set_OpReg(hcr_bulk_head,
4503                                     Get_ED(ept->hced_next));
4504 
4505                                 /* Clear prev ptr of  next endpoint */
4506                                 Set_ED(next_ept->hced_prev, NULL);
4507                                 break;
4508                         case USB_EP_ATTR_INTR:
4509                                 /*
4510                                  * HCCA area should point
4511                                  * directly to this ept.
4512                                  */
4513                                 ASSERT(Get_ED(ept->hced_node) >=
4514                                     NUM_STATIC_NODES);
4515 
4516                                 /* Get the hcca interrupt table index */
4517                                 node = ohci_hcca_intr_index(
4518                                     Get_ED(ept->hced_node));
4519 
4520                                 /*
4521                                  * Delete the ept from the
4522                                  * bottom of the tree.
4523                                  */
4524                                 Set_HCCA(ohcip->ohci_hccap->
4525                                     HccaIntTble[node], Get_ED(ept->hced_next));
4526 
4527                                 /*
4528                                  * Update the previous pointer
4529                                  * of ept->hced_next
4530                                  */
4531                                 if (Get_ED(next_ept->hced_state) !=
4532                                     HC_EPT_STATIC) {
4533 
4534                                         Set_ED(next_ept->hced_prev, NULL);
4535                                 }
4536 
4537                                 break;
4538                         case USB_EP_ATTR_ISOCH:
4539                         default:
4540                                 break;
4541                         }
4542                 } else {
4543                         /*
4544                          * If there was only one element on the list
4545                          * perform specific actions based on the type
4546                          * of the list.
4547                          */
4548                         switch (ept_type) {
4549                         case USB_EP_ATTR_CONTROL:
4550                                 /* Set the head to NULL */
4551                                 Set_OpReg(hcr_ctrl_head, NULL);
4552                                 break;
4553                         case USB_EP_ATTR_BULK:
4554                                 /* Set the head to NULL */
4555                                 Set_OpReg(hcr_bulk_head, NULL);
4556                                 break;
4557                         case USB_EP_ATTR_INTR:
4558                         case USB_EP_ATTR_ISOCH:
4559                         default:
4560                                 break;
4561                         }
4562                 }
4563         } else {
4564                 /* The previous ept points to the next one */
4565                 Set_ED(prev_ept->hced_next, Get_ED(ept->hced_next));
4566 
4567                 /*
4568                  * Set the previous ptr of the next_ept to prev_ept
4569                  * if this isn't the last endpoint on the list
4570                  */
4571                 if ((next_ept) &&
4572                     (Get_ED(next_ept->hced_state) != HC_EPT_STATIC)) {
4573 
4574                         /* Set the previous ptr of the next one */
4575                         Set_ED(next_ept->hced_prev, Get_ED(ept->hced_prev));
4576                 }
4577         }
4578 }
4579 
4580 
4581 /*
4582  * ohci_insert_ed_on_reclaim_list:
4583  *
4584  * Insert Endpoint onto the reclaim list
4585  */
4586 static void
4587 ohci_insert_ed_on_reclaim_list(
4588         ohci_state_t            *ohcip,
4589         ohci_pipe_private_t     *pp)
4590 {
4591         ohci_ed_t               *ept = pp->pp_ept; /* ept to be removed */
4592         ohci_ed_t               *next_ept, *prev_ept;
4593         usb_frame_number_t      frame_number;
4594 
4595         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4596 
4597         /*
4598          * Read current usb frame number and add appropriate number of
4599          * usb frames needs to wait before reclaiming current endpoint.
4600          */
4601         frame_number =
4602             ohci_get_current_frame_number(ohcip) + MAX_SOF_WAIT_COUNT;
4603 
4604         /* Store 32bit ID */
4605         Set_ED(ept->hced_reclaim_frame,
4606             ((uint32_t)(OHCI_GET_ID((void *)(uintptr_t)frame_number))));
4607 
4608         /* Insert the endpoint onto the reclaimation list */
4609         if (ohcip->ohci_reclaim_list) {
4610                 next_ept = ohcip->ohci_reclaim_list;
4611 
4612                 while (next_ept) {
4613                         prev_ept = next_ept;
4614                         next_ept = ohci_ed_iommu_to_cpu(ohcip,
4615                             Get_ED(next_ept->hced_reclaim_next));
4616                 }
4617 
4618                 Set_ED(prev_ept->hced_reclaim_next,
4619                     ohci_ed_cpu_to_iommu(ohcip, ept));
4620         } else {
4621                 ohcip->ohci_reclaim_list = ept;
4622         }
4623 
4624         ASSERT(Get_ED(ept->hced_reclaim_next) == NULL);
4625 
4626         /* Enable the SOF interrupt */
4627         Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
4628 }
4629 
4630 
4631 /*
4632  * ohci_deallocate_ed:
4633  * NOTE: This function is also called from POLLED MODE.
4634  *
4635  * Deallocate a Host Controller's (HC) Endpoint Descriptor (ED).
4636  */
4637 void
4638 ohci_deallocate_ed(
4639         ohci_state_t    *ohcip,
4640         ohci_ed_t       *old_ed)
4641 {
4642         ohci_td_t       *dummy_td;
4643 
4644         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4645             "ohci_deallocate_ed:");
4646 
4647         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4648 
4649         dummy_td = ohci_td_iommu_to_cpu(ohcip, Get_ED(old_ed->hced_headp));
4650 
4651         if (dummy_td) {
4652 
4653                 ASSERT(Get_TD(dummy_td->hctd_state) == HC_TD_DUMMY);
4654                 ohci_deallocate_td(ohcip, dummy_td);
4655         }
4656 
4657         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4658             "ohci_deallocate_ed: Deallocated 0x%p", (void *)old_ed);
4659 
4660         bzero((void *)old_ed, sizeof (ohci_ed_t));
4661         Set_ED(old_ed->hced_state, HC_EPT_FREE);
4662 }
4663 
4664 
4665 /*
4666  * ohci_ed_cpu_to_iommu:
4667  * NOTE: This function is also called from POLLED MODE.
4668  *
4669  * This function converts for the given Endpoint Descriptor (ED) CPU address
4670  * to IO address.
4671  */
4672 uint32_t
4673 ohci_ed_cpu_to_iommu(
4674         ohci_state_t    *ohcip,
4675         ohci_ed_t       *addr)
4676 {
4677         uint32_t        ed;
4678 
4679         ed = (uint32_t)ohcip->ohci_ed_pool_cookie.dmac_address +
4680             (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_ed_pool_addr));
4681 
4682         ASSERT(ed >= ohcip->ohci_ed_pool_cookie.dmac_address);
4683         ASSERT(ed <= ohcip->ohci_ed_pool_cookie.dmac_address +
4684             sizeof (ohci_ed_t) * ohci_ed_pool_size);
4685 
4686         return (ed);
4687 }
4688 
4689 
4690 /*
4691  * ohci_ed_iommu_to_cpu:
4692  *
4693  * This function converts for the given Endpoint Descriptor (ED) IO address
4694  * to CPU address.
4695  */
4696 static ohci_ed_t *
4697 ohci_ed_iommu_to_cpu(
4698         ohci_state_t    *ohcip,
4699         uintptr_t       addr)
4700 {
4701         ohci_ed_t       *ed;
4702 
4703         if (addr == NULL) {
4704 
4705                 return (NULL);
4706         }
4707 
4708         ed = (ohci_ed_t *)((uintptr_t)
4709             (addr - ohcip->ohci_ed_pool_cookie.dmac_address) +
4710             (uintptr_t)ohcip->ohci_ed_pool_addr);
4711 
4712         ASSERT(ed >= ohcip->ohci_ed_pool_addr);
4713         ASSERT((uintptr_t)ed <= (uintptr_t)ohcip->ohci_ed_pool_addr +
4714             (uintptr_t)(sizeof (ohci_ed_t) * ohci_ed_pool_size));
4715 
4716         return (ed);
4717 }
4718 
4719 
4720 /*
4721  * Transfer Descriptor manipulations functions
4722  */
4723 
4724 /*
4725  * ohci_initialize_dummy:
4726  *
4727  * An Endpoint Descriptor (ED) has a  dummy Transfer Descriptor (TD) on the
4728  * end of its TD list. Initially, both the head and tail pointers of the ED
4729  * point to the dummy TD.
4730  */
4731 static int
4732 ohci_initialize_dummy(
4733         ohci_state_t    *ohcip,
4734         ohci_ed_t       *ept)
4735 {
4736         ohci_td_t *dummy;
4737 
4738         /* Obtain a  dummy TD */
4739         dummy = ohci_allocate_td_from_pool(ohcip);
4740 
4741         if (dummy == NULL) {
4742                 return (USB_NO_RESOURCES);
4743         }
4744 
4745         /*
4746          * Both the head and tail pointers of an ED point
4747          * to this new dummy TD.
4748          */
4749         Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, dummy)));
4750         Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy)));
4751 
4752         return (USB_SUCCESS);
4753 }
4754 
4755 /*
4756  * ohci_allocate_ctrl_resources:
4757  *
4758  * Calculates the number of tds necessary for a ctrl transfer, and allocates
4759  * all the resources necessary.
4760  *
4761  * Returns NULL if there is insufficient resources otherwise TW.
4762  */
4763 static ohci_trans_wrapper_t *
4764 ohci_allocate_ctrl_resources(
4765         ohci_state_t            *ohcip,
4766         ohci_pipe_private_t     *pp,
4767         usb_ctrl_req_t          *ctrl_reqp,
4768         usb_flags_t             usb_flags)
4769 {
4770         size_t                  td_count = 2;
4771         size_t                  ctrl_buf_size;
4772         ohci_trans_wrapper_t    *tw;
4773 
4774         /* Add one more td for data phase */
4775         if (ctrl_reqp->ctrl_wLength) {
4776                 td_count++;
4777         }
4778 
4779         /*
4780          * If we have a control data phase, the data buffer starts
4781          * on the next 4K page boundary. So the TW buffer is allocated
4782          * to be larger than required. The buffer in the range of
4783          * [SETUP_SIZE, OHCI_MAX_TD_BUF_SIZE) is just for padding
4784          * and not to be transferred.
4785          */
4786         if (ctrl_reqp->ctrl_wLength) {
4787                 ctrl_buf_size = OHCI_MAX_TD_BUF_SIZE +
4788                     ctrl_reqp->ctrl_wLength;
4789         } else {
4790                 ctrl_buf_size = SETUP_SIZE;
4791         }
4792 
4793         tw = ohci_allocate_tw_resources(ohcip, pp, ctrl_buf_size,
4794             usb_flags, td_count);
4795 
4796         return (tw);
4797 }
4798 
4799 /*
4800  * ohci_insert_ctrl_req:
4801  *
4802  * Create a Transfer Descriptor (TD) and a data buffer for a control endpoint.
4803  */
4804 /* ARGSUSED */
4805 static void
4806 ohci_insert_ctrl_req(
4807         ohci_state_t            *ohcip,
4808         usba_pipe_handle_data_t *ph,
4809         usb_ctrl_req_t          *ctrl_reqp,
4810         ohci_trans_wrapper_t    *tw,
4811         usb_flags_t             usb_flags)
4812 {
4813         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
4814         uchar_t                 bmRequestType = ctrl_reqp->ctrl_bmRequestType;
4815         uchar_t                 bRequest = ctrl_reqp->ctrl_bRequest;
4816         uint16_t                wValue = ctrl_reqp->ctrl_wValue;
4817         uint16_t                wIndex = ctrl_reqp->ctrl_wIndex;
4818         uint16_t                wLength = ctrl_reqp->ctrl_wLength;
4819         mblk_t                  *data = ctrl_reqp->ctrl_data;
4820         uint32_t                ctrl = 0;
4821         int                     sdata;
4822 
4823         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4824             "ohci_insert_ctrl_req:");
4825 
4826         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4827 
4828         /*
4829          * Save current control request pointer and timeout values
4830          * in transfer wrapper.
4831          */
4832         tw->tw_curr_xfer_reqp = (usb_opaque_t)ctrl_reqp;
4833         tw->tw_timeout = ctrl_reqp->ctrl_timeout ?
4834             ctrl_reqp->ctrl_timeout : OHCI_DEFAULT_XFER_TIMEOUT;
4835 
4836         /*
4837          * Initialize the callback and any callback data for when
4838          * the td completes.
4839          */
4840         tw->tw_handle_td = ohci_handle_ctrl_td;
4841         tw->tw_handle_callback_value = NULL;
4842 
4843         /* Create the first four bytes of the setup packet */
4844         sdata = (bmRequestType << 24) | (bRequest << 16) |
4845             (((wValue >> 8) | (wValue << 8)) & 0x0000FFFF);
4846 
4847         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4848             "ohci_create_setup_pkt: sdata = 0x%x", sdata);
4849 
4850         ddi_put32(tw->tw_accesshandle, (uint_t *)tw->tw_buf, sdata);
4851 
4852         /* Create the second four bytes */
4853         sdata = (uint32_t)(((((wIndex >> 8) |
4854             (wIndex << 8)) << 16) & 0xFFFF0000) |
4855             (((wLength >> 8) | (wLength << 8)) & 0x0000FFFF));
4856 
4857         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4858             "ohci_create_setup_pkt: sdata = 0x%x", sdata);
4859 
4860         ddi_put32(tw->tw_accesshandle,
4861             (uint_t *)((uintptr_t)tw->tw_buf + sizeof (uint_t)), sdata);
4862 
4863         ctrl = HC_TD_SETUP|HC_TD_MS_DT|HC_TD_DT_0|HC_TD_6I;
4864 
4865         /*
4866          * The TD's are placed on the ED one at a time.
4867          * Once this TD is placed on the done list, the
4868          * data or status phase TD will be enqueued.
4869          */
4870         (void) ohci_insert_hc_td(ohcip, ctrl, 0, SETUP_SIZE,
4871             OHCI_CTRL_SETUP_PHASE, pp, tw);
4872 
4873         USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4874             "Create_setup: pp 0x%p", (void *)pp);
4875 
4876         /*
4877          * If this control transfer has a data phase, record the
4878          * direction. If the data phase is an OUT transaction,
4879          * copy the data into the buffer of the transfer wrapper.
4880          */
4881         if (wLength != 0) {
4882                 /* There is a data stage.  Find the direction */
4883                 if (bmRequestType & USB_DEV_REQ_DEV_TO_HOST) {
4884                         tw->tw_direction = HC_TD_IN;
4885                 } else {
4886                         tw->tw_direction = HC_TD_OUT;
4887 
4888                         /* Copy the data into the message */
4889                         ddi_rep_put8(tw->tw_accesshandle, data->b_rptr,
4890                             (uint8_t *)(tw->tw_buf + OHCI_MAX_TD_BUF_SIZE),
4891                             wLength, DDI_DEV_AUTOINCR);
4892 
4893                 }
4894 
4895                 ctrl = (ctrl_reqp->ctrl_attributes & USB_ATTRS_SHORT_XFER_OK) ?
4896                     HC_TD_R : 0;
4897 
4898                 /*
4899                  * There is a data stage.
4900                  * Find the direction.
4901                  */
4902                 if (tw->tw_direction == HC_TD_IN) {
4903                         ctrl = ctrl|HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I;
4904                 } else {
4905                         ctrl = ctrl|HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I;
4906                 }
4907 
4908                 /*
4909                  * Create the TD.  If this is an OUT transaction,
4910                  * the data is already in the buffer of the TW.
4911                  */
4912                 (void) ohci_insert_hc_td(ohcip, ctrl, OHCI_MAX_TD_BUF_SIZE,
4913                     wLength, OHCI_CTRL_DATA_PHASE, pp, tw);
4914 
4915                 /*
4916                  * The direction of the STATUS TD depends on
4917                  * the direction of the transfer.
4918                  */
4919                 if (tw->tw_direction == HC_TD_IN) {
4920                         ctrl = HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4921                 } else {
4922                         ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4923                 }
4924         } else {
4925                 ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4926         }
4927 
4928         /* Status stage */
4929         (void) ohci_insert_hc_td(ohcip, ctrl, 0,
4930             0, OHCI_CTRL_STATUS_PHASE, pp, tw);
4931 
4932         /* Indicate that the control list is filled */
4933         Set_OpReg(hcr_cmd_status, HCR_STATUS_CLF);
4934 
4935         /* Start the timer for this control transfer */
4936         ohci_start_xfer_timer(ohcip, pp, tw);
4937 }
4938 
4939 /*
4940  * ohci_allocate_bulk_resources:
4941  *
4942  * Calculates the number of tds necessary for a ctrl transfer, and allocates
4943  * all the resources necessary.
4944  *
4945  * Returns NULL if there is insufficient resources otherwise TW.
4946  */
4947 static ohci_trans_wrapper_t *
4948 ohci_allocate_bulk_resources(
4949         ohci_state_t            *ohcip,
4950         ohci_pipe_private_t     *pp,
4951         usb_bulk_req_t          *bulk_reqp,
4952         usb_flags_t             usb_flags)
4953 {
4954         size_t                  td_count = 0;
4955         ohci_trans_wrapper_t    *tw;
4956 
4957         /* Check the size of bulk request */
4958         if (bulk_reqp->bulk_len > OHCI_MAX_BULK_XFER_SIZE) {
4959 
4960                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4961                     "ohci_allocate_bulk_resources: Bulk request size 0x%x is "
4962                     "more than 0x%x", bulk_reqp->bulk_len,
4963                     OHCI_MAX_BULK_XFER_SIZE);
4964 
4965                 return (NULL);
4966         }
4967 
4968         /* Get the required bulk packet size */
4969         td_count = bulk_reqp->bulk_len / OHCI_MAX_TD_XFER_SIZE;
4970         if (bulk_reqp->bulk_len % OHCI_MAX_TD_XFER_SIZE ||
4971             bulk_reqp->bulk_len == 0) {
4972                 td_count++;
4973         }
4974 
4975         tw = ohci_allocate_tw_resources(ohcip, pp, bulk_reqp->bulk_len,
4976             usb_flags, td_count);
4977 
4978         return (tw);
4979 }
4980 
4981 /*
4982  * ohci_insert_bulk_req:
4983  *
4984  * Create a Transfer Descriptor (TD) and a data buffer for a bulk
4985  * endpoint.
4986  */
4987 /* ARGSUSED */
4988 static void
4989 ohci_insert_bulk_req(
4990         ohci_state_t            *ohcip,
4991         usba_pipe_handle_data_t *ph,
4992         usb_bulk_req_t          *bulk_reqp,
4993         ohci_trans_wrapper_t    *tw,
4994         usb_flags_t             flags)
4995 {
4996         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
4997         uint_t                  bulk_pkt_size, count;
4998         size_t                  residue = 0, len = 0;
4999         uint32_t                ctrl = 0;
5000         int                     pipe_dir;
5001 
5002         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5003             "ohci_insert_bulk_req: bulk_reqp = 0x%p flags = 0x%x",
5004             (void *)bulk_reqp, flags);
5005 
5006         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5007 
5008         /* Get the bulk pipe direction */
5009         pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5010 
5011         /* Get the required bulk packet size */
5012         bulk_pkt_size = min(bulk_reqp->bulk_len, OHCI_MAX_TD_XFER_SIZE);
5013 
5014         if (bulk_pkt_size)
5015                 residue = tw->tw_length % bulk_pkt_size;
5016 
5017         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5018             "ohci_insert_bulk_req: bulk_pkt_size = %d", bulk_pkt_size);
5019 
5020         /*
5021          * Save current bulk request pointer and timeout values
5022          * in transfer wrapper.
5023          */
5024         tw->tw_curr_xfer_reqp = (usb_opaque_t)bulk_reqp;
5025         tw->tw_timeout = bulk_reqp->bulk_timeout;
5026 
5027         /*
5028          * Initialize the callback and any callback
5029          * data required when the td completes.
5030          */
5031         tw->tw_handle_td = ohci_handle_bulk_td;
5032         tw->tw_handle_callback_value = NULL;
5033 
5034         tw->tw_direction =
5035             (pipe_dir == USB_EP_DIR_OUT) ? HC_TD_OUT : HC_TD_IN;
5036 
5037         if (tw->tw_direction == HC_TD_OUT && bulk_reqp->bulk_len) {
5038 
5039                 ASSERT(bulk_reqp->bulk_data != NULL);
5040 
5041                 /* Copy the data into the message */
5042                 ddi_rep_put8(tw->tw_accesshandle,
5043                     bulk_reqp->bulk_data->b_rptr, (uint8_t *)tw->tw_buf,
5044                     bulk_reqp->bulk_len, DDI_DEV_AUTOINCR);
5045         }
5046 
5047         ctrl = tw->tw_direction|HC_TD_DT_0|HC_TD_6I;
5048 
5049         /* Insert all the bulk TDs */
5050         for (count = 0; count < tw->tw_num_tds; count++) {
5051 
5052                 /* Check for last td */
5053                 if (count == (tw->tw_num_tds - 1)) {
5054 
5055                         ctrl = ((ctrl & ~HC_TD_DI) | HC_TD_1I);
5056 
5057                         /* Check for inserting residue data */
5058                         if (residue) {
5059                                 bulk_pkt_size = (uint_t)residue;
5060                         }
5061 
5062                         /*
5063                          * Only set the round bit on the last TD, to ensure
5064                          * the controller will always HALT the ED in case of
5065                          * a short transfer.
5066                          */
5067                         if (bulk_reqp->bulk_attributes &
5068                             USB_ATTRS_SHORT_XFER_OK) {
5069                                 ctrl |= HC_TD_R;
5070                         }
5071                 }
5072 
5073                 /* Insert the TD onto the endpoint */
5074                 (void) ohci_insert_hc_td(ohcip, ctrl, len,
5075                     bulk_pkt_size, 0, pp, tw);
5076 
5077                 len = len + bulk_pkt_size;
5078         }
5079 
5080         /* Indicate that the bulk list is filled */
5081         Set_OpReg(hcr_cmd_status, HCR_STATUS_BLF);
5082 
5083         /* Start the timer for this bulk transfer */
5084         ohci_start_xfer_timer(ohcip, pp, tw);
5085 }
5086 
5087 
5088 /*
5089  * ohci_start_periodic_pipe_polling:
5090  * NOTE: This function is also called from POLLED MODE.
5091  */
5092 int
5093 ohci_start_periodic_pipe_polling(
5094         ohci_state_t            *ohcip,
5095         usba_pipe_handle_data_t *ph,
5096         usb_opaque_t            periodic_in_reqp,
5097         usb_flags_t             flags)
5098 {
5099         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5100         usb_ep_descr_t          *eptd = &ph->p_ep;
5101         int                     error = USB_SUCCESS;
5102 
5103         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5104             "ohci_start_periodic_pipe_polling: ep%d",
5105             ph->p_ep.bEndpointAddress & USB_EP_NUM_MASK);
5106 
5107         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5108 
5109         /*
5110          * Check and handle start polling on root hub interrupt pipe.
5111          */
5112         if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) &&
5113             ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
5114             USB_EP_ATTR_INTR)) {
5115 
5116                 error = ohci_handle_root_hub_pipe_start_intr_polling(ph,
5117                     (usb_intr_req_t *)periodic_in_reqp, flags);
5118 
5119                 return (error);
5120         }
5121 
5122         switch (pp->pp_state) {
5123         case OHCI_PIPE_STATE_IDLE:
5124                 /* Save the Original client's Periodic IN request */
5125                 pp->pp_client_periodic_in_reqp = periodic_in_reqp;
5126 
5127                 /*
5128                  * This pipe is uninitialized or if a valid TD is
5129                  * not found then insert a TD on the interrupt or
5130                  * isochronous IN endpoint.
5131                  */
5132                 error = ohci_start_pipe_polling(ohcip, ph, flags);
5133 
5134                 if (error != USB_SUCCESS) {
5135                         USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5136                             "ohci_start_periodic_pipe_polling: "
5137                             "Start polling failed");
5138 
5139                         pp->pp_client_periodic_in_reqp = NULL;
5140 
5141                         return (error);
5142                 }
5143 
5144                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
5145                     "ohci_start_periodic_pipe_polling: PP = 0x%p", (void *)pp);
5146 
5147                 ASSERT((pp->pp_tw_head != NULL) && (pp->pp_tw_tail != NULL));
5148 
5149                 break;
5150         case OHCI_PIPE_STATE_ACTIVE:
5151                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5152                     "ohci_start_periodic_pipe_polling: "
5153                     "Polling is already in progress");
5154 
5155                 error = USB_FAILURE;
5156                 break;
5157         case OHCI_PIPE_STATE_ERROR:
5158                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5159                     "ohci_start_periodic_pipe_polling: "
5160                     "Pipe is halted and perform reset before restart polling");
5161 
5162                 error = USB_FAILURE;
5163                 break;
5164         default:
5165                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5166                     "ohci_start_periodic_pipe_polling: Undefined state");
5167 
5168                 error = USB_FAILURE;
5169                 break;
5170         }
5171 
5172         return (error);
5173 }
5174 
5175 
5176 /*
5177  * ohci_start_pipe_polling:
5178  *
5179  * Insert the number of periodic requests corresponding to polling
5180  * interval as calculated during pipe open.
5181  */
5182 static int
5183 ohci_start_pipe_polling(
5184         ohci_state_t            *ohcip,
5185         usba_pipe_handle_data_t *ph,
5186         usb_flags_t             flags)
5187 {
5188         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5189         usb_ep_descr_t          *eptd = &ph->p_ep;
5190         ohci_trans_wrapper_t    *tw_list, *tw;
5191         int                     i, total_tws;
5192         int                     error = USB_SUCCESS;
5193 
5194         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5195             "ohci_start_pipe_polling:");
5196 
5197         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5198 
5199         /*
5200          * For the start polling, pp_max_periodic_req_cnt will be zero
5201          * and for the restart polling request, it will be non zero.
5202          *
5203          * In case of start polling request, find out number of requests
5204          * required for the Interrupt IN endpoints corresponding to the
5205          * endpoint polling interval. For Isochronous IN endpoints, it is
5206          * always fixed since its polling interval will be one ms.
5207          */
5208         if (pp->pp_max_periodic_req_cnt == 0) {
5209 
5210                 ohci_set_periodic_pipe_polling(ohcip, ph);
5211         }
5212 
5213         ASSERT(pp->pp_max_periodic_req_cnt != 0);
5214 
5215         /* Allocate all the necessary resources for the IN transfer */
5216         tw_list = NULL;
5217         total_tws = pp->pp_max_periodic_req_cnt - pp->pp_cur_periodic_req_cnt;
5218         for (i = 0; i < total_tws; i++) {
5219                 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
5220                 case USB_EP_ATTR_INTR:
5221                         tw = ohci_allocate_intr_resources(
5222                             ohcip, ph, NULL, flags);
5223                         break;
5224                 case USB_EP_ATTR_ISOCH:
5225                         tw = ohci_allocate_isoc_resources(
5226                             ohcip, ph, NULL, flags);
5227                         break;
5228                 }
5229                 if (tw == NULL) {
5230                         error = USB_NO_RESOURCES;
5231                         /* There are not enough resources, deallocate the TWs */
5232                         tw = tw_list;
5233                         while (tw != NULL) {
5234                                 tw_list = tw->tw_next;
5235                                 ohci_deallocate_periodic_in_resource(
5236                                     ohcip, pp, tw);
5237                                 ohci_deallocate_tw_resources(ohcip, pp, tw);
5238                                 tw = tw_list;
5239                         }
5240                         return (error);
5241                 } else {
5242                         if (tw_list == NULL) {
5243                                 tw_list = tw;
5244                         }
5245                 }
5246         }
5247 
5248         i = 0;
5249         while (pp->pp_cur_periodic_req_cnt < pp->pp_max_periodic_req_cnt) {
5250 
5251                 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5252                     "ohci_start_pipe_polling: max = %d curr = %d tw = %p:",
5253                     pp->pp_max_periodic_req_cnt, pp->pp_cur_periodic_req_cnt,
5254                     (void *)tw_list);
5255 
5256                 tw = tw_list;
5257                 tw_list = tw->tw_next;
5258 
5259                 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
5260                 case USB_EP_ATTR_INTR:
5261                         ohci_insert_intr_req(ohcip, pp, tw, flags);
5262                         break;
5263                 case USB_EP_ATTR_ISOCH:
5264                         error = ohci_insert_isoc_req(ohcip, pp, tw, flags);
5265                         break;
5266                 }
5267                 if (error == USB_SUCCESS) {
5268                         pp->pp_cur_periodic_req_cnt++;
5269                 } else {
5270                         /*
5271                          * Deallocate the remaining tw
5272                          * The current tw should have already been deallocated
5273                          */
5274                         tw = tw_list;
5275                         while (tw != NULL) {
5276                                 tw_list = tw->tw_next;
5277                                 ohci_deallocate_periodic_in_resource(
5278                                     ohcip, pp, tw);
5279                                 ohci_deallocate_tw_resources(ohcip, pp, tw);
5280                                 tw = tw_list;
5281                         }
5282                         /*
5283                          * If this is the first req return an error.
5284                          * Otherwise return success.
5285                          */
5286                         if (i != 0) {
5287                                 error = USB_SUCCESS;
5288                         }
5289 
5290                         break;
5291                 }
5292                 i++;
5293         }
5294 
5295         return (error);
5296 }
5297 
5298 
5299 /*
5300  * ohci_set_periodic_pipe_polling:
5301  *
5302  * Calculate the number of periodic requests needed corresponding to the
5303  * interrupt/isochronous IN endpoints polling interval. Table below gives
5304  * the number of periodic requests needed for the interrupt/isochronous
5305  * IN endpoints according to endpoint polling interval.
5306  *
5307  * Polling interval             Number of periodic requests
5308  *
5309  * 1ms                          4
5310  * 2ms                          2
5311  * 4ms to 32ms                  1
5312  */
5313 static void
5314 ohci_set_periodic_pipe_polling(
5315         ohci_state_t            *ohcip,
5316         usba_pipe_handle_data_t *ph)
5317 {
5318         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5319         usb_ep_descr_t          *endpoint = &ph->p_ep;
5320         uchar_t                 ep_attr = endpoint->bmAttributes;
5321         uint_t                  interval;
5322 
5323         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5324             "ohci_set_periodic_pipe_polling:");
5325 
5326         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5327 
5328         pp->pp_cur_periodic_req_cnt = 0;
5329 
5330         /*
5331          * Check usb flag whether USB_FLAGS_ONE_TIME_POLL flag is
5332          * set and if so, set pp->pp_max_periodic_req_cnt to one.
5333          */
5334         if (((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) &&
5335             (pp->pp_client_periodic_in_reqp)) {
5336                 usb_intr_req_t *intr_reqp =
5337                     (usb_intr_req_t *)pp->pp_client_periodic_in_reqp;
5338 
5339                 if (intr_reqp->intr_attributes &
5340                     USB_ATTRS_ONE_XFER) {
5341 
5342                         pp->pp_max_periodic_req_cnt = INTR_XMS_REQS;
5343 
5344                         return;
5345                 }
5346         }
5347 
5348         mutex_enter(&ph->p_usba_device->usb_mutex);
5349 
5350         /*
5351          * The ohci_adjust_polling_interval function will not fail
5352          * at this instance since bandwidth allocation is already
5353          * done. Here we are getting only the periodic interval.
5354          */
5355         interval = ohci_adjust_polling_interval(ohcip, endpoint,
5356             ph->p_usba_device->usb_port_status);
5357 
5358         mutex_exit(&ph->p_usba_device->usb_mutex);
5359 
5360         switch (interval) {
5361         case INTR_1MS_POLL:
5362                 pp->pp_max_periodic_req_cnt = INTR_1MS_REQS;
5363                 break;
5364         case INTR_2MS_POLL:
5365                 pp->pp_max_periodic_req_cnt = INTR_2MS_REQS;
5366                 break;
5367         default:
5368                 pp->pp_max_periodic_req_cnt = INTR_XMS_REQS;
5369                 break;
5370         }
5371 
5372         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5373             "ohci_set_periodic_pipe_polling: Max periodic requests = %d",
5374             pp->pp_max_periodic_req_cnt);
5375 }
5376 
5377 /*
5378  * ohci_allocate_intr_resources:
5379  *
5380  * Calculates the number of tds necessary for a intr transfer, and allocates
5381  * all the necessary resources.
5382  *
5383  * Returns NULL if there is insufficient resources otherwise TW.
5384  */
5385 static ohci_trans_wrapper_t *
5386 ohci_allocate_intr_resources(
5387         ohci_state_t            *ohcip,
5388         usba_pipe_handle_data_t *ph,
5389         usb_intr_req_t          *intr_reqp,
5390         usb_flags_t             flags)
5391 {
5392         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5393         int                     pipe_dir;
5394         size_t                  td_count = 1;
5395         size_t                  tw_length;
5396         ohci_trans_wrapper_t    *tw;
5397 
5398         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5399             "ohci_allocate_intr_resources:");
5400 
5401         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5402 
5403         pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5404 
5405         /* Get the length of interrupt transfer & alloc data */
5406         if (intr_reqp) {
5407                 tw_length = intr_reqp->intr_len;
5408         } else {
5409                 ASSERT(pipe_dir == USB_EP_DIR_IN);
5410                 tw_length = (pp->pp_client_periodic_in_reqp) ?
5411                     (((usb_intr_req_t *)pp->
5412                     pp_client_periodic_in_reqp)->intr_len) :
5413                     ph->p_ep.wMaxPacketSize;
5414         }
5415 
5416         /* Check the size of interrupt request */
5417         if (tw_length > OHCI_MAX_TD_XFER_SIZE) {
5418 
5419                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5420                     "ohci_allocate_intr_resources: Intr request size 0x%lx is "
5421                     "more than 0x%x", tw_length, OHCI_MAX_TD_XFER_SIZE);
5422 
5423                 return (NULL);
5424         }
5425 
5426         if ((tw = ohci_allocate_tw_resources(ohcip, pp, tw_length,
5427             flags, td_count)) == NULL) {
5428 
5429                 return (NULL);
5430         }
5431 
5432         if (pipe_dir == USB_EP_DIR_IN) {
5433                 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) !=
5434                     USB_SUCCESS) {
5435 
5436                         ohci_deallocate_tw_resources(ohcip, pp, tw);
5437                         return (NULL);
5438                 }
5439                 tw->tw_direction = HC_TD_IN;
5440         } else {
5441                 if (tw_length) {
5442                         ASSERT(intr_reqp->intr_data != NULL);
5443 
5444                         /* Copy the data into the message */
5445                         ddi_rep_put8(tw->tw_accesshandle,
5446                             intr_reqp->intr_data->b_rptr, (uint8_t *)tw->tw_buf,
5447                             intr_reqp->intr_len, DDI_DEV_AUTOINCR);
5448                 }
5449 
5450                 tw->tw_curr_xfer_reqp = (usb_opaque_t)intr_reqp;
5451                 tw->tw_direction = HC_TD_OUT;
5452         }
5453 
5454         if (intr_reqp) {
5455                 tw->tw_timeout = intr_reqp->intr_timeout;
5456         }
5457 
5458         /*
5459          * Initialize the callback and any callback
5460          * data required when the td completes.
5461          */
5462         tw->tw_handle_td = ohci_handle_intr_td;
5463         tw->tw_handle_callback_value = NULL;
5464 
5465         return (tw);
5466 }
5467 
5468 /*
5469  * ohci_insert_intr_req:
5470  *
5471  * Insert an Interrupt request into the Host Controller's periodic list.
5472  */
5473 /* ARGSUSED */
5474 static void
5475 ohci_insert_intr_req(
5476         ohci_state_t            *ohcip,
5477         ohci_pipe_private_t     *pp,
5478         ohci_trans_wrapper_t    *tw,
5479         usb_flags_t             flags)
5480 {
5481         usb_intr_req_t          *curr_intr_reqp = NULL;
5482         uint_t                  ctrl = 0;
5483 
5484         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5485 
5486         ASSERT(tw->tw_curr_xfer_reqp != NULL);
5487 
5488         /* Get the current interrupt request pointer */
5489         curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
5490 
5491         ctrl = tw->tw_direction | HC_TD_DT_0 | HC_TD_1I;
5492 
5493         if (curr_intr_reqp->intr_attributes & USB_ATTRS_SHORT_XFER_OK) {
5494                 ctrl |= HC_TD_R;
5495         }
5496 
5497         /* Insert another interrupt TD */
5498         (void) ohci_insert_hc_td(ohcip, ctrl, 0, tw->tw_length, 0, pp, tw);
5499 
5500         /* Start the timer for this Interrupt transfer */
5501         ohci_start_xfer_timer(ohcip, pp, tw);
5502 }
5503 
5504 
5505 /*
5506  * ohci_stop_periodic_pipe_polling:
5507  */
5508 /* ARGSUSED */
5509 static int
5510 ohci_stop_periodic_pipe_polling(
5511         ohci_state_t            *ohcip,
5512         usba_pipe_handle_data_t *ph,
5513         usb_flags_t             flags)
5514 {
5515         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5516         usb_ep_descr_t          *eptd = &ph->p_ep;
5517 
5518         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5519             "ohci_stop_periodic_pipe_polling: Flags = 0x%x", flags);
5520 
5521         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5522 
5523         /*
5524          * Check and handle stop polling on root hub interrupt pipe.
5525          */
5526         if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) &&
5527             ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
5528             USB_EP_ATTR_INTR)) {
5529 
5530                 ohci_handle_root_hub_pipe_stop_intr_polling(
5531                     ph, flags);
5532                 return (USB_SUCCESS);
5533         }
5534 
5535         if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
5536 
5537                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5538                     "ohci_stop_periodic_pipe_polling: Polling already stopped");
5539 
5540                 return (USB_SUCCESS);
5541         }
5542 
5543         /* Set pipe state to pipe stop polling */
5544         pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
5545 
5546         ohci_pipe_cleanup(ohcip, ph);
5547 
5548         return (USB_SUCCESS);
5549 }
5550 
5551 /*
5552  * ohci_allocate_isoc_resources:
5553  *
5554  * Calculates the number of tds necessary for a intr transfer, and allocates
5555  * all the necessary resources.
5556  *
5557  * Returns NULL if there is insufficient resources otherwise TW.
5558  */
5559 static ohci_trans_wrapper_t *
5560 ohci_allocate_isoc_resources(
5561         ohci_state_t            *ohcip,
5562         usba_pipe_handle_data_t *ph,
5563         usb_isoc_req_t          *isoc_reqp,
5564         usb_flags_t             flags)
5565 {
5566         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5567         int                     pipe_dir;
5568         uint_t                  max_pkt_size = ph->p_ep.wMaxPacketSize;
5569         uint_t                  max_isoc_xfer_size;
5570         usb_isoc_pkt_descr_t    *isoc_pkt_descr, *start_isoc_pkt_descr;
5571         ushort_t                isoc_pkt_count;
5572         size_t                  count, td_count;
5573         size_t                  tw_length;
5574         size_t                  isoc_pkts_length;
5575         ohci_trans_wrapper_t    *tw;
5576 
5577 
5578         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5579             "ohci_allocate_isoc_resources: flags = ox%x", flags);
5580 
5581         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5582 
5583         /*
5584          *  Check whether pipe is in halted state.
5585          */
5586         if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
5587                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5588                     "ohci_allocate_isoc_resources:"
5589                     "Pipe is in error state, need pipe reset to continue");
5590 
5591                 return (NULL);
5592         }
5593 
5594         pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5595 
5596         /* Calculate the maximum isochronous transfer size */
5597         max_isoc_xfer_size = OHCI_MAX_ISOC_PKTS_PER_XFER * max_pkt_size;
5598 
5599         if (isoc_reqp) {
5600                 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr;
5601                 isoc_pkt_count = isoc_reqp->isoc_pkts_count;
5602                 isoc_pkts_length = isoc_reqp->isoc_pkts_length;
5603         } else {
5604                 isoc_pkt_descr = ((usb_isoc_req_t *)
5605                     pp->pp_client_periodic_in_reqp)->isoc_pkt_descr;
5606 
5607                 isoc_pkt_count = ((usb_isoc_req_t *)
5608                     pp->pp_client_periodic_in_reqp)->isoc_pkts_count;
5609 
5610                 isoc_pkts_length = ((usb_isoc_req_t *)
5611                     pp->pp_client_periodic_in_reqp)->isoc_pkts_length;
5612         }
5613 
5614         start_isoc_pkt_descr = isoc_pkt_descr;
5615 
5616         /*
5617          * For isochronous IN pipe, get value of number of isochronous
5618          * packets per usb isochronous request
5619          */
5620         if (pipe_dir == USB_EP_DIR_IN) {
5621                 for (count = 0, tw_length = 0;
5622                     count < isoc_pkt_count; count++) {
5623                         tw_length += isoc_pkt_descr->isoc_pkt_length;
5624                         isoc_pkt_descr++;
5625                 }
5626 
5627                 if ((isoc_pkts_length) && (isoc_pkts_length != tw_length)) {
5628 
5629                         USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5630                             "ohci_allocate_isoc_resources: "
5631                             "isoc_pkts_length 0x%lx is not equal to the sum of "
5632                             "all pkt lengths 0x%lx in an isoc request",
5633                             isoc_pkts_length, tw_length);
5634 
5635                         return (NULL);
5636                 }
5637 
5638         } else {
5639                 ASSERT(isoc_reqp != NULL);
5640                 tw_length = MBLKL(isoc_reqp->isoc_data);
5641         }
5642 
5643         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5644             "ohci_allocate_isoc_resources: length = 0x%lx", tw_length);
5645 
5646         /* Check the size of isochronous request */
5647         if (tw_length > max_isoc_xfer_size) {
5648 
5649                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5650                     "ohci_allocate_isoc_resources: Maximum isoc request"
5651                     "size 0x%x Given isoc request size 0x%lx",
5652                     max_isoc_xfer_size, tw_length);
5653 
5654                 return (NULL);
5655         }
5656 
5657         /*
5658          * Each isochronous TD can hold data upto eight isochronous
5659          * data packets. Calculate the number of isochronous TDs needs
5660          * to be insert to complete current isochronous request.
5661          */
5662         td_count = isoc_pkt_count / OHCI_ISOC_PKTS_PER_TD;
5663 
5664         if (isoc_pkt_count % OHCI_ISOC_PKTS_PER_TD) {
5665                 td_count++;
5666         }
5667 
5668         tw = ohci_create_isoc_transfer_wrapper(ohcip, pp, tw_length,
5669             start_isoc_pkt_descr, isoc_pkt_count, td_count, flags);
5670 
5671         if (tw == NULL) {
5672                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5673                     "ohci_create_isoc_transfer_wrapper: "
5674                     "Unable to allocate TW");
5675 
5676                 return (NULL);
5677         }
5678 
5679         if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) ==
5680             USB_SUCCESS) {
5681                 tw->tw_num_tds = (uint_t)td_count;
5682         } else {
5683                 ohci_deallocate_tw_resources(ohcip, pp, tw);
5684 
5685                 return (NULL);
5686         }
5687 
5688         if (pipe_dir == USB_EP_DIR_IN) {
5689                 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) !=
5690                     USB_SUCCESS) {
5691 
5692                         ohci_deallocate_tw_resources(ohcip, pp, tw);
5693                         return (NULL);
5694                 }
5695                 tw->tw_direction = HC_TD_IN;
5696         } else {
5697                 if (tw->tw_length) {
5698                         uchar_t *p;
5699                         int i;
5700 
5701                         ASSERT(isoc_reqp->isoc_data != NULL);
5702                         p = isoc_reqp->isoc_data->b_rptr;
5703 
5704                         /* Copy the data into the message */
5705                         for (i = 0; i < td_count; i++) {
5706                                 ddi_rep_put8(
5707                                     tw->tw_isoc_bufs[i].mem_handle, p,
5708                                     (uint8_t *)tw->tw_isoc_bufs[i].buf_addr,
5709                                     tw->tw_isoc_bufs[i].length,
5710                                     DDI_DEV_AUTOINCR);
5711                                 p += tw->tw_isoc_bufs[i].length;
5712                         }
5713                 }
5714                 tw->tw_curr_xfer_reqp = (usb_opaque_t)isoc_reqp;
5715                 tw->tw_direction = HC_TD_OUT;
5716         }
5717 
5718         /*
5719          * Initialize the callback and any callback
5720          * data required when the td completes.
5721          */
5722         tw->tw_handle_td = ohci_handle_isoc_td;
5723         tw->tw_handle_callback_value = NULL;
5724 
5725         return (tw);
5726 }
5727 
5728 /*
5729  * ohci_insert_isoc_req:
5730  *
5731  * Insert an isochronous request into the Host Controller's
5732  * isochronous list.  If there is an error is will appropriately
5733  * deallocate the unused resources.
5734  */
5735 static int
5736 ohci_insert_isoc_req(
5737         ohci_state_t            *ohcip,
5738         ohci_pipe_private_t     *pp,
5739         ohci_trans_wrapper_t    *tw,
5740         uint_t                  flags)
5741 {
5742         size_t                  curr_isoc_xfer_offset, curr_isoc_xfer_len;
5743         uint_t                  isoc_pkts, residue, count;
5744         uint_t                  i, ctrl, frame_count;
5745         uint_t                  error = USB_SUCCESS;
5746         usb_isoc_req_t          *curr_isoc_reqp;
5747         usb_isoc_pkt_descr_t    *curr_isoc_pkt_descr;
5748 
5749         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5750             "ohci_insert_isoc_req: flags = 0x%x", flags);
5751 
5752         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5753 
5754         /*
5755          * Get the current isochronous request and packet
5756          * descriptor pointers.
5757          */
5758         curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
5759         curr_isoc_pkt_descr = curr_isoc_reqp->isoc_pkt_descr;
5760 
5761         ASSERT(curr_isoc_reqp != NULL);
5762         ASSERT(curr_isoc_reqp->isoc_pkt_descr != NULL);
5763 
5764         /*
5765          * Save address of first usb isochronous packet descriptor.
5766          */
5767         tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr;
5768 
5769         /* Insert all the isochronous TDs */
5770         for (count = 0, curr_isoc_xfer_offset = 0,
5771             isoc_pkts = 0; count < tw->tw_num_tds; count++) {
5772 
5773                 residue = curr_isoc_reqp->isoc_pkts_count - isoc_pkts;
5774 
5775                 /* Check for inserting residue data */
5776                 if ((count == (tw->tw_num_tds - 1)) &&
5777                     (residue < OHCI_ISOC_PKTS_PER_TD)) {
5778                         frame_count = residue;
5779                 } else {
5780                         frame_count = OHCI_ISOC_PKTS_PER_TD;
5781                 }
5782 
5783                 curr_isoc_pkt_descr = tw->tw_curr_isoc_pktp;
5784 
5785                 /*
5786                  * Calculate length of isochronous transfer
5787                  * for the current TD.
5788                  */
5789                 for (i = 0, curr_isoc_xfer_len = 0;
5790                     i < frame_count; i++, curr_isoc_pkt_descr++) {
5791                         curr_isoc_xfer_len +=
5792                             curr_isoc_pkt_descr->isoc_pkt_length;
5793                 }
5794 
5795                 /*
5796                  * Programm td control field by checking whether this
5797                  * is last td.
5798                  */
5799                 if (count == (tw->tw_num_tds - 1)) {
5800                         ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) &
5801                             HC_ITD_FC) | HC_TD_DT_0 | HC_TD_0I);
5802                 } else {
5803                         ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) &
5804                             HC_ITD_FC) | HC_TD_DT_0 | HC_TD_6I);
5805                 }
5806 
5807                 /* Insert the TD into the endpoint */
5808                 if ((error = ohci_insert_hc_td(ohcip, ctrl, count,
5809                     curr_isoc_xfer_len, 0, pp, tw)) !=
5810                     USB_SUCCESS) {
5811                         tw->tw_num_tds = count;
5812                         tw->tw_length  = curr_isoc_xfer_offset;
5813                         break;
5814                 }
5815 
5816                 isoc_pkts += frame_count;
5817                 tw->tw_curr_isoc_pktp += frame_count;
5818                 curr_isoc_xfer_offset += curr_isoc_xfer_len;
5819         }
5820 
5821         if (error != USB_SUCCESS) {
5822                 /* Free periodic in resources */
5823                 if (tw->tw_direction == USB_EP_DIR_IN) {
5824                         ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
5825                 }
5826 
5827                 /* Free all resources if IN or if count == 0(for both IN/OUT) */
5828                 if (tw->tw_direction == USB_EP_DIR_IN || count == 0) {
5829 
5830                         ohci_deallocate_tw_resources(ohcip, pp, tw);
5831 
5832                         if (pp->pp_cur_periodic_req_cnt) {
5833                                 /*
5834                                  * Set pipe state to stop polling and
5835                                  * error to no resource. Don't insert
5836                                  * any more isochronous polling requests.
5837                                  */
5838                                 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
5839                                 pp->pp_error = error;
5840                         } else {
5841                                 /* Set periodic in pipe state to idle */
5842                                 pp->pp_state = OHCI_PIPE_STATE_IDLE;
5843                         }
5844                 }
5845         } else {
5846 
5847                 /*
5848                  * Reset back to the address of first usb isochronous
5849                  * packet descriptor.
5850                  */
5851                 tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr;
5852 
5853                 /* Reset the CONTINUE flag */
5854                 pp->pp_flag &= ~OHCI_ISOC_XFER_CONTINUE;
5855         }
5856 
5857         return (error);
5858 }
5859 
5860 
5861 /*
5862  * ohci_insert_hc_td:
5863  *
5864  * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
5865  * Always returns USB_SUCCESS, except for ISOCH.
5866  */
5867 static int
5868 ohci_insert_hc_td(
5869         ohci_state_t            *ohcip,
5870         uint_t                  hctd_ctrl,
5871         uint32_t                hctd_dma_offs,
5872         size_t                  hctd_length,
5873         uint32_t                hctd_ctrl_phase,
5874         ohci_pipe_private_t     *pp,
5875         ohci_trans_wrapper_t    *tw)
5876 {
5877         ohci_td_t               *new_dummy;
5878         ohci_td_t               *cpu_current_dummy;
5879         ohci_ed_t               *ept = pp->pp_ept;
5880         int                     error;
5881 
5882         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5883 
5884         /* Retrieve preallocated td from the TW */
5885         new_dummy = tw->tw_hctd_free_list;
5886 
5887         ASSERT(new_dummy != NULL);
5888 
5889         tw->tw_hctd_free_list = ohci_td_iommu_to_cpu(ohcip,
5890             Get_TD(new_dummy->hctd_tw_next_td));
5891         Set_TD(new_dummy->hctd_tw_next_td, NULL);
5892 
5893         /* Fill in the current dummy */
5894         cpu_current_dummy = (ohci_td_t *)
5895             (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp)));
5896 
5897         /*
5898          * Fill in the current dummy td and
5899          * add the new dummy to the end.
5900          */
5901         ohci_fill_in_td(ohcip, cpu_current_dummy, new_dummy,
5902             hctd_ctrl, hctd_dma_offs, hctd_length, hctd_ctrl_phase, pp, tw);
5903 
5904         /*
5905          * If this is an isochronous TD, first write proper
5906          * starting usb frame number in which this TD must
5907          * can be processed. After writing the frame number
5908          * insert this TD into the ED's list.
5909          */
5910         if ((pp->pp_pipe_handle->p_ep.bmAttributes &
5911             USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
5912 
5913                 error = ohci_insert_td_with_frame_number(
5914                     ohcip, pp, tw, cpu_current_dummy, new_dummy);
5915 
5916                 if (error != USB_SUCCESS) {
5917                         /* Reset the current dummy back to a dummy */
5918                         bzero((char *)cpu_current_dummy, sizeof (ohci_td_t));
5919                         Set_TD(cpu_current_dummy->hctd_state, HC_TD_DUMMY);
5920 
5921                         /* return the new dummy back to the free list */
5922                         bzero((char *)new_dummy, sizeof (ohci_td_t));
5923                         Set_TD(new_dummy->hctd_state, HC_TD_DUMMY);
5924                         if (tw->tw_hctd_free_list != NULL) {
5925                                 Set_TD(new_dummy->hctd_tw_next_td,
5926                                     ohci_td_cpu_to_iommu(ohcip,
5927                                     tw->tw_hctd_free_list));
5928                         }
5929                         tw->tw_hctd_free_list = new_dummy;
5930 
5931                         return (error);
5932                 }
5933         } else {
5934                 /*
5935                  * For control, bulk and interrupt TD, just
5936                  * add the new dummy to the ED's list. When
5937                  * this occurs, the Host Controller ill see
5938                  * the newly filled in dummy TD.
5939                  */
5940                 Set_ED(ept->hced_tailp,
5941                     (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
5942         }
5943 
5944         /* Insert this td onto the tw */
5945         ohci_insert_td_on_tw(ohcip, tw, cpu_current_dummy);
5946 
5947         return (USB_SUCCESS);
5948 }
5949 
5950 
5951 /*
5952  * ohci_allocate_td_from_pool:
5953  *
5954  * Allocate a Transfer Descriptor (TD) from the TD buffer pool.
5955  */
5956 static ohci_td_t *
5957 ohci_allocate_td_from_pool(ohci_state_t *ohcip)
5958 {
5959         int                             i, state;
5960         ohci_td_t                       *td;
5961 
5962         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5963 
5964         /*
5965          * Search for a blank Transfer Descriptor (TD)
5966          * in the TD buffer pool.
5967          */
5968         for (i = 0; i < ohci_td_pool_size; i ++) {
5969                 state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state);
5970                 if (state == HC_TD_FREE) {
5971                         break;
5972                 }
5973         }
5974 
5975         if (i >= ohci_td_pool_size) {
5976                 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
5977                     "ohci_allocate_td_from_pool: TD exhausted");
5978 
5979                 return (NULL);
5980         }
5981 
5982         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
5983             "ohci_allocate_td_from_pool: Allocated %d", i);
5984 
5985         /* Create a new dummy for the end of the TD list */
5986         td = &ohcip->ohci_td_pool_addr[i];
5987 
5988         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5989             "ohci_allocate_td_from_pool: td 0x%p", (void *)td);
5990 
5991         /* Mark the newly allocated TD as a dummy */
5992         Set_TD(td->hctd_state, HC_TD_DUMMY);
5993 
5994         return (td);
5995 }
5996 
5997 /*
5998  * ohci_fill_in_td:
5999  *
6000  * Fill in the fields of a Transfer Descriptor (TD).
6001  *
6002  * hctd_dma_offs - different meanings for non-isoc and isoc TDs:
6003  *          starting offset into the TW buffer for a non-isoc TD
6004  *          and the index into the isoc TD list for an isoc TD.
6005  *          For non-isoc TDs, the starting offset should be 4k
6006  *          aligned and the TDs in one transfer must be filled in
6007  *          increasing order.
6008  */
6009 static void
6010 ohci_fill_in_td(
6011         ohci_state_t            *ohcip,
6012         ohci_td_t               *td,
6013         ohci_td_t               *new_dummy,
6014         uint_t                  hctd_ctrl,
6015         uint32_t                hctd_dma_offs,
6016         size_t                  hctd_length,
6017         uint32_t                hctd_ctrl_phase,
6018         ohci_pipe_private_t     *pp,
6019         ohci_trans_wrapper_t    *tw)
6020 {
6021         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6022             "ohci_fill_in_td: td 0x%p bufoffs 0x%x len 0x%lx",
6023             (void *)td, hctd_dma_offs, hctd_length);
6024 
6025         /* Assert that the td to be filled in is a dummy */
6026         ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY);
6027 
6028         /* Change TD's state Active */
6029         Set_TD(td->hctd_state, HC_TD_ACTIVE);
6030 
6031         /* Update the TD special fields */
6032         if ((pp->pp_pipe_handle->p_ep.bmAttributes &
6033             USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
6034                 ohci_init_itd(ohcip, tw, hctd_ctrl, hctd_dma_offs, td);
6035         } else {
6036                 /* Update the dummy with control information */
6037                 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA));
6038 
6039                 ohci_init_td(ohcip, tw, hctd_dma_offs, hctd_length, td);
6040         }
6041 
6042         /* The current dummy now points to the new dummy */
6043         Set_TD(td->hctd_next_td, (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
6044 
6045         /*
6046          * For Control transfer, hctd_ctrl_phase is a valid field.
6047          */
6048         if (hctd_ctrl_phase) {
6049                 Set_TD(td->hctd_ctrl_phase, hctd_ctrl_phase);
6050         }
6051 
6052         /* Print the td */
6053         ohci_print_td(ohcip, td);
6054 
6055         /* Fill in the wrapper portion of the TD */
6056 
6057         /* Set the transfer wrapper */
6058         ASSERT(tw != NULL);
6059         ASSERT(tw->tw_id != NULL);
6060 
6061         Set_TD(td->hctd_trans_wrapper, (uint32_t)tw->tw_id);
6062         Set_TD(td->hctd_tw_next_td, NULL);
6063 }
6064 
6065 
6066 /*
6067  * ohci_init_td:
6068  *
6069  * Initialize the buffer address portion of non-isoc Transfer
6070  * Descriptor (TD).
6071  */
6072 void
6073 ohci_init_td(
6074         ohci_state_t            *ohcip,
6075         ohci_trans_wrapper_t    *tw,
6076         uint32_t                hctd_dma_offs,
6077         size_t                  hctd_length,
6078         ohci_td_t               *td)
6079 {
6080         uint32_t        page_addr, start_addr = 0, end_addr = 0;
6081         size_t          buf_len = hctd_length;
6082         int             rem_len, i;
6083 
6084         /*
6085          * TDs must be filled in increasing DMA offset order.
6086          * tw_dma_offs is initialized to be 0 at TW creation and
6087          * is only increased in this function.
6088          */
6089         ASSERT(buf_len == 0 || hctd_dma_offs >= tw->tw_dma_offs);
6090 
6091         Set_TD(td->hctd_xfer_offs, hctd_dma_offs);
6092         Set_TD(td->hctd_xfer_len, buf_len);
6093 
6094         /* Computing the starting buffer address and end buffer address */
6095         for (i = 0; (i < 2) && (buf_len > 0); i++) {
6096                 /* Advance to the next DMA cookie if necessary */
6097                 if ((tw->tw_dma_offs + tw->tw_cookie.dmac_size) <=
6098                     hctd_dma_offs) {
6099                         /*
6100                          * tw_dma_offs always points to the starting offset
6101                          * of a cookie
6102                          */
6103                         tw->tw_dma_offs += tw->tw_cookie.dmac_size;
6104                         ddi_dma_nextcookie(tw->tw_dmahandle, &tw->tw_cookie);
6105                         tw->tw_cookie_idx++;
6106                         ASSERT(tw->tw_cookie_idx < tw->tw_ncookies);
6107                 }
6108 
6109                 ASSERT((tw->tw_dma_offs + tw->tw_cookie.dmac_size) >
6110                     hctd_dma_offs);
6111 
6112                 /*
6113                  * Counting the remained buffer length to be filled in
6114                  * the TD for current DMA cookie
6115                  */
6116                 rem_len = (tw->tw_dma_offs + tw->tw_cookie.dmac_size) -
6117                     hctd_dma_offs;
6118 
6119                 /* Get the beginning address of the buffer */
6120                 page_addr = (hctd_dma_offs - tw->tw_dma_offs) +
6121                     tw->tw_cookie.dmac_address;
6122                 ASSERT((page_addr % OHCI_4K_ALIGN) == 0);
6123 
6124                 if (i == 0) {
6125                         start_addr = page_addr;
6126                 }
6127 
6128                 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6129                     "ohci_init_td: page_addr 0x%x dmac_size "
6130                     "0x%lx idx %d", page_addr, tw->tw_cookie.dmac_size,
6131                     tw->tw_cookie_idx);
6132 
6133                 if (buf_len <= OHCI_MAX_TD_BUF_SIZE) {
6134                         ASSERT(buf_len <= rem_len);
6135                         end_addr = page_addr + buf_len - 1;
6136                         buf_len = 0;
6137                         break;
6138                 } else {
6139                         ASSERT(rem_len >= OHCI_MAX_TD_BUF_SIZE);
6140                         buf_len -= OHCI_MAX_TD_BUF_SIZE;
6141                         hctd_dma_offs += OHCI_MAX_TD_BUF_SIZE;
6142                 }
6143         }
6144 
6145         ASSERT(buf_len == 0);
6146 
6147         Set_TD(td->hctd_cbp, start_addr);
6148         Set_TD(td->hctd_buf_end, end_addr);
6149 }
6150 
6151 
6152 /*
6153  * ohci_init_itd:
6154  *
6155  * Initialize the buffer address portion of isoc Transfer Descriptor (TD).
6156  */
6157 static void
6158 ohci_init_itd(
6159         ohci_state_t            *ohcip,
6160         ohci_trans_wrapper_t    *tw,
6161         uint_t                  hctd_ctrl,
6162         uint32_t                index,
6163         ohci_td_t               *td)
6164 {
6165         uint32_t                start_addr, end_addr, offset, offset_addr;
6166         ohci_isoc_buf_t         *bufp;
6167         size_t                  buf_len;
6168         uint_t                  buf, fc, toggle, flag;
6169         usb_isoc_pkt_descr_t    *temp_pkt_descr;
6170         int                     i;
6171 
6172         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6173 
6174         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6175             "ohci_init_itd: ctrl = 0x%x", hctd_ctrl);
6176 
6177         /*
6178          * Write control information except starting
6179          * usb frame number.
6180          */
6181         Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA));
6182 
6183         bufp = &tw->tw_isoc_bufs[index];
6184         Set_TD(td->hctd_xfer_offs, index);
6185         Set_TD(td->hctd_xfer_len, bufp->length);
6186 
6187         start_addr = bufp->cookie.dmac_address;
6188         ASSERT((start_addr % OHCI_4K_ALIGN) == 0);
6189 
6190         buf_len = bufp->length;
6191         if (bufp->ncookies == OHCI_DMA_ATTR_TD_SGLLEN) {
6192                 buf_len = bufp->length - bufp->cookie.dmac_size;
6193                 ddi_dma_nextcookie(bufp->dma_handle, &bufp->cookie);
6194         }
6195         end_addr = bufp->cookie.dmac_address + buf_len - 1;
6196 
6197         /*
6198          * For an isochronous transfer, the hctd_cbp contains,
6199          * the 4k page, and not the actual start of the buffer.
6200          */
6201         Set_TD(td->hctd_cbp, ((uint32_t)start_addr & HC_ITD_PAGE_MASK));
6202         Set_TD(td->hctd_buf_end, end_addr);
6203 
6204         fc = (hctd_ctrl & HC_ITD_FC) >> HC_ITD_FC_SHIFT;
6205         toggle = 0;
6206         buf = start_addr;
6207 
6208         /*
6209          * Get the address of first isochronous data packet
6210          * for the current isochronous TD.
6211          */
6212         temp_pkt_descr =  tw->tw_curr_isoc_pktp;
6213 
6214         /* The offsets are actually offsets into the page */
6215         for (i = 0; i <= fc; i++) {
6216                 offset_addr = (uint32_t)((buf &
6217                     HC_ITD_OFFSET_ADDR) | (HC_ITD_OFFSET_CC));
6218 
6219                 flag =  ((start_addr &
6220                     HC_ITD_PAGE_MASK) ^ (buf & HC_ITD_PAGE_MASK));
6221 
6222                 if (flag) {
6223                         offset_addr |= HC_ITD_4KBOUNDARY_CROSS;
6224                 }
6225 
6226                 if (toggle) {
6227                         offset = (uint32_t)((offset_addr <<
6228                             HC_ITD_OFFSET_SHIFT) & HC_ITD_ODD_OFFSET);
6229 
6230                         Set_TD(td->hctd_offsets[i / 2],
6231                             Get_TD(td->hctd_offsets[i / 2]) | offset);
6232                         toggle = 0;
6233                 } else {
6234                         offset = (uint32_t)(offset_addr & HC_ITD_EVEN_OFFSET);
6235 
6236                         Set_TD(td->hctd_offsets[i / 2],
6237                             Get_TD(td->hctd_offsets[i / 2]) | offset);
6238                         toggle = 1;
6239                 }
6240 
6241                 buf = (uint32_t)(buf + temp_pkt_descr->isoc_pkt_length);
6242                 temp_pkt_descr++;
6243         }
6244 }
6245 
6246 
6247 /*
6248  * ohci_insert_td_with_frame_number:
6249  *
6250  * Insert current isochronous TD into the ED's list. with proper
6251  * usb frame number in which this TD can be processed.
6252  */
6253 static int
6254 ohci_insert_td_with_frame_number(
6255         ohci_state_t            *ohcip,
6256         ohci_pipe_private_t     *pp,
6257         ohci_trans_wrapper_t    *tw,
6258         ohci_td_t               *current_td,
6259         ohci_td_t               *dummy_td)
6260 {
6261         usb_isoc_req_t          *isoc_reqp =
6262             (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
6263         usb_frame_number_t      current_frame_number, start_frame_number;
6264         uint_t                  ddic, ctrl, isoc_pkts;
6265         ohci_ed_t               *ept = pp->pp_ept;
6266 
6267         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6268             "ohci_insert_td_with_frame_number:"
6269             "isoc flags 0x%x", isoc_reqp->isoc_attributes);
6270 
6271         /* Get the TD ctrl information */
6272         isoc_pkts = ((Get_TD(current_td->hctd_ctrl) &
6273             HC_ITD_FC) >> HC_ITD_FC_SHIFT) + 1;
6274 
6275         /*
6276          * Enter critical, while programming the usb frame number
6277          * and inserting current isochronous TD into the ED's list.
6278          */
6279         ddic = ddi_enter_critical();
6280 
6281         /* Get the current frame number */
6282         current_frame_number = ohci_get_current_frame_number(ohcip);
6283 
6284         /* Check the given isochronous flags */
6285         switch (isoc_reqp->isoc_attributes &
6286             (USB_ATTRS_ISOC_START_FRAME | USB_ATTRS_ISOC_XFER_ASAP)) {
6287         case USB_ATTRS_ISOC_START_FRAME:
6288                 /* Starting frame number is specified */
6289                 if (pp->pp_flag & OHCI_ISOC_XFER_CONTINUE) {
6290                         /* Get the starting usb frame number */
6291                         start_frame_number = pp->pp_next_frame_number;
6292                 } else {
6293                         /* Check for the Starting usb frame number */
6294                         if ((isoc_reqp->isoc_frame_no == 0) ||
6295                             ((isoc_reqp->isoc_frame_no +
6296                             isoc_reqp->isoc_pkts_count) <
6297                             current_frame_number)) {
6298 
6299                                 /* Exit the critical */
6300                                 ddi_exit_critical(ddic);
6301 
6302                                 USB_DPRINTF_L2(PRINT_MASK_LISTS,
6303                                     ohcip->ohci_log_hdl,
6304                                     "ohci_insert_td_with_frame_number:"
6305                                     "Invalid starting frame number");
6306 
6307                                 return (USB_INVALID_START_FRAME);
6308                         }
6309 
6310                         /* Get the starting usb frame number */
6311                         start_frame_number = isoc_reqp->isoc_frame_no;
6312 
6313                         pp->pp_next_frame_number = 0;
6314                 }
6315                 break;
6316         case USB_ATTRS_ISOC_XFER_ASAP:
6317                 /* ohci has to specify starting frame number */
6318                 if ((pp->pp_next_frame_number) &&
6319                     (pp->pp_next_frame_number > current_frame_number)) {
6320                         /*
6321                          * Get the next usb frame number.
6322                          */
6323                         start_frame_number = pp->pp_next_frame_number;
6324                 } else {
6325                         /*
6326                          * Add appropriate offset to the current usb
6327                          * frame number and use it as a starting frame
6328                          * number.
6329                          */
6330                         start_frame_number =
6331                             current_frame_number + OHCI_FRAME_OFFSET;
6332                 }
6333 
6334                 if (!(pp->pp_flag & OHCI_ISOC_XFER_CONTINUE)) {
6335                         isoc_reqp->isoc_frame_no = start_frame_number;
6336                 }
6337                 break;
6338         default:
6339                 /* Exit the critical */
6340                 ddi_exit_critical(ddic);
6341 
6342                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6343                     "ohci_insert_td_with_frame_number: Either starting "
6344                     "frame number or ASAP flags are not set, attrs = 0x%x",
6345                     isoc_reqp->isoc_attributes);
6346 
6347                 return (USB_NO_FRAME_NUMBER);
6348         }
6349 
6350         /* Get the TD ctrl information */
6351         ctrl = Get_TD(current_td->hctd_ctrl) & (~(HC_ITD_SF));
6352 
6353         /* Set the frame number field */
6354         Set_TD(current_td->hctd_ctrl, ctrl | (start_frame_number & HC_ITD_SF));
6355 
6356         /*
6357          * Add the new dummy to the ED's list. When this occurs,
6358          * the Host Controller will see newly filled in dummy TD.
6359          */
6360         Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy_td)));
6361 
6362         /* Exit the critical */
6363         ddi_exit_critical(ddic);
6364 
6365         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6366             "ohci_insert_td_with_frame_number:"
6367             "current frame number 0x%llx start frame number 0x%llx",
6368             (unsigned long long)current_frame_number,
6369             (unsigned long long)start_frame_number);
6370 
6371         /*
6372          * Increment this saved frame number by current number
6373          * of data packets needs to be transfer.
6374          */
6375         pp->pp_next_frame_number = start_frame_number + isoc_pkts;
6376 
6377         /*
6378          * Set OHCI_ISOC_XFER_CONTINUE flag in order to send other
6379          * isochronous packets,  part of the current isoch request
6380          * in the subsequent frames.
6381          */
6382         pp->pp_flag |= OHCI_ISOC_XFER_CONTINUE;
6383 
6384         return (USB_SUCCESS);
6385 }
6386 
6387 
6388 /*
6389  * ohci_insert_td_on_tw:
6390  *
6391  * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that
6392  * are allocated for this transfer. Insert a TD  onto this list. The  list
6393  * of TD's does not include the dummy TD that is at the end of the list of
6394  * TD's for the endpoint.
6395  */
6396 static void
6397 ohci_insert_td_on_tw(
6398         ohci_state_t            *ohcip,
6399         ohci_trans_wrapper_t    *tw,
6400         ohci_td_t               *td)
6401 {
6402         /*
6403          * Set the next pointer to NULL because
6404          * this is the last TD on list.
6405          */
6406         Set_TD(td->hctd_tw_next_td, NULL);
6407 
6408         if (tw->tw_hctd_head == NULL) {
6409                 ASSERT(tw->tw_hctd_tail == NULL);
6410                 tw->tw_hctd_head = td;
6411                 tw->tw_hctd_tail = td;
6412         } else {
6413                 ohci_td_t *dummy = (ohci_td_t *)tw->tw_hctd_tail;
6414 
6415                 ASSERT(dummy != NULL);
6416                 ASSERT(dummy != td);
6417                 ASSERT(Get_TD(td->hctd_state) != HC_TD_DUMMY);
6418 
6419                 /* Add the td to the end of the list */
6420                 Set_TD(dummy->hctd_tw_next_td,
6421                     ohci_td_cpu_to_iommu(ohcip, td));
6422 
6423                 tw->tw_hctd_tail = td;
6424 
6425                 ASSERT(Get_TD(td->hctd_tw_next_td) == NULL);
6426         }
6427 }
6428 
6429 
6430 /*
6431  * ohci_traverse_tds:
6432  * NOTE: This function is also called from POLLED MODE.
6433  *
6434  * Traverse the list of TD's for an endpoint.  Since the endpoint is marked
6435  * as sKipped,  the Host Controller (HC) is no longer accessing these TD's.
6436  * Remove all the TD's that are attached to the endpoint.
6437  */
6438 void
6439 ohci_traverse_tds(
6440         ohci_state_t            *ohcip,
6441         usba_pipe_handle_data_t *ph)
6442 {
6443         ohci_trans_wrapper_t    *tw;
6444         ohci_ed_t               *ept;
6445         ohci_pipe_private_t     *pp;
6446         uint32_t                addr;
6447         ohci_td_t               *tailp, *headp, *next;
6448 
6449         pp = (ohci_pipe_private_t *)ph->p_hcd_private;
6450         ept = pp->pp_ept;
6451 
6452         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6453             "ohci_traverse_tds: ph = 0x%p ept = 0x%p",
6454             (void *)ph, (void *)ept);
6455 
6456         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6457 
6458         addr = Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD;
6459 
6460         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6461             "ohci_traverse_tds: addr (head) = 0x%x", addr);
6462 
6463         headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr));
6464 
6465         addr = Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL;
6466 
6467         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6468             "ohci_traverse_tds: addr (tail) = 0x%x", addr);
6469 
6470         tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr));
6471 
6472         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6473             "ohci_traverse_tds: cpu head = 0x%p cpu tail = 0x%p",
6474             (void *)headp, (void *)tailp);
6475 
6476         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6477             "ohci_traverse_tds: iommu head = 0x%x iommu tail = 0x%x",
6478             ohci_td_cpu_to_iommu(ohcip, headp),
6479             ohci_td_cpu_to_iommu(ohcip, tailp));
6480 
6481         /*
6482          * Traverse the list of TD's that are currently on the endpoint.
6483          * These TD's have not been processed and will not be processed
6484          * because the endpoint processing is stopped.
6485          */
6486         while (headp != tailp) {
6487                 next = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
6488                     (Get_TD(headp->hctd_next_td) & HC_EPT_TD_TAIL)));
6489 
6490                 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
6491                     (uint32_t)Get_TD(headp->hctd_trans_wrapper));
6492 
6493                 /* Stop the the transfer timer */
6494                 ohci_stop_xfer_timer(ohcip, tw, OHCI_REMOVE_XFER_ALWAYS);
6495 
6496                 ohci_deallocate_td(ohcip, headp);
6497                 headp = next;
6498         }
6499 
6500         /* Both head and tail pointers must be same */
6501         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6502             "ohci_traverse_tds: head = 0x%p tail = 0x%p",
6503             (void *)headp, (void *)tailp);
6504 
6505         /* Update the pointer in the endpoint descriptor */
6506         Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, headp)));
6507 
6508         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6509             "ohci_traverse_tds: new head = 0x%x",
6510             (ohci_td_cpu_to_iommu(ohcip, headp)));
6511 
6512         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6513             "ohci_traverse_tds: tailp = 0x%x headp = 0x%x",
6514             (Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL),
6515             (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
6516 
6517         ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) ==
6518             (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
6519 }
6520 
6521 
6522 /*
6523  * ohci_done_list_tds:
6524  *
6525  * There may be TD's on the done list that have not been processed yet. Walk
6526  * through these TD's and mark them as RECLAIM. All the mappings for the  TD
6527  * will be torn down, so the interrupt handle is alerted of this fact through
6528  * the RECLAIM flag.
6529  */
6530 static void
6531 ohci_done_list_tds(
6532         ohci_state_t            *ohcip,
6533         usba_pipe_handle_data_t *ph)
6534 {
6535         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
6536         ohci_trans_wrapper_t    *head_tw = pp->pp_tw_head;
6537         ohci_trans_wrapper_t    *next_tw;
6538         ohci_td_t               *head_td, *next_td;
6539 
6540         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6541 
6542         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6543             "ohci_done_list_tds:");
6544 
6545         /* Process the transfer wrappers for this pipe */
6546         next_tw = head_tw;
6547         while (next_tw) {
6548                 head_td = (ohci_td_t *)next_tw->tw_hctd_head;
6549                 next_td = head_td;
6550 
6551                 if (head_td) {
6552                         /*
6553                          * Walk through each TD for this transfer
6554                          * wrapper. If a TD still exists, then it
6555                          * is currently on the done list.
6556                          */
6557                         while (next_td) {
6558 
6559                                 /* To free TD, set TD state to RECLAIM */
6560                                 Set_TD(next_td->hctd_state, HC_TD_RECLAIM);
6561 
6562                                 Set_TD(next_td->hctd_trans_wrapper, NULL);
6563 
6564                                 next_td = ohci_td_iommu_to_cpu(ohcip,
6565                                     Get_TD(next_td->hctd_tw_next_td));
6566                         }
6567                 }
6568 
6569                 /* Stop the the transfer timer */
6570                 ohci_stop_xfer_timer(ohcip, next_tw, OHCI_REMOVE_XFER_ALWAYS);
6571 
6572                 next_tw = next_tw->tw_next;
6573         }
6574 }
6575 
6576 
6577 /*
6578  * Remove old_td from tw and update the links.
6579  */
6580 void
6581 ohci_unlink_td_from_tw(
6582         ohci_state_t            *ohcip,
6583         ohci_td_t               *old_td,
6584         ohci_trans_wrapper_t    *tw)
6585 {
6586         ohci_td_t *next, *head, *tail;
6587 
6588         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6589             "ohci_unlink_td_from_tw: ohcip = 0x%p, old_td = 0x%p, tw = 0x%p",
6590             (void *)ohcip, (void *)old_td, (void *)tw);
6591 
6592         if (old_td == NULL || tw == NULL) {
6593 
6594                 return;
6595         }
6596 
6597         head = tw->tw_hctd_head;
6598         tail = tw->tw_hctd_tail;
6599 
6600         if (head == NULL) {
6601 
6602                 return;
6603         }
6604 
6605         /* if this old_td is on head */
6606         if (old_td == head) {
6607                 if (old_td == tail) {
6608                         tw->tw_hctd_head = NULL;
6609                         tw->tw_hctd_tail = NULL;
6610                 } else {
6611                         tw->tw_hctd_head = ohci_td_iommu_to_cpu(ohcip,
6612                             Get_TD(head->hctd_tw_next_td));
6613                 }
6614 
6615                 return;
6616         }
6617 
6618         /* find this old_td's position in the tw */
6619         next = ohci_td_iommu_to_cpu(ohcip, Get_TD(head->hctd_tw_next_td));
6620         while (next && (old_td != next)) {
6621                 head = next;
6622                 next = ohci_td_iommu_to_cpu(ohcip,
6623                     Get_TD(next->hctd_tw_next_td));
6624         }
6625 
6626         /* unlink the found old_td from the tw */
6627         if (old_td == next) {
6628                 Set_TD(head->hctd_tw_next_td, Get_TD(next->hctd_tw_next_td));
6629                 if (old_td == tail) {
6630                         tw->tw_hctd_tail = head;
6631                 }
6632         }
6633 }
6634 
6635 
6636 /*
6637  * ohci_deallocate_td:
6638  * NOTE: This function is also called from POLLED MODE.
6639  *
6640  * Deallocate a Host Controller's (HC) Transfer Descriptor (TD).
6641  */
6642 void
6643 ohci_deallocate_td(
6644         ohci_state_t    *ohcip,
6645         ohci_td_t       *old_td)
6646 {
6647         ohci_trans_wrapper_t    *tw;
6648 
6649         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6650             "ohci_deallocate_td: old_td = 0x%p", (void *)old_td);
6651 
6652         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6653 
6654         /*
6655          * Obtain the transaction wrapper and tw will be
6656          * NULL for the dummy and for the reclaim TD's.
6657          */
6658         if ((Get_TD(old_td->hctd_state) == HC_TD_DUMMY) ||
6659             (Get_TD(old_td->hctd_state) == HC_TD_RECLAIM)) {
6660                 tw = (ohci_trans_wrapper_t *)((uintptr_t)
6661                     Get_TD(old_td->hctd_trans_wrapper));
6662                 ASSERT(tw == NULL);
6663         } else {
6664                 tw = (ohci_trans_wrapper_t *)
6665                     OHCI_LOOKUP_ID((uint32_t)
6666                     Get_TD(old_td->hctd_trans_wrapper));
6667                 ASSERT(tw != NULL);
6668         }
6669 
6670         /*
6671          * If this TD should be reclaimed, don't try to access its
6672          * transfer wrapper.
6673          */
6674         if ((Get_TD(old_td->hctd_state) != HC_TD_RECLAIM) && tw) {
6675 
6676                 ohci_unlink_td_from_tw(ohcip, old_td, tw);
6677         }
6678 
6679         bzero((void *)old_td, sizeof (ohci_td_t));
6680         Set_TD(old_td->hctd_state, HC_TD_FREE);
6681 
6682         USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6683             "ohci_deallocate_td: td 0x%p", (void *)old_td);
6684 }
6685 
6686 
6687 /*
6688  * ohci_td_cpu_to_iommu:
6689  * NOTE: This function is also called from POLLED MODE.
6690  *
6691  * This function converts for the given Transfer Descriptor (TD) CPU address
6692  * to IO address.
6693  */
6694 uint32_t
6695 ohci_td_cpu_to_iommu(
6696         ohci_state_t    *ohcip,
6697         ohci_td_t       *addr)
6698 {
6699         uint32_t        td;
6700 
6701         td  = (uint32_t)ohcip->ohci_td_pool_cookie.dmac_address +
6702             (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_td_pool_addr));
6703 
6704         ASSERT((ohcip->ohci_td_pool_cookie.dmac_address +
6705             (uint32_t) (sizeof (ohci_td_t) *
6706             (addr - ohcip->ohci_td_pool_addr))) ==
6707             (ohcip->ohci_td_pool_cookie.dmac_address +
6708             (uint32_t)((uintptr_t)addr - (uintptr_t)
6709             (ohcip->ohci_td_pool_addr))));
6710 
6711         ASSERT(td >= ohcip->ohci_td_pool_cookie.dmac_address);
6712         ASSERT(td <= ohcip->ohci_td_pool_cookie.dmac_address +
6713             sizeof (ohci_td_t) * ohci_td_pool_size);
6714 
6715         return (td);
6716 }
6717 
6718 
6719 /*
6720  * ohci_td_iommu_to_cpu:
6721  * NOTE: This function is also called from POLLED MODE.
6722  *
6723  * This function converts for the given Transfer Descriptor (TD) IO address
6724  * to CPU address.
6725  */
6726 ohci_td_t *
6727 ohci_td_iommu_to_cpu(
6728         ohci_state_t    *ohcip,
6729         uintptr_t       addr)
6730 {
6731         ohci_td_t       *td;
6732 
6733         if (addr == NULL) {
6734 
6735                 return (NULL);
6736         }
6737 
6738         td = (ohci_td_t *)((uintptr_t)
6739             (addr - ohcip->ohci_td_pool_cookie.dmac_address) +
6740             (uintptr_t)ohcip->ohci_td_pool_addr);
6741 
6742         ASSERT(td >= ohcip->ohci_td_pool_addr);
6743         ASSERT((uintptr_t)td <= (uintptr_t)ohcip->ohci_td_pool_addr +
6744             (uintptr_t)(sizeof (ohci_td_t) * ohci_td_pool_size));
6745 
6746         return (td);
6747 }
6748 
6749 /*
6750  * ohci_allocate_tds_for_tw:
6751  *
6752  * Allocate n Transfer Descriptors (TD) from the TD buffer pool and places it
6753  * into the TW.
6754  *
6755  * Returns USB_NO_RESOURCES if it was not able to allocate all the requested TD
6756  * otherwise USB_SUCCESS.
6757  */
6758 int
6759 ohci_allocate_tds_for_tw(
6760         ohci_state_t            *ohcip,
6761         ohci_trans_wrapper_t    *tw,
6762         size_t                  td_count)
6763 {
6764         ohci_td_t               *td;
6765         uint32_t                td_addr;
6766         int                     i;
6767         int                     error = USB_SUCCESS;
6768 
6769         for (i = 0; i < td_count; i++) {
6770                 td = ohci_allocate_td_from_pool(ohcip);
6771                 if (td == NULL) {
6772                         error = USB_NO_RESOURCES;
6773                         USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6774                             "ohci_allocate_tds_for_tw: "
6775                             "Unable to allocate %lu TDs",
6776                             td_count);
6777                         break;
6778                 }
6779                 if (tw->tw_hctd_free_list != NULL) {
6780                         td_addr = ohci_td_cpu_to_iommu(ohcip,
6781                             tw->tw_hctd_free_list);
6782                         Set_TD(td->hctd_tw_next_td, td_addr);
6783                 }
6784                 tw->tw_hctd_free_list = td;
6785         }
6786 
6787         return (error);
6788 }
6789 
6790 /*
6791  * ohci_allocate_tw_resources:
6792  *
6793  * Allocate a Transaction Wrapper (TW) and n Transfer Descriptors (TD)
6794  * from the TD buffer pool and places it into the TW.  It does an all
6795  * or nothing transaction.
6796  *
6797  * Returns NULL if there is insufficient resources otherwise TW.
6798  */
6799 static ohci_trans_wrapper_t *
6800 ohci_allocate_tw_resources(
6801         ohci_state_t            *ohcip,
6802         ohci_pipe_private_t     *pp,
6803         size_t                  tw_length,
6804         usb_flags_t             usb_flags,
6805         size_t                  td_count)
6806 {
6807         ohci_trans_wrapper_t    *tw;
6808 
6809         tw = ohci_create_transfer_wrapper(ohcip, pp, tw_length, usb_flags);
6810 
6811         if (tw == NULL) {
6812                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6813                     "ohci_allocate_tw_resources: Unable to allocate TW");
6814         } else {
6815                 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) ==
6816                     USB_SUCCESS) {
6817                         tw->tw_num_tds = (uint_t)td_count;
6818                 } else {
6819                         ohci_deallocate_tw_resources(ohcip, pp, tw);
6820                         tw = NULL;
6821                 }
6822         }
6823 
6824         return (tw);
6825 }
6826 
6827 /*
6828  * ohci_free_tw_tds_resources:
6829  *
6830  * Free all allocated resources for Transaction Wrapper (TW).
6831  * Does not free the TW itself.
6832  */
6833 static void
6834 ohci_free_tw_tds_resources(
6835         ohci_state_t            *ohcip,
6836         ohci_trans_wrapper_t    *tw)
6837 {
6838         ohci_td_t               *td;
6839         ohci_td_t               *temp_td;
6840 
6841         td = tw->tw_hctd_free_list;
6842         while (td != NULL) {
6843                 /* Save the pointer to the next td before destroying it */
6844                 temp_td = ohci_td_iommu_to_cpu(ohcip,
6845                     Get_TD(td->hctd_tw_next_td));
6846                 ohci_deallocate_td(ohcip, td);
6847                 td = temp_td;
6848         }
6849         tw->tw_hctd_free_list = NULL;
6850 }
6851 
6852 
6853 /*
6854  * Transfer Wrapper functions
6855  *
6856  * ohci_create_transfer_wrapper:
6857  *
6858  * Create a Transaction Wrapper (TW) for non-isoc transfer types
6859  * and this involves the allocating of DMA resources.
6860  */
6861 static ohci_trans_wrapper_t *
6862 ohci_create_transfer_wrapper(
6863         ohci_state_t            *ohcip,
6864         ohci_pipe_private_t     *pp,
6865         size_t                  length,
6866         uint_t                  usb_flags)
6867 {
6868         ddi_device_acc_attr_t   dev_attr;
6869         int                     result;
6870         size_t                  real_length;
6871         ohci_trans_wrapper_t    *tw;
6872         ddi_dma_attr_t          dma_attr;
6873         int                     kmem_flag;
6874         int                     (*dmamem_wait)(caddr_t);
6875         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
6876 
6877         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6878             "ohci_create_transfer_wrapper: length = 0x%lx flags = 0x%x",
6879             length, usb_flags);
6880 
6881         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6882 
6883         /* isochronous pipe should not call into this function */
6884         if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) ==
6885             USB_EP_ATTR_ISOCH) {
6886 
6887                 return (NULL);
6888         }
6889 
6890         /* SLEEP flag should not be used while holding mutex */
6891         kmem_flag = KM_NOSLEEP;
6892         dmamem_wait = DDI_DMA_DONTWAIT;
6893 
6894         /* Allocate space for the transfer wrapper */
6895         tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag);
6896 
6897         if (tw == NULL) {
6898                 USB_DPRINTF_L2(PRINT_MASK_ALLOC,  ohcip->ohci_log_hdl,
6899                     "ohci_create_transfer_wrapper: kmem_zalloc failed");
6900 
6901                 return (NULL);
6902         }
6903 
6904         /* zero-length packet doesn't need to allocate dma memory */
6905         if (length == 0) {
6906 
6907                 goto dmadone;
6908         }
6909 
6910         /* allow sg lists for transfer wrapper dma memory */
6911         bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t));
6912         dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TW_SGLLEN;
6913         dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
6914 
6915         /* Allocate the DMA handle */
6916         result = ddi_dma_alloc_handle(ohcip->ohci_dip,
6917             &dma_attr, dmamem_wait, 0, &tw->tw_dmahandle);
6918 
6919         if (result != DDI_SUCCESS) {
6920                 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6921                     "ohci_create_transfer_wrapper: Alloc handle failed");
6922 
6923                 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6924 
6925                 return (NULL);
6926         }
6927 
6928         dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6929 
6930         /* The host controller will be little endian */
6931         dev_attr.devacc_attr_endian_flags  = DDI_STRUCTURE_BE_ACC;
6932         dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6933 
6934         /* Allocate the memory */
6935         result = ddi_dma_mem_alloc(tw->tw_dmahandle, length,
6936             &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, NULL,
6937             (caddr_t *)&tw->tw_buf, &real_length, &tw->tw_accesshandle);
6938 
6939         if (result != DDI_SUCCESS) {
6940                 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6941                     "ohci_create_transfer_wrapper: dma_mem_alloc fail");
6942 
6943                 ddi_dma_free_handle(&tw->tw_dmahandle);
6944                 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6945 
6946                 return (NULL);
6947         }
6948 
6949         ASSERT(real_length >= length);
6950 
6951         /* Bind the handle */
6952         result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL,
6953             (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
6954             dmamem_wait, NULL, &tw->tw_cookie, &tw->tw_ncookies);
6955 
6956         if (result != DDI_DMA_MAPPED) {
6957                 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
6958 
6959                 ddi_dma_mem_free(&tw->tw_accesshandle);
6960                 ddi_dma_free_handle(&tw->tw_dmahandle);
6961                 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6962 
6963                 return (NULL);
6964         }
6965 
6966         tw->tw_cookie_idx = 0;
6967         tw->tw_dma_offs = 0;
6968 
6969 dmadone:
6970         /*
6971          * Only allow one wrapper to be added at a time. Insert the
6972          * new transaction wrapper into the list for this pipe.
6973          */
6974         if (pp->pp_tw_head == NULL) {
6975                 pp->pp_tw_head = tw;
6976                 pp->pp_tw_tail = tw;
6977         } else {
6978                 pp->pp_tw_tail->tw_next = tw;
6979                 pp->pp_tw_tail = tw;
6980         }
6981 
6982         /* Store the transfer length */
6983         tw->tw_length = length;
6984 
6985         /* Store a back pointer to the pipe private structure */
6986         tw->tw_pipe_private = pp;
6987 
6988         /* Store the transfer type - synchronous or asynchronous */
6989         tw->tw_flags = usb_flags;
6990 
6991         /* Get and Store 32bit ID */
6992         tw->tw_id = OHCI_GET_ID((void *)tw);
6993 
6994         ASSERT(tw->tw_id != NULL);
6995 
6996         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6997             "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u",
6998             (void *)tw, tw->tw_ncookies);
6999 
7000         return (tw);
7001 }
7002 
7003 
7004 /*
7005  * Transfer Wrapper functions
7006  *
7007  * ohci_create_isoc_transfer_wrapper:
7008  *
7009  * Create a Transaction Wrapper (TW) for isoc transfer
7010  * and this involves the allocating of DMA resources.
7011  */
7012 static ohci_trans_wrapper_t *
7013 ohci_create_isoc_transfer_wrapper(
7014         ohci_state_t            *ohcip,
7015         ohci_pipe_private_t     *pp,
7016         size_t                  length,
7017         usb_isoc_pkt_descr_t    *descr,
7018         ushort_t                pkt_count,
7019         size_t                  td_count,
7020         uint_t                  usb_flags)
7021 {
7022         ddi_device_acc_attr_t   dev_attr;
7023         int                     result;
7024         size_t                  real_length, xfer_size;
7025         uint_t                  ccount;
7026         ohci_trans_wrapper_t    *tw;
7027         ddi_dma_attr_t          dma_attr;
7028         int                     kmem_flag;
7029         uint_t                  i, j, frame_count, residue;
7030         int                     (*dmamem_wait)(caddr_t);
7031         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
7032         usb_isoc_pkt_descr_t    *isoc_pkt_descr = descr;
7033 
7034         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7035             "ohci_create_isoc_transfer_wrapper: length = 0x%lx flags = 0x%x",
7036             length, usb_flags);
7037 
7038         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7039 
7040         /* non-isochronous pipe should not call into this function */
7041         if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) !=
7042             USB_EP_ATTR_ISOCH) {
7043 
7044                 return (NULL);
7045         }
7046 
7047         /* SLEEP flag should not be used in interrupt context */
7048         if (servicing_interrupt()) {
7049                 kmem_flag = KM_NOSLEEP;
7050                 dmamem_wait = DDI_DMA_DONTWAIT;
7051         } else {
7052                 kmem_flag = KM_SLEEP;
7053                 dmamem_wait = DDI_DMA_SLEEP;
7054         }
7055 
7056         /* Allocate space for the transfer wrapper */
7057         tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag);
7058 
7059         if (tw == NULL) {
7060                 USB_DPRINTF_L2(PRINT_MASK_ALLOC,  ohcip->ohci_log_hdl,
7061                     "ohci_create_transfer_wrapper: kmem_zalloc failed");
7062 
7063                 return (NULL);
7064         }
7065 
7066         /* Allocate space for the isoc buffer handles */
7067         tw->tw_isoc_strtlen = sizeof (ohci_isoc_buf_t) * td_count;
7068         if ((tw->tw_isoc_bufs = kmem_zalloc(tw->tw_isoc_strtlen,
7069             kmem_flag)) == NULL) {
7070                 USB_DPRINTF_L2(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7071                     "ohci_create_isoc_transfer_wrapper: kmem_alloc "
7072                     "isoc buffer failed");
7073                 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7074 
7075                 return (NULL);
7076         }
7077 
7078         /* allow sg lists for transfer wrapper dma memory */
7079         bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t));
7080         dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TD_SGLLEN;
7081         dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
7082 
7083         dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
7084 
7085         /* The host controller will be little endian */
7086         dev_attr.devacc_attr_endian_flags  = DDI_STRUCTURE_BE_ACC;
7087         dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
7088 
7089         residue = pkt_count % OHCI_ISOC_PKTS_PER_TD;
7090 
7091         for (i = 0; i < td_count; i++) {
7092                 tw->tw_isoc_bufs[i].index = i;
7093 
7094                 if ((i == (td_count - 1)) && (residue != 0)) {
7095                         frame_count = residue;
7096                 } else {
7097                         frame_count = OHCI_ISOC_PKTS_PER_TD;
7098                 }
7099 
7100                 /* Allocate the DMA handle */
7101                 result = ddi_dma_alloc_handle(ohcip->ohci_dip, &dma_attr,
7102                     dmamem_wait, 0, &tw->tw_isoc_bufs[i].dma_handle);
7103 
7104                 if (result != DDI_SUCCESS) {
7105                         USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7106                             "ohci_create_isoc_transfer_wrapper: "
7107                             "Alloc handle failed");
7108 
7109                         for (j = 0; j < i; j++) {
7110                                 result = ddi_dma_unbind_handle(
7111                                     tw->tw_isoc_bufs[j].dma_handle);
7112                                 ASSERT(result == USB_SUCCESS);
7113                                 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7114                                     mem_handle);
7115                                 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7116                                     dma_handle);
7117                         }
7118                         kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7119                         kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7120 
7121                         return (NULL);
7122                 }
7123 
7124                 /* Compute the memory length */
7125                 for (xfer_size = 0, j = 0; j < frame_count; j++) {
7126                         ASSERT(isoc_pkt_descr != NULL);
7127                         xfer_size += isoc_pkt_descr->isoc_pkt_length;
7128                         isoc_pkt_descr++;
7129                 }
7130 
7131                 /* Allocate the memory */
7132                 result = ddi_dma_mem_alloc(tw->tw_isoc_bufs[i].dma_handle,
7133                     xfer_size, &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait,
7134                     NULL, (caddr_t *)&tw->tw_isoc_bufs[i].buf_addr,
7135                     &real_length, &tw->tw_isoc_bufs[i].mem_handle);
7136 
7137                 if (result != DDI_SUCCESS) {
7138                         USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7139                             "ohci_create_isoc_transfer_wrapper: "
7140                             "dma_mem_alloc %d fail", i);
7141                         ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7142 
7143                         for (j = 0; j < i; j++) {
7144                                 result = ddi_dma_unbind_handle(
7145                                     tw->tw_isoc_bufs[j].dma_handle);
7146                                 ASSERT(result == USB_SUCCESS);
7147                                 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7148                                     mem_handle);
7149                                 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7150                                     dma_handle);
7151                         }
7152                         kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7153                         kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7154 
7155                         return (NULL);
7156                 }
7157 
7158                 ASSERT(real_length >= xfer_size);
7159 
7160                 /* Bind the handle */
7161                 result = ddi_dma_addr_bind_handle(
7162                     tw->tw_isoc_bufs[i].dma_handle, NULL,
7163                     (caddr_t)tw->tw_isoc_bufs[i].buf_addr, real_length,
7164                     DDI_DMA_RDWR|DDI_DMA_CONSISTENT, dmamem_wait, NULL,
7165                     &tw->tw_isoc_bufs[i].cookie, &ccount);
7166 
7167                 if ((result == DDI_DMA_MAPPED) &&
7168                     (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) {
7169                         tw->tw_isoc_bufs[i].length = xfer_size;
7170                         tw->tw_isoc_bufs[i].ncookies = ccount;
7171 
7172                         continue;
7173                 } else {
7174                         USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7175                             "ohci_create_isoc_transfer_wrapper: "
7176                             "Bind handle %d failed", i);
7177                         if (result == DDI_DMA_MAPPED) {
7178                                 result = ddi_dma_unbind_handle(
7179                                     tw->tw_isoc_bufs[i].dma_handle);
7180                                 ASSERT(result == USB_SUCCESS);
7181                         }
7182                         ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle);
7183                         ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7184 
7185                         for (j = 0; j < i; j++) {
7186                                 result = ddi_dma_unbind_handle(
7187                                     tw->tw_isoc_bufs[j].dma_handle);
7188                                 ASSERT(result == USB_SUCCESS);
7189                                 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7190                                     mem_handle);
7191                                 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7192                                     dma_handle);
7193                         }
7194                         kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7195                         kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7196 
7197                         return (NULL);
7198                 }
7199         }
7200 
7201         /*
7202          * Only allow one wrapper to be added at a time. Insert the
7203          * new transaction wrapper into the list for this pipe.
7204          */
7205         if (pp->pp_tw_head == NULL) {
7206                 pp->pp_tw_head = tw;
7207                 pp->pp_tw_tail = tw;
7208         } else {
7209                 pp->pp_tw_tail->tw_next = tw;
7210                 pp->pp_tw_tail = tw;
7211         }
7212 
7213         /* Store the transfer length */
7214         tw->tw_length = length;
7215 
7216         /* Store the td numbers */
7217         tw->tw_ncookies = (uint_t)td_count;
7218 
7219         /* Store a back pointer to the pipe private structure */
7220         tw->tw_pipe_private = pp;
7221 
7222         /* Store the transfer type - synchronous or asynchronous */
7223         tw->tw_flags = usb_flags;
7224 
7225         /* Get and Store 32bit ID */
7226         tw->tw_id = OHCI_GET_ID((void *)tw);
7227 
7228         ASSERT(tw->tw_id != NULL);
7229 
7230         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7231             "ohci_create_isoc_transfer_wrapper: tw = 0x%p", (void *)tw);
7232 
7233         return (tw);
7234 }
7235 
7236 
7237 /*
7238  * ohci_start_xfer_timer:
7239  *
7240  * Start the timer for the control, bulk and for one time interrupt
7241  * transfers.
7242  */
7243 /* ARGSUSED */
7244 static void
7245 ohci_start_xfer_timer(
7246         ohci_state_t            *ohcip,
7247         ohci_pipe_private_t     *pp,
7248         ohci_trans_wrapper_t    *tw)
7249 {
7250         USB_DPRINTF_L3(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7251             "ohci_start_xfer_timer: tw = 0x%p", (void *)tw);
7252 
7253         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7254 
7255         /*
7256          * The timeout handling is done only for control, bulk and for
7257          * one time Interrupt transfers.
7258          *
7259          * NOTE: If timeout is zero; Assume infinite timeout and don't
7260          * insert this transfer on the timeout list.
7261          */
7262         if (tw->tw_timeout) {
7263                 /*
7264                  * Increase timeout value by one second and this extra one
7265                  * second is used to halt the endpoint if given transfer
7266                  * times out.
7267                  */
7268                 tw->tw_timeout++;
7269 
7270                 /*
7271                  * Add this transfer wrapper into the transfer timeout list.
7272                  */
7273                 if (ohcip->ohci_timeout_list) {
7274                         tw->tw_timeout_next = ohcip->ohci_timeout_list;
7275                 }
7276 
7277                 ohcip->ohci_timeout_list = tw;
7278                 ohci_start_timer(ohcip);
7279         }
7280 }
7281 
7282 
7283 /*
7284  * ohci_stop_xfer_timer:
7285  *
7286  * Start the timer for the control, bulk and for one time interrupt
7287  * transfers.
7288  */
7289 void
7290 ohci_stop_xfer_timer(
7291         ohci_state_t            *ohcip,
7292         ohci_trans_wrapper_t    *tw,
7293         uint_t                  flag)
7294 {
7295         timeout_id_t            timer_id;
7296 
7297         USB_DPRINTF_L3(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7298             "ohci_stop_xfer_timer: tw = 0x%p", (void *)tw);
7299 
7300         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7301 
7302         /*
7303          * The timeout handling is done only for control, bulk
7304          * and for one time Interrupt transfers.
7305          */
7306         if (ohcip->ohci_timeout_list == NULL) {
7307                 return;
7308         }
7309 
7310         switch (flag) {
7311         case OHCI_REMOVE_XFER_IFLAST:
7312                 if (tw->tw_hctd_head != tw->tw_hctd_tail) {
7313                         break;
7314                 }
7315                 /* FALLTHRU */
7316         case OHCI_REMOVE_XFER_ALWAYS:
7317                 ohci_remove_tw_from_timeout_list(ohcip, tw);
7318 
7319                 if ((ohcip->ohci_timeout_list == NULL) &&
7320                     (ohcip->ohci_timer_id)) {
7321 
7322                         timer_id = ohcip->ohci_timer_id;
7323 
7324                         /* Reset the timer id to zero */
7325                         ohcip->ohci_timer_id = 0;
7326 
7327                         mutex_exit(&ohcip->ohci_int_mutex);
7328 
7329                         (void) untimeout(timer_id);
7330 
7331                         mutex_enter(&ohcip->ohci_int_mutex);
7332                 }
7333                 break;
7334         default:
7335                 break;
7336         }
7337 }
7338 
7339 
7340 /*
7341  * ohci_xfer_timeout_handler:
7342  *
7343  * Control or bulk transfer timeout handler.
7344  */
7345 static void
7346 ohci_xfer_timeout_handler(void *arg)
7347 {
7348         ohci_state_t            *ohcip = (ohci_state_t *)arg;
7349         ohci_trans_wrapper_t    *exp_xfer_list_head = NULL;
7350         ohci_trans_wrapper_t    *exp_xfer_list_tail = NULL;
7351         ohci_trans_wrapper_t    *tw, *next;
7352         ohci_td_t               *td;
7353         usb_flags_t             flags;
7354 
7355         USB_DPRINTF_L3(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7356             "ohci_xfer_timeout_handler: ohcip = 0x%p", (void *)ohcip);
7357 
7358         mutex_enter(&ohcip->ohci_int_mutex);
7359 
7360         /* Set the required flags */
7361         flags = OHCI_FLAGS_NOSLEEP | OHCI_FLAGS_DMA_SYNC;
7362 
7363         /*
7364          * Check whether still timeout handler is valid.
7365          */
7366         if (ohcip->ohci_timer_id) {
7367 
7368                 /* Reset the timer id to zero */
7369                 ohcip->ohci_timer_id = 0;
7370         } else {
7371                 mutex_exit(&ohcip->ohci_int_mutex);
7372 
7373                 return;
7374         }
7375 
7376         /* Get the transfer timeout list head */
7377         tw = ohcip->ohci_timeout_list;
7378 
7379         /*
7380          * Process ohci timeout list and look whether the timer
7381          * has expired for any transfers. Create a temporary list
7382          * of expired transfers and process them later.
7383          */
7384         while (tw) {
7385                 /* Get the transfer on the timeout list */
7386                 next = tw->tw_timeout_next;
7387 
7388                 tw->tw_timeout--;
7389 
7390                 /*
7391                  * Set the sKip bit to stop all transactions on
7392                  * this pipe
7393                  */
7394                 if (tw->tw_timeout == 1) {
7395                         ohci_modify_sKip_bit(ohcip,
7396                             tw->tw_pipe_private, SET_sKip, flags);
7397 
7398                         /* Reset dma sync flag */
7399                         flags &= ~OHCI_FLAGS_DMA_SYNC;
7400                 }
7401 
7402                 /* Remove tw from the timeout list */
7403                 if (tw->tw_timeout == 0) {
7404 
7405                         ohci_remove_tw_from_timeout_list(ohcip, tw);
7406 
7407                         /* Add tw to the end of expire list */
7408                         if (exp_xfer_list_head) {
7409                                 exp_xfer_list_tail->tw_timeout_next = tw;
7410                         } else {
7411                                 exp_xfer_list_head = tw;
7412                         }
7413                         exp_xfer_list_tail = tw;
7414                         tw->tw_timeout_next = NULL;
7415                 }
7416 
7417                 tw = next;
7418         }
7419 
7420         /* Get the expired transfer timeout list head */
7421         tw = exp_xfer_list_head;
7422 
7423         if (tw && (flags & OHCI_FLAGS_DMA_SYNC)) {
7424                 /* Sync ED and TD pool */
7425                 Sync_ED_TD_Pool(ohcip);
7426         }
7427 
7428         /*
7429          * Process the expired transfers by notifing the corrsponding
7430          * client driver through the exception callback.
7431          */
7432         while (tw) {
7433                 /* Get the transfer on the expired transfer timeout list */
7434                 next = tw->tw_timeout_next;
7435 
7436                 td = tw->tw_hctd_head;
7437 
7438                 while (td) {
7439                         /* Set TD state to TIMEOUT */
7440                         Set_TD(td->hctd_state, HC_TD_TIMEOUT);
7441 
7442                         /* Get the next TD from the wrapper */
7443                         td = ohci_td_iommu_to_cpu(ohcip,
7444                             Get_TD(td->hctd_tw_next_td));
7445                 }
7446 
7447                 ohci_handle_error(ohcip, tw->tw_hctd_head, USB_CR_TIMEOUT);
7448 
7449                 tw = next;
7450         }
7451 
7452         ohci_start_timer(ohcip);
7453         mutex_exit(&ohcip->ohci_int_mutex);
7454 }
7455 
7456 
7457 /*
7458  * ohci_remove_tw_from_timeout_list:
7459  *
7460  * Remove Control or bulk transfer from the timeout list.
7461  */
7462 static void
7463 ohci_remove_tw_from_timeout_list(
7464         ohci_state_t            *ohcip,
7465         ohci_trans_wrapper_t    *tw)
7466 {
7467         ohci_trans_wrapper_t    *prev, *next;
7468 
7469         USB_DPRINTF_L3(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7470             "ohci_remove_tw_from_timeout_list: tw = 0x%p", (void *)tw);
7471 
7472         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7473 
7474         if (ohcip->ohci_timeout_list == tw) {
7475                 ohcip->ohci_timeout_list = tw->tw_timeout_next;
7476         } else {
7477                 prev = ohcip->ohci_timeout_list;
7478                 next = prev->tw_timeout_next;
7479 
7480                 while (next && (next != tw)) {
7481                         prev = next;
7482                         next = next->tw_timeout_next;
7483                 }
7484 
7485                 if (next == tw) {
7486                         prev->tw_timeout_next = next->tw_timeout_next;
7487                 }
7488         }
7489 
7490         /* Reset the xfer timeout */
7491         tw->tw_timeout_next = NULL;
7492 }
7493 
7494 
7495 /*
7496  * ohci_start_timer:
7497  *
7498  * Start the ohci timer
7499  */
7500 static void
7501 ohci_start_timer(ohci_state_t   *ohcip)
7502 {
7503         USB_DPRINTF_L3(PRINT_MASK_LISTS,  ohcip->ohci_log_hdl,
7504             "ohci_start_timer: ohcip = 0x%p", (void *)ohcip);
7505 
7506         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7507 
7508         /*
7509          * Start the global timer only if currently timer is not
7510          * running and if there are any transfers on the timeout
7511          * list. This timer will be per USB Host Controller.
7512          */
7513         if ((!ohcip->ohci_timer_id) && (ohcip->ohci_timeout_list)) {
7514                 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler,
7515                     (void *)ohcip, drv_sectohz(1));
7516         }
7517 }
7518 
7519 
7520 /*
7521  * ohci_deallocate_tw_resources:
7522  * NOTE: This function is also called from POLLED MODE.
7523  *
7524  * Deallocate of a Transaction Wrapper (TW) and this involves the freeing of
7525  * of DMA resources.
7526  */
7527 void
7528 ohci_deallocate_tw_resources(
7529         ohci_state_t            *ohcip,
7530         ohci_pipe_private_t     *pp,
7531         ohci_trans_wrapper_t    *tw)
7532 {
7533         ohci_trans_wrapper_t    *prev, *next;
7534 
7535         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7536             "ohci_deallocate_tw_resources: tw = 0x%p", (void *)tw);
7537 
7538         /*
7539          * If the transfer wrapper has no Host Controller (HC)
7540          * Transfer Descriptors (TD) associated with it,  then
7541          * remove the transfer wrapper.
7542          */
7543         if (tw->tw_hctd_head) {
7544                 ASSERT(tw->tw_hctd_tail != NULL);
7545 
7546                 return;
7547         }
7548 
7549         ASSERT(tw->tw_hctd_tail == NULL);
7550 
7551         /* Make sure we return all the unused td's to the pool as well */
7552         ohci_free_tw_tds_resources(ohcip, tw);
7553 
7554         /*
7555          * If pp->pp_tw_head and pp->pp_tw_tail are pointing to
7556          * given TW then set the head and  tail  equal to NULL.
7557          * Otherwise search for this TW in the linked TW's list
7558          * and then remove this TW from the list.
7559          */
7560         if (pp->pp_tw_head == tw) {
7561                 if (pp->pp_tw_tail == tw) {
7562                         pp->pp_tw_head = NULL;
7563                         pp->pp_tw_tail = NULL;
7564                 } else {
7565                         pp->pp_tw_head = tw->tw_next;
7566                 }
7567         } else {
7568                 prev = pp->pp_tw_head;
7569                 next = prev->tw_next;
7570 
7571                 while (next && (next != tw)) {
7572                         prev = next;
7573                         next = next->tw_next;
7574                 }
7575 
7576                 if (next == tw) {
7577                         prev->tw_next = next->tw_next;
7578 
7579                         if (pp->pp_tw_tail == tw) {
7580                                 pp->pp_tw_tail = prev;
7581                         }
7582                 }
7583         }
7584 
7585         ohci_free_tw(ohcip, tw);
7586 }
7587 
7588 
7589 /*
7590  * ohci_free_dma_resources:
7591  *
7592  * Free dma resources of a Transfer Wrapper (TW) and also free the TW.
7593  */
7594 static void
7595 ohci_free_dma_resources(
7596         ohci_state_t            *ohcip,
7597         usba_pipe_handle_data_t *ph)
7598 {
7599         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
7600         ohci_trans_wrapper_t    *head_tw = pp->pp_tw_head;
7601         ohci_trans_wrapper_t    *next_tw, *tw;
7602 
7603         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7604             "ohci_free_dma_resources: ph = 0x%p", (void *)ph);
7605 
7606         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7607 
7608         /* Process the Transfer Wrappers */
7609         next_tw = head_tw;
7610         while (next_tw) {
7611                 tw = next_tw;
7612                 next_tw = tw->tw_next;
7613 
7614                 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7615                     "ohci_free_dma_resources: Free TW = 0x%p", (void *)tw);
7616 
7617                 ohci_free_tw(ohcip, tw);
7618         }
7619 
7620         /* Adjust the head and tail pointers */
7621         pp->pp_tw_head = NULL;
7622         pp->pp_tw_tail = NULL;
7623 }
7624 
7625 
7626 /*
7627  * ohci_free_tw:
7628  *
7629  * Free the Transfer Wrapper (TW).
7630  */
7631 static void
7632 ohci_free_tw(
7633         ohci_state_t            *ohcip,
7634         ohci_trans_wrapper_t    *tw)
7635 {
7636         int                     rval, i;
7637 
7638         USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7639             "ohci_free_tw: tw = 0x%p", (void *)tw);
7640 
7641         ASSERT(tw != NULL);
7642         ASSERT(tw->tw_id != NULL);
7643 
7644         /* Free 32bit ID */
7645         OHCI_FREE_ID((uint32_t)tw->tw_id);
7646 
7647         if (tw->tw_isoc_strtlen > 0) {
7648                 ASSERT(tw->tw_isoc_bufs != NULL);
7649                 for (i = 0; i < tw->tw_ncookies; i++) {
7650                         if (tw->tw_isoc_bufs[i].ncookies > 0) {
7651                                 rval = ddi_dma_unbind_handle(
7652                                     tw->tw_isoc_bufs[i].dma_handle);
7653                                 ASSERT(rval == USB_SUCCESS);
7654                         }
7655                         ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle);
7656                         ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7657                 }
7658                 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7659         } else if (tw->tw_dmahandle != NULL) {
7660                 if (tw->tw_ncookies > 0) {
7661                         rval = ddi_dma_unbind_handle(tw->tw_dmahandle);
7662                         ASSERT(rval == DDI_SUCCESS);
7663                 }
7664                 ddi_dma_mem_free(&tw->tw_accesshandle);
7665                 ddi_dma_free_handle(&tw->tw_dmahandle);
7666         }
7667 
7668         /* Free transfer wrapper */
7669         kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7670 }
7671 
7672 
7673 /*
7674  * Interrupt Handling functions
7675  */
7676 
7677 /*
7678  * ohci_intr:
7679  *
7680  * OpenHCI (OHCI) interrupt handling routine.
7681  */
7682 static uint_t
7683 ohci_intr(caddr_t arg1, caddr_t arg2)
7684 {
7685         ohci_state_t            *ohcip = (ohci_state_t *)arg1;
7686         uint_t                  intr;
7687         ohci_td_t               *done_head = NULL;
7688         ohci_save_intr_sts_t    *ohci_intr_sts = &ohcip->ohci_save_intr_sts;
7689 
7690         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7691             "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p",
7692             (void *)arg1, (void *)arg2);
7693 
7694         mutex_enter(&ohcip->ohci_int_mutex);
7695 
7696         /* Any interrupt is not handled for the suspended device. */
7697         if (ohcip->ohci_hc_soft_state == OHCI_CTLR_SUSPEND_STATE) {
7698                 mutex_exit(&ohcip->ohci_int_mutex);
7699 
7700                 return (DDI_INTR_UNCLAIMED);
7701         }
7702 
7703         /*
7704          * Suppose if we switched to the polled mode from the normal
7705          * mode when interrupt handler is executing then we  need to
7706          * save the interrupt status information in the  polled mode
7707          * to  avoid race conditions. The following flag will be set
7708          * and reset on entering & exiting of ohci interrupt handler
7709          * respectively.  This flag will be used in the  polled mode
7710          * to check whether the interrupt handler was running when we
7711          * switched to the polled mode from the normal mode.
7712          */
7713         ohci_intr_sts->ohci_intr_flag = OHCI_INTR_HANDLING;
7714 
7715         /* Temporarily turn off interrupts */
7716         Set_OpReg(hcr_intr_disable, HCR_INTR_MIE);
7717 
7718         /*
7719          * Handle any missed ohci interrupt especially WriteDoneHead
7720          * and SOF interrupts because of previous polled mode switch.
7721          */
7722         ohci_handle_missed_intr(ohcip);
7723 
7724         /*
7725          * Now process the actual ohci interrupt events  that caused
7726          * invocation of this ohci interrupt handler.
7727          */
7728 
7729         /*
7730          * Updating the WriteDoneHead interrupt:
7731          *
7732          * (a) Host Controller
7733          *
7734          *      - First Host controller (HC) checks  whether WDH bit
7735          *        in the interrupt status register is cleared.
7736          *
7737          *      - If WDH bit is cleared then HC writes new done head
7738          *        list information into the HCCA done head field.
7739          *
7740          *      - Set WDH bit in the interrupt status register.
7741          *
7742          * (b) Host Controller Driver (HCD)
7743          *
7744          *      - First read the interrupt status register. The HCCA
7745          *        done head and WDH bit may be set or may not be set
7746          *        while reading the interrupt status register.
7747          *
7748          *      - Read the  HCCA done head list. By this time may be
7749          *        HC has updated HCCA done head and  WDH bit in ohci
7750          *        interrupt status register.
7751          *
7752          *      - If done head is non-null and if WDH bit is not set
7753          *        then Host Controller has updated HCCA  done head &
7754          *        WDH bit in the interrupt stats register in between
7755          *        reading the interrupt status register & HCCA      done
7756          *        head. In that case, definitely WDH bit will be set
7757          *        in the interrupt status register & driver can take
7758          *        it for granted.
7759          *
7760          * Now read the Interrupt Status & Interrupt enable register
7761          * to determine the exact interrupt events.
7762          */
7763         intr = ohci_intr_sts->ohci_curr_intr_sts =
7764             (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable));
7765 
7766         if (ohcip->ohci_hccap) {
7767                 /* Sync HCCA area */
7768                 Sync_HCCA(ohcip);
7769 
7770                 /* Read and Save the HCCA DoneHead value */
7771                 done_head = ohci_intr_sts->ohci_curr_done_lst =
7772                     (ohci_td_t *)(uintptr_t)
7773                     (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) &
7774                     HCCA_DONE_HEAD_MASK);
7775 
7776                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7777                     "ohci_intr: Done head! 0x%p", (void *)done_head);
7778         }
7779 
7780         /* Update kstat values */
7781         ohci_do_intrs_stats(ohcip, intr);
7782 
7783         /*
7784          * Look at the HccaDoneHead, if it is a non-zero valid address,
7785          * a done list update interrupt is indicated. Otherwise, this
7786          * intr bit is cleared.
7787          */
7788         if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
7789 
7790                 /* Set the WriteDoneHead bit in the interrupt events */
7791                 intr |= HCR_INTR_WDH;
7792         } else {
7793 
7794                 /* Clear the WriteDoneHead bit */
7795                 intr &= ~HCR_INTR_WDH;
7796         }
7797 
7798         /*
7799          * We could have gotten a spurious interrupts. If so, do not
7800          * claim it.  This is quite  possible on some  architectures
7801          * where more than one PCI slots share the IRQs.  If so, the
7802          * associated driver's interrupt routine may get called even
7803          * if the interrupt is not meant for them.
7804          *
7805          * By unclaiming the interrupt, the other driver gets chance
7806          * to service its interrupt.
7807          */
7808         if (!intr) {
7809 
7810                 /* Reset the interrupt handler flag */
7811                 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING;
7812 
7813                 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE);
7814                 mutex_exit(&ohcip->ohci_int_mutex);
7815                 return (DDI_INTR_UNCLAIMED);
7816         }
7817 
7818         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7819             "Interrupt status 0x%x", intr);
7820 
7821         /*
7822          * Check for Frame Number Overflow.
7823          */
7824         if (intr & HCR_INTR_FNO) {
7825                 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7826                     "ohci_intr: Frame Number Overflow");
7827 
7828                 ohci_handle_frame_number_overflow(ohcip);
7829         }
7830 
7831         if (intr & HCR_INTR_SOF) {
7832                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7833                     "ohci_intr: Start of Frame");
7834 
7835                 /* Set ohci_sof_flag indicating SOF interrupt occurred */
7836                 ohcip->ohci_sof_flag = B_TRUE;
7837 
7838                 /* Disabel SOF interrupt */
7839                 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF);
7840 
7841                 /*
7842                  * Call cv_broadcast on every SOF interrupt to wakeup
7843                  * all the threads that are waiting the SOF.  Calling
7844                  * cv_broadcast on every SOF has no effect even if no
7845                  * threads are waiting for the SOF.
7846                  */
7847                 cv_broadcast(&ohcip->ohci_SOF_cv);
7848         }
7849 
7850         if (intr & HCR_INTR_SO) {
7851                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7852                     "ohci_intr: Schedule overrun");
7853 
7854                 ohcip->ohci_so_error++;
7855         }
7856 
7857         if ((intr & HCR_INTR_WDH) && (done_head)) {
7858                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7859                     "ohci_intr: Done Head");
7860 
7861                 /*
7862                  * Currently if we are processing one  WriteDoneHead
7863                  * interrupt  and also if we  switched to the polled
7864                  * mode at least once  during this time,  then there
7865                  * may be chance that  Host Controller generates one
7866                  * more Write DoneHead or Start of Frame  interrupts
7867                  * for the normal since the polled code clears WDH &
7868                  * SOF interrupt bits before returning to the normal
7869                  * mode. Under this condition, we must not clear the
7870                  * HCCA done head field & also we must not clear WDH
7871                  * interrupt bit in the interrupt  status register.
7872                  */
7873                 if (done_head == (ohci_td_t *)(uintptr_t)
7874                     (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) &
7875                     HCCA_DONE_HEAD_MASK)) {
7876 
7877                         /* Reset the done head to NULL */
7878                         Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL);
7879                 } else {
7880                         intr &= ~HCR_INTR_WDH;
7881                 }
7882 
7883                 /* Clear the current done head field */
7884                 ohci_intr_sts->ohci_curr_done_lst = NULL;
7885 
7886                 ohci_traverse_done_list(ohcip, done_head);
7887         }
7888 
7889         /* Process endpoint reclaimation list */
7890         if (ohcip->ohci_reclaim_list) {
7891                 ohci_handle_endpoint_reclaimation(ohcip);
7892         }
7893 
7894         if (intr & HCR_INTR_RD) {
7895                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7896                     "ohci_intr: Resume Detected");
7897         }
7898 
7899         if (intr & HCR_INTR_RHSC) {
7900                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7901                     "ohci_intr: Root hub status change");
7902         }
7903 
7904         if (intr & HCR_INTR_OC) {
7905                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7906                     "ohci_intr: Change ownership");
7907 
7908         }
7909 
7910         if (intr & HCR_INTR_UE) {
7911                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7912                     "ohci_intr: Unrecoverable error");
7913 
7914                 ohci_handle_ue(ohcip);
7915         }
7916 
7917         /* Acknowledge the interrupt */
7918         Set_OpReg(hcr_intr_status, intr);
7919 
7920         /* Clear the current interrupt event field */
7921         ohci_intr_sts->ohci_curr_intr_sts = 0;
7922 
7923         /*
7924          * Reset the following flag indicating exiting the interrupt
7925          * handler and this flag will be used in the polled  mode to
7926          * do some extra processing.
7927          */
7928         ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING;
7929 
7930         Set_OpReg(hcr_intr_enable, HCR_INTR_MIE);
7931 
7932         /*
7933          * Read interrupt status register to make sure that any PIO
7934          * store to clear the ISR has made it on the PCI bus before
7935          * returning from its interrupt handler.
7936          */
7937         (void) Get_OpReg(hcr_intr_status);
7938 
7939         mutex_exit(&ohcip->ohci_int_mutex);
7940 
7941         USB_DPRINTF_L3(PRINT_MASK_INTR,  ohcip->ohci_log_hdl,
7942             "Interrupt handling completed");
7943 
7944         return (DDI_INTR_CLAIMED);
7945 }
7946 
7947 /*
7948  * Check whether done_head is a valid td point address.
7949  * It should be non-zero, 16-byte aligned, and fall in ohci_td_pool.
7950  */
7951 static int
7952 ohci_check_done_head(ohci_state_t *ohcip, ohci_td_t *done_head)
7953 {
7954         uintptr_t lower, upper, headp;
7955         lower = ohcip->ohci_td_pool_cookie.dmac_address;
7956         upper = lower + ohcip->ohci_td_pool_cookie.dmac_size;
7957         headp = (uintptr_t)done_head;
7958 
7959         if (headp && !(headp & ~HCCA_DONE_HEAD_MASK) &&
7960             (headp >= lower) && (headp < upper)) {
7961 
7962                 return (USB_SUCCESS);
7963         } else {
7964 
7965                 return (USB_FAILURE);
7966         }
7967 }
7968 
7969 /*
7970  * ohci_handle_missed_intr:
7971  *
7972  * Handle any ohci missed interrupts because of polled mode switch.
7973  */
7974 static void
7975 ohci_handle_missed_intr(ohci_state_t    *ohcip)
7976 {
7977         ohci_save_intr_sts_t            *ohci_intr_sts =
7978             &ohcip->ohci_save_intr_sts;
7979         ohci_td_t                       *done_head;
7980         uint_t                          intr;
7981 
7982         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7983 
7984         /*
7985          * Check whether we have  missed any ohci interrupts because
7986          * of the polled mode switch during  previous ohci interrupt
7987          * handler execution. Only  Write Done Head & SOF interrupts
7988          * saved in the polled mode. First process  these interrupts
7989          * before processing actual interrupts that caused invocation
7990          * of ohci interrupt handler.
7991          */
7992         if (!ohci_intr_sts->ohci_missed_intr_sts) {
7993                 /* No interrupts are missed, simply return */
7994 
7995                 return;
7996         }
7997 
7998         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7999             "ohci_handle_missed_intr: Handle ohci missed interrupts");
8000 
8001         /*
8002          * The functionality and importance of critical code section
8003          * in the normal mode ohci  interrupt handler & its usage in
8004          * the polled mode is explained below.
8005          *
8006          * (a) Normal mode:
8007          *
8008          *      - Set the flag  indicating that  processing critical
8009          *        code in ohci interrupt handler.
8010          *
8011          *      - Process the missed ohci interrupts by  copying the
8012          *        miised interrupt events and done  head list fields
8013          *        information to the critical interrupt event & done
8014          *        list fields.
8015          *
8016          *      - Reset the missed ohci interrupt events & done head
8017          *        list fields so that the new missed interrupt event
8018          *        and done head list information can be saved.
8019          *
8020          *      - All above steps will be executed  with in critical
8021          *        section of the  interrupt handler.Then ohci missed
8022          *        interrupt handler will be called to service missed
8023          *        ohci interrupts.
8024          *
8025          * (b) Polled mode:
8026          *
8027          *      - On entering the polled code,it checks for critical
8028          *        section code execution within the normal mode ohci
8029          *        interrupt handler.
8030          *
8031          *      - If the critical section code is executing in normal
8032          *        mode ohci interrupt handler and if copying of ohci
8033          *        missed interrupt events & done head list fields to
8034          *        the critical fields is finished then save the "any
8035          *        missed interrupt events & done head list"  because
8036          *        of current polled mode switch into "critical missed
8037          *        interrupt events & done list fields" instead actual
8038          *        missed events and done list fields.
8039          *
8040          *      - Otherwise save "any missed interrupt events & done
8041          *        list" because of this  current polled  mode switch
8042          *        in the actual missed  interrupt events & done head
8043          *        list fields.
8044          */
8045 
8046         /*
8047          * Set flag indicating that  interrupt handler is processing
8048          * critical interrupt code,  so that polled mode code checks
8049          * for this condition & will do extra processing as explained
8050          * above in order to aviod the race conditions.
8051          */
8052         ohci_intr_sts->ohci_intr_flag |= OHCI_INTR_CRITICAL;
8053         ohci_intr_sts->ohci_critical_intr_sts |=
8054             ohci_intr_sts->ohci_missed_intr_sts;
8055 
8056         if (ohci_intr_sts->ohci_missed_done_lst) {
8057 
8058                 ohci_intr_sts->ohci_critical_done_lst =
8059                     ohci_intr_sts->ohci_missed_done_lst;
8060         }
8061 
8062         ohci_intr_sts->ohci_missed_intr_sts = 0;
8063         ohci_intr_sts->ohci_missed_done_lst = NULL;
8064         ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_CRITICAL;
8065 
8066         intr = ohci_intr_sts->ohci_critical_intr_sts;
8067         done_head = ohci_intr_sts->ohci_critical_done_lst;
8068 
8069         if (intr & HCR_INTR_SOF) {
8070                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8071                     "ohci_handle_missed_intr: Start of Frame");
8072 
8073                 /*
8074                  * Call cv_broadcast on every SOF interrupt to wakeup
8075                  * all the threads that are waiting the SOF.  Calling
8076                  * cv_broadcast on every SOF has no effect even if no
8077                  * threads are waiting for the SOF.
8078                  */
8079                 cv_broadcast(&ohcip->ohci_SOF_cv);
8080         }
8081 
8082         if ((intr & HCR_INTR_WDH) && (done_head)) {
8083                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8084                     "ohci_handle_missed_intr: Done Head");
8085 
8086                 /* Clear the critical done head field */
8087                 ohci_intr_sts->ohci_critical_done_lst = NULL;
8088 
8089                 ohci_traverse_done_list(ohcip, done_head);
8090         }
8091 
8092         /* Clear the critical interrupt event field */
8093         ohci_intr_sts->ohci_critical_intr_sts = 0;
8094 }
8095 
8096 
8097 /*
8098  * ohci_handle_ue:
8099  *
8100  * Handling of Unrecoverable Error interrupt (UE).
8101  */
8102 static void
8103 ohci_handle_ue(ohci_state_t     *ohcip)
8104 {
8105         usb_frame_number_t      before_frame_number, after_frame_number;
8106 
8107         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8108 
8109         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8110             "ohci_handle_ue: Handling of UE interrupt");
8111 
8112         /*
8113          * First check whether current UE error occured due to USB or
8114          * due to some other subsystem. This can be verified by reading
8115          * usb frame numbers before & after a delay of few milliseconds.
8116          * If usb frame number read after delay is greater than the one
8117          * read before delay, then, USB subsystem is fine. In this case,
8118          * disable UE error interrupt and return without shutdowning the
8119          * USB subsystem.
8120          *
8121          * Otherwise, if usb frame number read after delay is less than
8122          * or equal to one read before the delay, then, current UE error
8123          * occured from USB susbsystem. In this case,go ahead with actual
8124          * UE error recovery procedure.
8125          *
8126          * Get the current usb frame number before waiting for few
8127          * milliseconds.
8128          */
8129         before_frame_number = ohci_get_current_frame_number(ohcip);
8130 
8131         /* Wait for few milliseconds */
8132         drv_usecwait(OHCI_TIMEWAIT);
8133 
8134         /*
8135          * Get the current usb frame number after waiting for
8136          * milliseconds.
8137          */
8138         after_frame_number = ohci_get_current_frame_number(ohcip);
8139 
8140         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8141             "ohci_handle_ue: Before Frm No 0x%llx After Frm No 0x%llx",
8142             (unsigned long long)before_frame_number,
8143             (unsigned long long)after_frame_number);
8144 
8145         if (after_frame_number > before_frame_number) {
8146 
8147                 /* Disable UE interrupt */
8148                 Set_OpReg(hcr_intr_disable, HCR_INTR_UE);
8149 
8150                 return;
8151         }
8152 
8153         /*
8154          * This UE is due to USB hardware error. Reset ohci controller
8155          * and reprogram to bring it back to functional state.
8156          */
8157         if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) {
8158                 USB_DPRINTF_L0(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8159                     "Unrecoverable USB Hardware Error");
8160 
8161                 /* Disable UE interrupt */
8162                 Set_OpReg(hcr_intr_disable, HCR_INTR_UE);
8163 
8164                 /* Set host controller soft state to error */
8165                 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE;
8166         }
8167 }
8168 
8169 
8170 /*
8171  * ohci_handle_frame_number_overflow:
8172  *
8173  * Update software based usb frame number part on every frame number
8174  * overflow interrupt.
8175  *
8176  * NOTE: This function is also called from POLLED MODE.
8177  *
8178  * Refer ohci spec 1.0a, section 5.3, page 81 for more details.
8179  */
8180 void
8181 ohci_handle_frame_number_overflow(ohci_state_t *ohcip)
8182 {
8183         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8184             "ohci_handle_frame_number_overflow:");
8185 
8186         ohcip->ohci_fno += (0x10000 -
8187             (((Get_HCCA(ohcip->ohci_hccap->HccaFrameNo) &
8188             0xFFFF) ^ ohcip->ohci_fno) & 0x8000));
8189 
8190         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8191             "ohci_handle_frame_number_overflow:"
8192             "Frame Number Higher Part 0x%llx\n",
8193             (unsigned long long)(ohcip->ohci_fno));
8194 }
8195 
8196 
8197 /*
8198  * ohci_handle_endpoint_reclaimation:
8199  *
8200  * Reclamation of Host Controller (HC) Endpoint Descriptors (ED).
8201  */
8202 static void
8203 ohci_handle_endpoint_reclaimation(ohci_state_t  *ohcip)
8204 {
8205         usb_frame_number_t      current_frame_number;
8206         usb_frame_number_t      endpoint_frame_number;
8207         ohci_ed_t               *reclaim_ed;
8208 
8209         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8210             "ohci_handle_endpoint_reclaimation:");
8211 
8212         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8213 
8214         current_frame_number = ohci_get_current_frame_number(ohcip);
8215 
8216         /*
8217          * Deallocate all Endpoint Descriptors (ED) which are on the
8218          * reclaimation list. These ED's are already removed from the
8219          * interrupt lattice tree.
8220          */
8221         while (ohcip->ohci_reclaim_list) {
8222                 reclaim_ed = ohcip->ohci_reclaim_list;
8223 
8224                 endpoint_frame_number = (usb_frame_number_t)(uintptr_t)
8225                     (OHCI_LOOKUP_ID(Get_ED(reclaim_ed->hced_reclaim_frame)));
8226 
8227                 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8228                     "ohci_handle_endpoint_reclaimation:"
8229                     "current frame number 0x%llx endpoint frame number 0x%llx",
8230                     (unsigned long long)current_frame_number,
8231                     (unsigned long long)endpoint_frame_number);
8232 
8233                 /*
8234                  * Deallocate current endpoint only if endpoint's usb frame
8235                  * number is less than or equal to current usb frame number.
8236                  *
8237                  * If endpoint's usb frame number is greater than the current
8238                  * usb frame number, ignore rest of the endpoints in the list
8239                  * since rest of the endpoints are inserted into the reclaim
8240                  * list later than the current reclaim endpoint.
8241                  */
8242                 if (endpoint_frame_number > current_frame_number) {
8243                         break;
8244                 }
8245 
8246                 /* Get the next endpoint from the rec. list */
8247                 ohcip->ohci_reclaim_list = ohci_ed_iommu_to_cpu(ohcip,
8248                     Get_ED(reclaim_ed->hced_reclaim_next));
8249 
8250                 /* Free 32bit ID */
8251                 OHCI_FREE_ID((uint32_t)Get_ED(reclaim_ed->hced_reclaim_frame));
8252 
8253                 /* Deallocate the endpoint */
8254                 ohci_deallocate_ed(ohcip, reclaim_ed);
8255         }
8256 }
8257 
8258 
8259 /*
8260  * ohci_traverse_done_list:
8261  */
8262 static void
8263 ohci_traverse_done_list(
8264         ohci_state_t            *ohcip,
8265         ohci_td_t               *head_done_list)
8266 {
8267         uint_t                  state;          /* TD state */
8268         ohci_td_t               *td, *old_td;   /* TD pointers */
8269         usb_cr_t                error;          /* Error from TD */
8270         ohci_trans_wrapper_t    *tw = NULL;     /* Transfer wrapper */
8271         ohci_pipe_private_t     *pp = NULL;     /* Pipe private field */
8272 
8273         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8274             "ohci_traverse_done_list:");
8275 
8276         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8277 
8278         /* Sync ED and TD pool */
8279         Sync_ED_TD_Pool(ohcip);
8280 
8281         /* Reverse the done list */
8282         td = ohci_reverse_done_list(ohcip, head_done_list);
8283 
8284         /* Traverse the list of transfer descriptors */
8285         while (td) {
8286                 /* Check for TD state */
8287                 state = Get_TD(td->hctd_state);
8288 
8289                 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8290                     "ohci_traverse_done_list:\n\t"
8291                     "td = 0x%p  state = 0x%x", (void *)td, state);
8292 
8293                 /*
8294                  * Obtain the  transfer wrapper only  if the TD is
8295                  * not marked as RECLAIM.
8296                  *
8297                  * A TD that is marked as  RECLAIM has had its DMA
8298                  * mappings, ED, TD and pipe private structure are
8299                  * ripped down. Just deallocate this TD.
8300                  */
8301                 if (state != HC_TD_RECLAIM) {
8302 
8303                         tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
8304                             (uint32_t)Get_TD(td->hctd_trans_wrapper));
8305 
8306                         ASSERT(tw != NULL);
8307 
8308                         pp = tw->tw_pipe_private;
8309 
8310                         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8311                             "ohci_traverse_done_list: PP = 0x%p TW = 0x%p",
8312                             (void *)pp, (void *)tw);
8313                 }
8314 
8315                 /*
8316                  * Don't process the TD if its  state is marked as
8317                  * either RECLAIM or TIMEOUT.
8318                  *
8319                  * A TD that is marked as TIMEOUT has already been
8320                  * processed by TD timeout handler & client driver
8321                  * has been informed through exception callback.
8322                  */
8323                 if ((state != HC_TD_RECLAIM) && (state != HC_TD_TIMEOUT)) {
8324 
8325                         /* Look at the error status */
8326                         error = ohci_parse_error(ohcip, td);
8327 
8328                         if (error == USB_CR_OK) {
8329                                 ohci_handle_normal_td(ohcip, td, tw);
8330                         } else {
8331                                 /* handle the error condition */
8332                                 ohci_handle_error(ohcip, td, error);
8333                         }
8334                 } else {
8335                         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8336                             "ohci_traverse_done_list: TD State = %d", state);
8337                 }
8338 
8339                 /*
8340                  * Save a pointer to the current transfer descriptor
8341                  */
8342                 old_td = td;
8343 
8344                 td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td));
8345 
8346                 /* Deallocate this transfer descriptor */
8347                 ohci_deallocate_td(ohcip, old_td);
8348 
8349                 /*
8350                  * Deallocate the transfer wrapper if there are no more
8351                  * TD's for the transfer wrapper. ohci_deallocate_tw_resources()
8352                  * will  not deallocate the tw for a periodic  endpoint
8353                  * since it will always have a TD attached to it.
8354                  *
8355                  * Do not deallocate the TW if it is a isoc or intr pipe in.
8356                  * The tw's are reused.
8357                  *
8358                  * An TD that is marked as reclaim doesn't have a  pipe
8359                  * or a TW associated with it anymore so don't call this
8360                  * function.
8361                  */
8362                 if (state != HC_TD_RECLAIM) {
8363                         ASSERT(tw != NULL);
8364                         ohci_deallocate_tw_resources(ohcip, pp, tw);
8365                 }
8366         }
8367 }
8368 
8369 
8370 /*
8371  * ohci_reverse_done_list:
8372  *
8373  * Reverse the order of the Transfer Descriptor (TD) Done List.
8374  */
8375 static ohci_td_t *
8376 ohci_reverse_done_list(
8377         ohci_state_t    *ohcip,
8378         ohci_td_t       *head_done_list)
8379 {
8380         ohci_td_t       *cpu_new_tail, *cpu_new_head, *cpu_save;
8381 
8382         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8383             "ohci_reverse_done_list:");
8384 
8385         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8386         ASSERT(head_done_list != NULL);
8387 
8388         /* At first, both the tail and head pointers point to the same elem */
8389         cpu_new_tail = cpu_new_head =
8390             ohci_td_iommu_to_cpu(ohcip, (uintptr_t)head_done_list);
8391 
8392         /* See if the list has only one element */
8393         if (Get_TD(cpu_new_head->hctd_next_td) == NULL) {
8394 
8395                 return (cpu_new_head);
8396         }
8397 
8398         /* Advance the head pointer */
8399         cpu_new_head = (ohci_td_t *)
8400             ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td));
8401 
8402         /* The new tail now points to nothing */
8403         Set_TD(cpu_new_tail->hctd_next_td, NULL);
8404 
8405         cpu_save = (ohci_td_t *)
8406             ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td));
8407 
8408         /* Reverse the list and store the pointers as CPU addresses */
8409         while (cpu_save) {
8410                 Set_TD(cpu_new_head->hctd_next_td,
8411                     ohci_td_cpu_to_iommu(ohcip, cpu_new_tail));
8412 
8413                 cpu_new_tail = cpu_new_head;
8414                 cpu_new_head = cpu_save;
8415 
8416                 cpu_save = (ohci_td_t *)
8417                     ohci_td_iommu_to_cpu(ohcip,
8418                     Get_TD(cpu_new_head->hctd_next_td));
8419         }
8420 
8421         Set_TD(cpu_new_head->hctd_next_td,
8422             ohci_td_cpu_to_iommu(ohcip, cpu_new_tail));
8423 
8424         return (cpu_new_head);
8425 }
8426 
8427 
8428 /*
8429  * ohci_parse_error:
8430  *
8431  * Parse the result for any errors.
8432  */
8433 static usb_cr_t
8434 ohci_parse_error(
8435         ohci_state_t            *ohcip,
8436         ohci_td_t               *td)
8437 {
8438         uint_t                  ctrl;
8439         usb_ep_descr_t          *eptd;
8440         ohci_trans_wrapper_t    *tw;
8441         ohci_pipe_private_t     *pp;
8442         uint_t                  flag;
8443         usb_cr_t                error;
8444 
8445         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8446             "ohci_parse_error:");
8447 
8448         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8449 
8450         ASSERT(td != NULL);
8451 
8452         /* Obtain the transfer wrapper from the TD */
8453         tw = (ohci_trans_wrapper_t *)
8454             OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper));
8455 
8456         ASSERT(tw != NULL);
8457 
8458         /* Obtain the pipe private structure */
8459         pp = tw->tw_pipe_private;
8460 
8461         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8462             "ohci_parse_error: PP 0x%p TW 0x%p", (void *)pp, (void *)tw);
8463 
8464         eptd = &pp->pp_pipe_handle->p_ep;
8465 
8466         ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC;
8467 
8468         /*
8469          * Check the condition code of completed TD and report errors
8470          * if any. This checking will be done both for the general and
8471          * the isochronous TDs.
8472          */
8473         if ((error = ohci_check_for_error(ohcip, pp, tw, td, ctrl)) !=
8474             USB_CR_OK) {
8475                 flag = OHCI_REMOVE_XFER_ALWAYS;
8476         } else {
8477                 flag  = OHCI_REMOVE_XFER_IFLAST;
8478         }
8479 
8480         /* Stop the the transfer timer */
8481         ohci_stop_xfer_timer(ohcip, tw, flag);
8482 
8483         /*
8484          * The isochronous endpoint needs additional error checking
8485          * and special processing.
8486          */
8487         if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
8488             USB_EP_ATTR_ISOCH) {
8489 
8490                 ohci_parse_isoc_error(ohcip, pp, tw, td);
8491 
8492                 /* always reset error */
8493                 error = USB_CR_OK;
8494         }
8495 
8496         return (error);
8497 }
8498 
8499 
8500 /*
8501  * ohci_parse_isoc_error:
8502  *
8503  * Check for any errors in the isochronous data packets. Also fillup
8504  * the status for each of the isochrnous data packets.
8505  */
8506 void
8507 ohci_parse_isoc_error(
8508         ohci_state_t            *ohcip,
8509         ohci_pipe_private_t     *pp,
8510         ohci_trans_wrapper_t    *tw,
8511         ohci_td_t               *td)
8512 {
8513         usb_isoc_req_t          *isoc_reqp;
8514         usb_isoc_pkt_descr_t    *isoc_pkt_descr;
8515         uint_t                  toggle = 0, fc, ctrl, psw;
8516         int                     i;
8517 
8518         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8519             "ohci_parse_isoc_error: td 0x%p", (void *)td);
8520 
8521         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8522 
8523         fc = ((uint_t)Get_TD(td->hctd_ctrl) &
8524             HC_ITD_FC) >> HC_ITD_FC_SHIFT;
8525 
8526         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
8527             "ohci_parse_isoc_error: frame count %d", fc);
8528 
8529         /*
8530          * Get the address of current usb isochronous request
8531          * and array of packet descriptors.
8532          */
8533         isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
8534         isoc_pkt_descr = isoc_reqp->isoc_pkt_descr;
8535         isoc_pkt_descr += tw->tw_pkt_idx;
8536 
8537         for (i = 0; i <= fc; i++) {
8538 
8539                 psw = Get_TD(td->hctd_offsets[i / 2]);
8540 
8541                 if (toggle) {
8542                         ctrl = psw & HC_ITD_ODD_OFFSET;
8543                         toggle = 0;
8544                 } else {
8545                         ctrl =  (psw & HC_ITD_EVEN_OFFSET) <<
8546                             HC_ITD_OFFSET_SHIFT;
8547                         toggle = 1;
8548                 }
8549 
8550                 isoc_pkt_descr->isoc_pkt_actual_length =
8551                     (ctrl >> HC_ITD_OFFSET_SHIFT) & HC_ITD_OFFSET_ADDR;
8552 
8553                 ctrl = (uint_t)(ctrl & (uint32_t)HC_TD_CC);
8554 
8555                 /* Write the status of isoc data packet */
8556                 isoc_pkt_descr->isoc_pkt_status =
8557                     ohci_check_for_error(ohcip, pp, tw, td, ctrl);
8558 
8559                 if (isoc_pkt_descr->isoc_pkt_status) {
8560                         /* Increment isoc data packet error count */
8561                         isoc_reqp->isoc_error_count++;
8562                 }
8563 
8564                 /*
8565                  * Get the address of next isoc data packet descriptor.
8566                  */
8567                 isoc_pkt_descr++;
8568         }
8569         tw->tw_pkt_idx = tw->tw_pkt_idx + fc + 1;
8570 
8571         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
8572             "ohci_parse_isoc_error: tw_pkt_idx %d", tw->tw_pkt_idx);
8573 
8574 }
8575 
8576 
8577 /*
8578  * ohci_check_for_error:
8579  *
8580  * Check for any errors.
8581  */
8582 static usb_cr_t
8583 ohci_check_for_error(
8584         ohci_state_t            *ohcip,
8585         ohci_pipe_private_t     *pp,
8586         ohci_trans_wrapper_t    *tw,
8587         ohci_td_t               *td,
8588         uint_t                  ctrl)
8589 {
8590         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
8591         uchar_t                 ep_attrs = ph->p_ep.bmAttributes;
8592         usb_cr_t                error = USB_CR_OK;
8593         usb_req_attrs_t         xfer_attrs;
8594 
8595         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8596             "ohci_check_for_error: td = 0x%p ctrl = 0x%x",
8597             (void *)td, ctrl);
8598 
8599         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8600 
8601         switch (ctrl) {
8602         case HC_TD_CC_NO_E:
8603                 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8604                     "ohci_check_for_error: No Error");
8605                 error = USB_CR_OK;
8606                 break;
8607         case HC_TD_CC_CRC:
8608                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8609                     "ohci_check_for_error: CRC error");
8610                 error = USB_CR_CRC;
8611                 break;
8612         case HC_TD_CC_BS:
8613                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8614                     "ohci_check_for_error: Bit stuffing");
8615                 error = USB_CR_BITSTUFFING;
8616                 break;
8617         case HC_TD_CC_DTM:
8618                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8619                     "ohci_check_for_error: Data Toggle Mismatch");
8620                 error = USB_CR_DATA_TOGGLE_MM;
8621                 break;
8622         case HC_TD_CC_STALL:
8623                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8624                     "ohci_check_for_error: Stall");
8625                 error = USB_CR_STALL;
8626                 break;
8627         case HC_TD_CC_DNR:
8628                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8629                     "ohci_check_for_error: Device not responding");
8630                 error = USB_CR_DEV_NOT_RESP;
8631                 break;
8632         case HC_TD_CC_PCF:
8633                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8634                     "ohci_check_for_error: PID check failure");
8635                 error = USB_CR_PID_CHECKFAILURE;
8636                 break;
8637         case HC_TD_CC_UPID:
8638                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8639                     "ohci_check_for_error: Unexpected PID");
8640                 error = USB_CR_UNEXP_PID;
8641                 break;
8642         case HC_TD_CC_DO:
8643                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8644                     "ohci_check_for_error: Data overrrun");
8645                 error = USB_CR_DATA_OVERRUN;
8646                 break;
8647         case HC_TD_CC_DU:
8648                 /*
8649                  * Check whether short packets are acceptable.
8650                  * If so don't report error to client drivers
8651                  * and restart the endpoint. Otherwise report
8652                  * data underrun error to client driver.
8653                  */
8654                 xfer_attrs = ohci_get_xfer_attrs(ohcip, pp, tw);
8655 
8656                 if (xfer_attrs & USB_ATTRS_SHORT_XFER_OK) {
8657                         error = USB_CR_OK;
8658                         if ((ep_attrs & USB_EP_ATTR_MASK) !=
8659                             USB_EP_ATTR_ISOCH) {
8660                                 /*
8661                                  * Cleanup the remaining resources that may have
8662                                  * been allocated for this transfer.
8663                                  */
8664                                 if (ohci_cleanup_data_underrun(ohcip, pp, tw,
8665                                     td) == USB_SUCCESS) {
8666                                         /* Clear the halt bit */
8667                                         Set_ED(pp->pp_ept->hced_headp,
8668                                             (Get_ED(pp->pp_ept->hced_headp) &
8669                                             ~HC_EPT_Halt));
8670                                 } else {
8671                                         error = USB_CR_UNSPECIFIED_ERR;
8672                                 }
8673                         }
8674                 } else {
8675                         USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8676                             "ohci_check_for_error: Data underrun");
8677 
8678                         error = USB_CR_DATA_UNDERRUN;
8679                 }
8680 
8681                 break;
8682         case HC_TD_CC_BO:
8683                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8684                     "ohci_check_for_error: Buffer overrun");
8685                 error = USB_CR_BUFFER_OVERRUN;
8686                 break;
8687         case HC_TD_CC_BU:
8688                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8689                     "ohci_check_for_error: Buffer underrun");
8690                 error = USB_CR_BUFFER_UNDERRUN;
8691                 break;
8692         case HC_TD_CC_NA:
8693         default:
8694                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8695                     "ohci_check_for_error: Not accessed");
8696                 error = USB_CR_NOT_ACCESSED;
8697                 break;
8698         }
8699 
8700         if (error) {
8701                 uint_t hced_ctrl =  Get_ED(pp->pp_ept->hced_ctrl);
8702 
8703                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8704                     "ohci_check_for_error: Error %d Device address %d "
8705                     "Endpoint number %d", error, (hced_ctrl & HC_EPT_FUNC),
8706                     ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT));
8707         }
8708 
8709         return (error);
8710 }
8711 
8712 
8713 /*
8714  * ohci_handle_error:
8715  *
8716  * Inform USBA about occured transaction errors by calling the USBA callback
8717  * routine.
8718  */
8719 static void
8720 ohci_handle_error(
8721         ohci_state_t            *ohcip,
8722         ohci_td_t               *td,
8723         usb_cr_t                error)
8724 {
8725         ohci_trans_wrapper_t    *tw;
8726         usba_pipe_handle_data_t *ph;
8727         ohci_pipe_private_t     *pp;
8728         mblk_t                  *mp = NULL;
8729         size_t                  length = 0;
8730         uchar_t                 attributes;
8731         usb_intr_req_t          *curr_intr_reqp;
8732 
8733         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8734             "ohci_handle_error: error = 0x%x", error);
8735 
8736         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8737 
8738         ASSERT(td != NULL);
8739 
8740         /* Print the values in the td */
8741         ohci_print_td(ohcip, td);
8742 
8743         /* Obtain the transfer wrapper from the TD */
8744         tw = (ohci_trans_wrapper_t *)
8745             OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper));
8746 
8747         ASSERT(tw != NULL);
8748 
8749         /* Obtain the pipe private structure */
8750         pp = tw->tw_pipe_private;
8751 
8752         ph = tw->tw_pipe_private->pp_pipe_handle;
8753         attributes = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
8754 
8755         /*
8756          * Special error handling
8757          */
8758         if (tw->tw_direction == HC_TD_IN) {
8759 
8760                 switch (attributes) {
8761                 case USB_EP_ATTR_CONTROL:
8762                         if (((ph->p_ep.bmAttributes &
8763                             USB_EP_ATTR_MASK) ==
8764                             USB_EP_ATTR_CONTROL) &&
8765                             (Get_TD(td->hctd_ctrl_phase) ==
8766                             OHCI_CTRL_SETUP_PHASE)) {
8767 
8768                                 break;
8769                         }
8770                         /* FALLTHROUGH */
8771                 case USB_EP_ATTR_BULK:
8772                         /*
8773                          * Call ohci_sendup_td_message
8774                          * to send message to upstream.
8775                          */
8776                         ohci_sendup_td_message(ohcip, pp, tw, td, error);
8777 
8778                         return;
8779                 case USB_EP_ATTR_INTR:
8780                         curr_intr_reqp =
8781                             (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
8782 
8783                         if (curr_intr_reqp->intr_attributes &
8784                             USB_ATTRS_ONE_XFER) {
8785 
8786                                 ohci_handle_one_xfer_completion(ohcip, tw);
8787                         }
8788 
8789                         /* Decrement periodic in request count */
8790                         pp->pp_cur_periodic_req_cnt--;
8791                         break;
8792                 case USB_EP_ATTR_ISOCH:
8793                 default:
8794                         break;
8795                 }
8796         } else {
8797                 switch (attributes) {
8798                 case USB_EP_ATTR_BULK:
8799                 case USB_EP_ATTR_INTR:
8800                         /*
8801                          * If "CurrentBufferPointer" of Transfer
8802                          * Descriptor (TD) is not equal to zero,
8803                          * then we sent less data  to the device
8804                          * than requested by client. In that case,
8805                          * return the mblk after updating the
8806                          * data->r_ptr.
8807                          */
8808                         if (Get_TD(td->hctd_cbp)) {
8809                                 usb_opaque_t xfer_reqp = tw->tw_curr_xfer_reqp;
8810                                 size_t residue;
8811 
8812                                 residue = ohci_get_td_residue(ohcip, td);
8813                                 length = Get_TD(td->hctd_xfer_offs) +
8814                                     Get_TD(td->hctd_xfer_len) - residue;
8815 
8816                                 USB_DPRINTF_L2(PRINT_MASK_INTR,
8817                                     ohcip->ohci_log_hdl,
8818                                     "ohci_handle_error: requested data %lu "
8819                                     "sent data %lu", tw->tw_length, length);
8820 
8821                                 if (attributes == USB_EP_ATTR_BULK) {
8822                                         mp = (mblk_t *)((usb_bulk_req_t *)
8823                                             (xfer_reqp))->bulk_data;
8824                                 } else {
8825                                         mp = (mblk_t *)((usb_intr_req_t *)
8826                                             (xfer_reqp))->intr_data;
8827                                 }
8828 
8829                                 /* Increment the read pointer */
8830                                 mp->b_rptr = mp->b_rptr + length;
8831                         }
8832                         break;
8833                 default:
8834                         break;
8835                 }
8836         }
8837 
8838         /*
8839          * Callback the client with the
8840          * failure reason.
8841          */
8842         ohci_hcdi_callback(ph, tw, error);
8843 
8844         /* Check anybody is waiting for transfers completion event */
8845         ohci_check_for_transfers_completion(ohcip, pp);
8846 }
8847 
8848 /*
8849  * ohci_cleanup_data_underrun:
8850  *
8851  * Cleans up resources when a short xfer occurs
8852  */
8853 static int
8854 ohci_cleanup_data_underrun(
8855         ohci_state_t            *ohcip,
8856         ohci_pipe_private_t     *pp,
8857         ohci_trans_wrapper_t    *tw,
8858         ohci_td_t               *td)
8859 {
8860         ohci_td_t               *next_td;
8861         ohci_td_t               *last_td;
8862         ohci_td_t               *temp_td;
8863         uint32_t                last_td_addr;
8864         uint_t                  hced_head;
8865 
8866         USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8867             "ohci_cleanup_data_underrun: td 0x%p, tw 0x%p",
8868             (void *)td, (void *)tw);
8869 
8870         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8871         ASSERT(tw->tw_hctd_head == td);
8872 
8873         /* Check if this TD is the last td in the tw */
8874         last_td = tw->tw_hctd_tail;
8875         if (td == last_td) {
8876                 /* There is no need for cleanup */
8877                 return (USB_SUCCESS);
8878         }
8879 
8880         /*
8881          * Make sure the ED is halted before we change any td's.
8882          * If for some reason it is not halted, return error to client
8883          * driver so they can reset the port.
8884          */
8885         hced_head = Get_ED(pp->pp_ept->hced_headp);
8886         if (!(hced_head & HC_EPT_Halt)) {
8887                 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl);
8888 
8889                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8890                     "ohci_cleanup_data_underrun: Unable to clean up a short "
8891                     "xfer error.  Client might send/receive irrelevant data."
8892                     " Device address %d Endpoint number %d",
8893                     (hced_ctrl & HC_EPT_FUNC),
8894                     ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT));
8895 
8896                 Set_ED(pp->pp_ept->hced_headp, hced_head | HC_EPT_Halt);
8897 
8898                 return (USB_FAILURE);
8899         }
8900 
8901         /*
8902          * Get the address of the first td of the next transfer (tw).
8903          * This td, may currently be a dummy td, but when a new request
8904          * arrives, it will be transformed into a regular td.
8905          */
8906         last_td_addr = Get_TD(last_td->hctd_next_td);
8907         /* Set ED head to this last td */
8908         Set_ED(pp->pp_ept->hced_headp,
8909             (last_td_addr & HC_EPT_TD_HEAD) |
8910             (hced_head & ~HC_EPT_TD_HEAD));
8911 
8912         /*
8913          * Start removing all the unused TD's from the TW,
8914          * but keep the first one.
8915          */
8916         tw->tw_hctd_tail = td;
8917 
8918         /*
8919          * Get the last_td, the next td in the tw list.
8920          * Afterwards completely disassociate the current td from other tds
8921          */
8922         next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip,
8923             Get_TD(td->hctd_tw_next_td));
8924         Set_TD(td->hctd_tw_next_td, NULL);
8925 
8926         /*
8927          * Iterate down the tw list and deallocate them
8928          */
8929         while (next_td != NULL) {
8930                 tw->tw_num_tds--;
8931                 /* Disassociate this td from it's TW and set to RECLAIM */
8932                 Set_TD(next_td->hctd_trans_wrapper, NULL);
8933                 Set_TD(next_td->hctd_state, HC_TD_RECLAIM);
8934 
8935                 temp_td = next_td;
8936 
8937                 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip,
8938                     Get_TD(next_td->hctd_tw_next_td));
8939 
8940                 ohci_deallocate_td(ohcip, temp_td);
8941         }
8942 
8943         ASSERT(tw->tw_num_tds == 1);
8944 
8945         return (USB_SUCCESS);
8946 }
8947 
8948 /*
8949  * ohci_handle_normal_td:
8950  */
8951 static void
8952 ohci_handle_normal_td(
8953         ohci_state_t            *ohcip,
8954         ohci_td_t               *td,
8955         ohci_trans_wrapper_t    *tw)
8956 {
8957         ohci_pipe_private_t     *pp;    /* Pipe private field */
8958 
8959         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8960             "ohci_handle_normal_td:");
8961 
8962         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8963         ASSERT(tw != NULL);
8964 
8965         /* Obtain the pipe private structure */
8966         pp = tw->tw_pipe_private;
8967 
8968         (*tw->tw_handle_td)(ohcip, pp, tw,
8969             td, tw->tw_handle_callback_value);
8970 
8971         /* Check anybody is waiting for transfers completion event */
8972         ohci_check_for_transfers_completion(ohcip, pp);
8973 }
8974 
8975 
8976 /*
8977  * ohci_handle_ctrl_td:
8978  *
8979  * Handle a control Transfer Descriptor (TD).
8980  */
8981 /* ARGSUSED */
8982 static void
8983 ohci_handle_ctrl_td(
8984         ohci_state_t            *ohcip,
8985         ohci_pipe_private_t     *pp,
8986         ohci_trans_wrapper_t    *tw,
8987         ohci_td_t               *td,
8988         void                    *tw_handle_callback_value)
8989 {
8990         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
8991 
8992         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8993             "ohci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p state = 0x%x",
8994             (void *)pp, (void *)tw, (void *)td, Get_TD(td->hctd_ctrl_phase));
8995 
8996         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8997 
8998         /*
8999          * Check which control transfer phase got completed.
9000          */
9001         tw->tw_num_tds--;
9002         switch (Get_TD(td->hctd_ctrl_phase)) {
9003         case OHCI_CTRL_SETUP_PHASE:
9004                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9005                     "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
9006 
9007                 break;
9008         case OHCI_CTRL_DATA_PHASE:
9009                 /*
9010                  * If "CurrentBufferPointer" of Transfer Descriptor (TD)
9011                  * is not equal to zero, then we received less data from
9012                  * the device than requested by us. In that case, get the
9013                  * actual received data size.
9014                  */
9015                 if (Get_TD(td->hctd_cbp)) {
9016                         size_t                  length, residue;
9017 
9018                         residue = ohci_get_td_residue(ohcip, td);
9019                         length = Get_TD(td->hctd_xfer_offs) +
9020                             Get_TD(td->hctd_xfer_len) - residue;
9021 
9022                         USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9023                             "ohci_handle_ctrl_qtd: requested data %lu "
9024                             "received data %lu", tw->tw_length, length);
9025 
9026                         /* Save actual received data length */
9027                         tw->tw_length = length;
9028                 }
9029 
9030                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9031                     "Data complete: pp 0x%p td 0x%p",
9032                     (void *)pp, (void *)td);
9033 
9034                 break;
9035         case OHCI_CTRL_STATUS_PHASE:
9036                 if ((tw->tw_length != 0) &&
9037                     (tw->tw_direction == HC_TD_IN)) {
9038 
9039                         /*
9040                          * Call ohci_sendup_td_message
9041                          * to send message to upstream.
9042                          */
9043                         ohci_sendup_td_message(ohcip,
9044                             pp, tw, td, USB_CR_OK);
9045                 } else {
9046                         ohci_do_byte_stats(ohcip,
9047                             tw->tw_length - OHCI_MAX_TD_BUF_SIZE,
9048                             ph->p_ep.bmAttributes,
9049                             ph->p_ep.bEndpointAddress);
9050 
9051                         ohci_hcdi_callback(ph, tw, USB_CR_OK);
9052                 }
9053 
9054                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9055                     "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
9056 
9057                 break;
9058         }
9059 }
9060 
9061 
9062 /*
9063  * ohci_handle_bulk_td:
9064  *
9065  * Handle a bulk Transfer Descriptor (TD).
9066  */
9067 /* ARGSUSED */
9068 static void
9069 ohci_handle_bulk_td(
9070         ohci_state_t            *ohcip,
9071         ohci_pipe_private_t     *pp,
9072         ohci_trans_wrapper_t    *tw,
9073         ohci_td_t               *td,
9074         void                    *tw_handle_callback_value)
9075 {
9076         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9077         usb_ep_descr_t          *eptd = &ph->p_ep;
9078 
9079         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9080             "ohci_handle_bulk_td:");
9081 
9082         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9083 
9084         /*
9085          * Decrement the TDs counter and check whether all the bulk
9086          * data has been send or received. If TDs counter reaches
9087          * zero then inform client driver about completion current
9088          * bulk request. Other wise wait for completion of other bulk
9089          * TDs or transactions on this pipe.
9090          */
9091         if (--tw->tw_num_tds != 0) {
9092 
9093                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9094                     "ohci_handle_bulk_td: Number of TDs %d", tw->tw_num_tds);
9095 
9096                 return;
9097         }
9098 
9099         /*
9100          * If this is a bulk in pipe, return the data to the client.
9101          * For a bulk out pipe, there is no need to do anything.
9102          */
9103         if ((eptd->bEndpointAddress &
9104             USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9105 
9106                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9107                     "ohci_handle_bulk_td: Bulk out pipe");
9108 
9109                 ohci_do_byte_stats(ohcip, tw->tw_length,
9110                     eptd->bmAttributes, eptd->bEndpointAddress);
9111 
9112                 /* Do the callback */
9113                 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9114 
9115                 return;
9116         }
9117 
9118         /* Call ohci_sendup_td_message to send message to upstream */
9119         ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9120 }
9121 
9122 
9123 /*
9124  * ohci_handle_intr_td:
9125  *
9126  * Handle a interrupt Transfer Descriptor (TD).
9127  */
9128 /* ARGSUSED */
9129 static void
9130 ohci_handle_intr_td(
9131         ohci_state_t            *ohcip,
9132         ohci_pipe_private_t     *pp,
9133         ohci_trans_wrapper_t    *tw,
9134         ohci_td_t               *td,
9135         void                    *tw_handle_callback_value)
9136 {
9137         usb_intr_req_t          *curr_intr_reqp =
9138             (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9139         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9140         usb_ep_descr_t          *eptd = &ph->p_ep;
9141         usb_req_attrs_t         attrs;
9142         int                     error = USB_SUCCESS;
9143 
9144         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9145             "ohci_handle_intr_td: pp=0x%p tw=0x%p td=0x%p"
9146             "intr_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td,
9147             (void *)curr_intr_reqp, (void *)curr_intr_reqp->intr_data);
9148 
9149         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9150 
9151         /* Get the interrupt xfer attributes */
9152         attrs = curr_intr_reqp->intr_attributes;
9153 
9154         /*
9155          * For a Interrupt OUT pipe, we just callback and we are done
9156          */
9157         if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9158 
9159                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9160                     "ohci_handle_intr_td: Intr out pipe, intr_reqp=0x%p,"
9161                     "data=0x%p", (void *)curr_intr_reqp,
9162                     (void *)curr_intr_reqp->intr_data);
9163 
9164                 ohci_do_byte_stats(ohcip, tw->tw_length,
9165                     eptd->bmAttributes, eptd->bEndpointAddress);
9166 
9167                 /* Do the callback */
9168                 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9169 
9170                 return;
9171         }
9172 
9173         /* Decrement number of interrupt request count */
9174         pp->pp_cur_periodic_req_cnt--;
9175 
9176         /*
9177          * Check usb flag whether USB_FLAGS_ONE_XFER flag is set
9178          * and if so, free duplicate request.
9179          */
9180         if (attrs & USB_ATTRS_ONE_XFER) {
9181                 ohci_handle_one_xfer_completion(ohcip, tw);
9182         }
9183 
9184         /* Call ohci_sendup_td_message to callback into client */
9185         ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9186 
9187         /*
9188          * If interrupt pipe state is still active, insert next Interrupt
9189          * request into the Host Controller's Interrupt list.  Otherwise
9190          * you are done.
9191          */
9192         if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
9193                 return;
9194         }
9195 
9196         if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) ==
9197             USB_SUCCESS) {
9198                 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9199 
9200                 ASSERT(curr_intr_reqp != NULL);
9201 
9202                 tw->tw_num_tds = 1;
9203 
9204                 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) {
9205                         ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9206                         error = USB_FAILURE;
9207                 } else if (ohci_allocate_tds_for_tw(ohcip, tw,
9208                     tw->tw_num_tds) != USB_SUCCESS) {
9209                         ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9210                         error = USB_FAILURE;
9211                 }
9212         }
9213 
9214         if (error != USB_SUCCESS) {
9215                 /*
9216                  * Set pipe state to stop polling and error to no
9217                  * resource. Don't insert any more interrupt polling
9218                  * requests.
9219                  */
9220                 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
9221                 pp->pp_error = USB_CR_NO_RESOURCES;
9222         } else {
9223                 ohci_insert_intr_req(ohcip, pp, tw, 0);
9224 
9225                 /* Increment number of interrupt request count */
9226                 pp->pp_cur_periodic_req_cnt++;
9227 
9228                 ASSERT(pp->pp_cur_periodic_req_cnt ==
9229                     pp->pp_max_periodic_req_cnt);
9230         }
9231 }
9232 
9233 
9234 /*
9235  * ohci_handle_one_xfer_completion:
9236  */
9237 static void
9238 ohci_handle_one_xfer_completion(
9239         ohci_state_t            *ohcip,
9240         ohci_trans_wrapper_t    *tw)
9241 {
9242         usba_pipe_handle_data_t *ph = tw->tw_pipe_private->pp_pipe_handle;
9243         ohci_pipe_private_t     *pp = tw->tw_pipe_private;
9244         usb_intr_req_t          *curr_intr_reqp =
9245             (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9246 
9247         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9248             "ohci_handle_one_xfer_completion: tw = 0x%p", (void *)tw);
9249 
9250         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9251         ASSERT(curr_intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER);
9252 
9253         pp->pp_state = OHCI_PIPE_STATE_IDLE;
9254 
9255         /*
9256          * For one xfer, we need to copy back data ptr
9257          * and free current request
9258          */
9259         ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))->
9260             intr_data = ((usb_intr_req_t *)
9261             (tw->tw_curr_xfer_reqp))->intr_data;
9262 
9263         ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL;
9264 
9265         /* Now free duplicate current request */
9266         usb_free_intr_req((usb_intr_req_t *)tw-> tw_curr_xfer_reqp);
9267 
9268         mutex_enter(&ph->p_mutex);
9269         ph->p_req_count--;
9270         mutex_exit(&ph->p_mutex);
9271 
9272         /* Make client's request the current request */
9273         tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp;
9274         pp->pp_client_periodic_in_reqp = NULL;
9275 }
9276 
9277 
9278 /*
9279  * ohci_handle_isoc_td:
9280  *
9281  * Handle an isochronous Transfer Descriptor (TD).
9282  */
9283 /* ARGSUSED */
9284 static void
9285 ohci_handle_isoc_td(
9286         ohci_state_t            *ohcip,
9287         ohci_pipe_private_t     *pp,
9288         ohci_trans_wrapper_t    *tw,
9289         ohci_td_t               *td,
9290         void                    *tw_handle_callback_value)
9291 {
9292         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9293         usb_ep_descr_t          *eptd = &ph->p_ep;
9294         usb_isoc_req_t          *curr_isoc_reqp =
9295             (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
9296         int                     error = USB_SUCCESS;
9297 
9298         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9299             "ohci_handle_isoc_td: pp=0x%p tw=0x%p td=0x%p"
9300             "isoc_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td,
9301             (void *)curr_isoc_reqp, (void *)curr_isoc_reqp->isoc_data);
9302 
9303         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9304 
9305         /*
9306          * Decrement the TDs counter and check whether all the isoc
9307          * data has been send or received. If TDs counter reaches
9308          * zero then inform client driver about completion current
9309          * isoc request. Otherwise wait for completion of other isoc
9310          * TDs or transactions on this pipe.
9311          */
9312         if (--tw->tw_num_tds != 0) {
9313 
9314                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9315                     "ohci_handle_isoc_td: Number of TDs %d", tw->tw_num_tds);
9316 
9317                 return;
9318         }
9319 
9320         /*
9321          * If this is a isoc in pipe, return the data to the client.
9322          * For a isoc out pipe, there is no need to do anything.
9323          */
9324         if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9325                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9326                     "ohci_handle_isoc_td: Isoc out pipe, isoc_reqp=0x%p,"
9327                     "data=0x%p", (void *)curr_isoc_reqp,
9328                     (void *)curr_isoc_reqp->isoc_data);
9329 
9330                 ohci_do_byte_stats(ohcip, tw->tw_length,
9331                     eptd->bmAttributes, eptd->bEndpointAddress);
9332 
9333                 /* Do the callback */
9334                 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9335 
9336                 return;
9337         }
9338 
9339         /* Decrement number of IN isochronous request count */
9340         pp->pp_cur_periodic_req_cnt--;
9341 
9342         /* Call ohci_sendup_td_message to send message to upstream */
9343         ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9344 
9345         /*
9346          * If isochronous pipe state is still active, insert next isochronous
9347          * request into the Host Controller's isochronous list.
9348          */
9349         if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
9350                 return;
9351         }
9352 
9353         if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) ==
9354             USB_SUCCESS) {
9355                 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
9356 
9357                 ASSERT(curr_isoc_reqp != NULL);
9358 
9359                 tw->tw_num_tds =
9360                     curr_isoc_reqp->isoc_pkts_count / OHCI_ISOC_PKTS_PER_TD;
9361                 if (curr_isoc_reqp->isoc_pkts_count % OHCI_ISOC_PKTS_PER_TD) {
9362                         tw->tw_num_tds++;
9363                 }
9364 
9365                 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) {
9366                         ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9367                         error = USB_FAILURE;
9368                 } else if (ohci_allocate_tds_for_tw(ohcip, tw,
9369                     tw->tw_num_tds) != USB_SUCCESS) {
9370                         ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9371                         error = USB_FAILURE;
9372                 }
9373         }
9374 
9375         if (error != USB_SUCCESS ||
9376             ohci_insert_isoc_req(ohcip, pp, tw, 0) != USB_SUCCESS) {
9377                 /*
9378                  * Set pipe state to stop polling and error to no
9379                  * resource. Don't insert any more isoch polling
9380                  * requests.
9381                  */
9382                 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
9383                 pp->pp_error = USB_CR_NO_RESOURCES;
9384 
9385         } else {
9386                 /* Increment number of IN isochronous request count */
9387                 pp->pp_cur_periodic_req_cnt++;
9388 
9389                 ASSERT(pp->pp_cur_periodic_req_cnt ==
9390                     pp->pp_max_periodic_req_cnt);
9391         }
9392 }
9393 
9394 
9395 /*
9396  * ohci_tw_rebind_cookie:
9397  *
9398  * If the cookie associated with a DMA buffer has been walked, the cookie
9399  * is not usable any longer. To reuse the DMA buffer, the DMA handle needs
9400  * to rebind for cookies.
9401  */
9402 static int
9403 ohci_tw_rebind_cookie(
9404         ohci_state_t            *ohcip,
9405         ohci_pipe_private_t     *pp,
9406         ohci_trans_wrapper_t    *tw)
9407 {
9408         usb_ep_descr_t          *eptd = &pp->pp_pipe_handle->p_ep;
9409         int                     rval, i;
9410         uint_t                  ccount;
9411 
9412         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9413             "ohci_tw_rebind_cookie:");
9414 
9415         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9416 
9417         if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
9418                 ASSERT(tw->tw_num_tds == tw->tw_ncookies);
9419 
9420                 for (i = 0; i < tw->tw_num_tds; i++) {
9421                         if (tw->tw_isoc_bufs[i].ncookies == 1) {
9422 
9423                                 /*
9424                                  * no need to rebind when there is
9425                                  * only one cookie in a buffer
9426                                  */
9427                                 continue;
9428                         }
9429 
9430                         /* unbind the DMA handle before rebinding */
9431                         rval = ddi_dma_unbind_handle(
9432                             tw->tw_isoc_bufs[i].dma_handle);
9433                         ASSERT(rval == USB_SUCCESS);
9434                         tw->tw_isoc_bufs[i].ncookies = 0;
9435 
9436                         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9437                             "rebind dma_handle %d", i);
9438 
9439                         /* rebind the handle to get cookies */
9440                         rval = ddi_dma_addr_bind_handle(
9441                             tw->tw_isoc_bufs[i].dma_handle, NULL,
9442                             (caddr_t)tw->tw_isoc_bufs[i].buf_addr,
9443                             tw->tw_isoc_bufs[i].length,
9444                             DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
9445                             DDI_DMA_DONTWAIT, NULL,
9446                             &tw->tw_isoc_bufs[i].cookie, &ccount);
9447 
9448                         if ((rval == DDI_DMA_MAPPED) &&
9449                             (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) {
9450                                 tw->tw_isoc_bufs[i].ncookies = ccount;
9451                         } else {
9452 
9453                                 return (USB_NO_RESOURCES);
9454                         }
9455                 }
9456         } else {
9457                 if (tw->tw_cookie_idx != 0) {
9458                         /* unbind the DMA handle before rebinding */
9459                         rval = ddi_dma_unbind_handle(tw->tw_dmahandle);
9460                         ASSERT(rval == DDI_SUCCESS);
9461                         tw->tw_ncookies = 0;
9462 
9463                         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9464                             "rebind dma_handle");
9465 
9466                         /* rebind the handle to get cookies */
9467                         rval = ddi_dma_addr_bind_handle(
9468                             tw->tw_dmahandle, NULL,
9469                             (caddr_t)tw->tw_buf, tw->tw_length,
9470                             DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
9471                             DDI_DMA_DONTWAIT, NULL,
9472                             &tw->tw_cookie, &ccount);
9473 
9474                         if (rval == DDI_DMA_MAPPED) {
9475                                 tw->tw_ncookies = ccount;
9476                                 tw->tw_dma_offs = 0;
9477                                 tw->tw_cookie_idx = 0;
9478                         } else {
9479 
9480                                 return (USB_NO_RESOURCES);
9481                         }
9482                 }
9483         }
9484 
9485         return (USB_SUCCESS);
9486 }
9487 
9488 
9489 /*
9490  * ohci_sendup_td_message:
9491  *      copy data, if necessary and do callback
9492  */
9493 static void
9494 ohci_sendup_td_message(
9495         ohci_state_t            *ohcip,
9496         ohci_pipe_private_t     *pp,
9497         ohci_trans_wrapper_t    *tw,
9498         ohci_td_t               *td,
9499         usb_cr_t                error)
9500 {
9501         usb_ep_descr_t          *eptd = &pp->pp_pipe_handle->p_ep;
9502         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9503         size_t                  length = 0, skip_len = 0, residue;
9504         mblk_t                  *mp;
9505         uchar_t                 *buf;
9506         usb_opaque_t            curr_xfer_reqp = tw->tw_curr_xfer_reqp;
9507 
9508         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9509 
9510         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9511             "ohci_sendup_td_message:");
9512 
9513         ASSERT(tw != NULL);
9514 
9515         length = tw->tw_length;
9516 
9517         switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
9518         case USB_EP_ATTR_CONTROL:
9519                 /*
9520                  * Get the correct length, adjust it for the setup size
9521                  * which is not part of the data length in control end
9522                  * points.  Update tw->tw_length for future references.
9523                  */
9524                 if (((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_wLength) {
9525                         tw->tw_length = length = length - OHCI_MAX_TD_BUF_SIZE;
9526                 } else {
9527                         tw->tw_length = length = length - SETUP_SIZE;
9528                 }
9529 
9530                 /* Set the length of the buffer to skip */
9531                 skip_len = OHCI_MAX_TD_BUF_SIZE;
9532 
9533                 if (Get_TD(td->hctd_ctrl_phase) != OHCI_CTRL_DATA_PHASE) {
9534                         break;
9535                 }
9536                 /* FALLTHRU */
9537         case USB_EP_ATTR_BULK:
9538         case USB_EP_ATTR_INTR:
9539                 /*
9540                  * If error is "data overrun", do not check for the
9541                  * "CurrentBufferPointer"  and return whatever data
9542                  * received to the client driver.
9543                  */
9544                 if (error == USB_CR_DATA_OVERRUN) {
9545                         break;
9546                 }
9547 
9548                 /*
9549                  * If "CurrentBufferPointer" of Transfer Descriptor
9550                  * (TD) is not equal to zero, then we received less
9551                  * data from the device than requested by us. In that
9552                  * case, get the actual received data size.
9553                  */
9554                 if (Get_TD(td->hctd_cbp)) {
9555                         residue = ohci_get_td_residue(ohcip, td);
9556                         length = Get_TD(td->hctd_xfer_offs) +
9557                             Get_TD(td->hctd_xfer_len) - residue - skip_len;
9558 
9559                         USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9560                             "ohci_sendup_qtd_message: requested data %lu "
9561                             "received data %lu", tw->tw_length, length);
9562                 }
9563 
9564                 break;
9565         case USB_EP_ATTR_ISOCH:
9566         default:
9567                 break;
9568         }
9569 
9570         /* Copy the data into the mblk_t */
9571         buf = (uchar_t *)tw->tw_buf + skip_len;
9572 
9573         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9574             "ohci_sendup_qtd_message: length %lu error %d", length, error);
9575 
9576         /* Get the message block */
9577         switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
9578         case USB_EP_ATTR_CONTROL:
9579                 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data;
9580                 break;
9581         case USB_EP_ATTR_BULK:
9582                 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data;
9583                 break;
9584         case USB_EP_ATTR_INTR:
9585                 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data;
9586                 break;
9587         case USB_EP_ATTR_ISOCH:
9588                 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data;
9589                 break;
9590         }
9591 
9592         ASSERT(mp != NULL);
9593 
9594         if (length) {
9595                 int i;
9596                 uchar_t *p = mp->b_rptr;
9597 
9598                 /*
9599                  * Update kstat byte counts
9600                  * The control endpoints don't have direction bits so in
9601                  * order for control stats to be counted correctly an in
9602                  * bit must be faked on a control read.
9603                  */
9604                 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
9605                     USB_EP_ATTR_CONTROL) {
9606                         ohci_do_byte_stats(ohcip, length,
9607                             eptd->bmAttributes, USB_EP_DIR_IN);
9608                 } else {
9609                         ohci_do_byte_stats(ohcip, length,
9610                             eptd->bmAttributes, eptd->bEndpointAddress);
9611                 }
9612 
9613                 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
9614                     USB_EP_ATTR_ISOCH) {
9615                         for (i = 0; i < tw->tw_ncookies; i++) {
9616                                 Sync_IO_Buffer(
9617                                     tw->tw_isoc_bufs[i].dma_handle,
9618                                     tw->tw_isoc_bufs[i].length);
9619 
9620                                 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle,
9621                                     p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr,
9622                                     tw->tw_isoc_bufs[i].length,
9623                                     DDI_DEV_AUTOINCR);
9624                                 p += tw->tw_isoc_bufs[i].length;
9625                         }
9626                         tw->tw_pkt_idx = 0;
9627                 } else {
9628                         /* Sync IO buffer */
9629                         Sync_IO_Buffer(tw->tw_dmahandle, (skip_len + length));
9630 
9631                         /* Copy the data into the message */
9632                         ddi_rep_get8(tw->tw_accesshandle,
9633                             mp->b_rptr, buf, length, DDI_DEV_AUTOINCR);
9634                 }
9635 
9636                 /* Increment the write pointer */
9637                 mp->b_wptr = mp->b_wptr + length;
9638         } else {
9639                 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9640                     "ohci_sendup_td_message: Zero length packet");
9641         }
9642 
9643         ohci_hcdi_callback(ph, tw, error);
9644 }
9645 
9646 
9647 /*
9648  * ohci_get_td_residue:
9649  *
9650  * Calculate the bytes not transfered by the TD
9651  */
9652 size_t
9653 ohci_get_td_residue(
9654         ohci_state_t    *ohcip,
9655         ohci_td_t       *td)
9656 {
9657         uint32_t        buf_addr, end_addr;
9658         size_t          residue;
9659 
9660         buf_addr = Get_TD(td->hctd_cbp);
9661         end_addr = Get_TD(td->hctd_buf_end);
9662 
9663         if ((buf_addr & 0xfffff000) ==
9664             (end_addr & 0xfffff000)) {
9665                 residue = end_addr - buf_addr + 1;
9666         } else {
9667                 residue = OHCI_MAX_TD_BUF_SIZE -
9668                     (buf_addr & 0x00000fff) +
9669                     (end_addr & 0x00000fff) + 1;
9670         }
9671 
9672         return (residue);
9673 }
9674 
9675 
9676 /*
9677  * Miscellaneous functions
9678  */
9679 
9680 /*
9681  * ohci_obtain_state:
9682  * NOTE: This function is also called from POLLED MODE.
9683  */
9684 ohci_state_t *
9685 ohci_obtain_state(dev_info_t    *dip)
9686 {
9687         int                     instance = ddi_get_instance(dip);
9688         ohci_state_t            *state = ddi_get_soft_state(
9689             ohci_statep, instance);
9690 
9691         ASSERT(state != NULL);
9692 
9693         return (state);
9694 }
9695 
9696 
9697 /*
9698  * ohci_state_is_operational:
9699  *
9700  * Check the Host controller state and return proper values.
9701  */
9702 int
9703 ohci_state_is_operational(ohci_state_t  *ohcip)
9704 {
9705         int                             val;
9706 
9707         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9708 
9709         switch (ohcip->ohci_hc_soft_state) {
9710         case OHCI_CTLR_INIT_STATE:
9711         case OHCI_CTLR_SUSPEND_STATE:
9712                 val = USB_FAILURE;
9713                 break;
9714         case OHCI_CTLR_OPERATIONAL_STATE:
9715                 val = USB_SUCCESS;
9716                 break;
9717         case OHCI_CTLR_ERROR_STATE:
9718                 val = USB_HC_HARDWARE_ERROR;
9719                 break;
9720         default:
9721                 val = USB_FAILURE;
9722                 break;
9723         }
9724 
9725         return (val);
9726 }
9727 
9728 
9729 /*
9730  * ohci_do_soft_reset
9731  *
9732  * Do soft reset of ohci host controller.
9733  */
9734 int
9735 ohci_do_soft_reset(ohci_state_t *ohcip)
9736 {
9737         usb_frame_number_t      before_frame_number, after_frame_number;
9738         timeout_id_t            xfer_timer_id, rh_timer_id;
9739         ohci_regs_t             *ohci_save_regs;
9740         ohci_td_t               *done_head;
9741 
9742         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9743 
9744         /* Increment host controller error count */
9745         ohcip->ohci_hc_error++;
9746 
9747         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9748             "ohci_do_soft_reset:"
9749             "Reset ohci host controller 0x%x", ohcip->ohci_hc_error);
9750 
9751         /*
9752          * Allocate space for saving current Host Controller
9753          * registers. Don't do any recovery if allocation
9754          * fails.
9755          */
9756         ohci_save_regs = (ohci_regs_t *)
9757             kmem_zalloc(sizeof (ohci_regs_t), KM_NOSLEEP);
9758 
9759         if (ohci_save_regs == NULL) {
9760                 USB_DPRINTF_L2(PRINT_MASK_INTR,  ohcip->ohci_log_hdl,
9761                     "ohci_do_soft_reset: kmem_zalloc failed");
9762 
9763                 return (USB_FAILURE);
9764         }
9765 
9766         /* Save current ohci registers */
9767         ohci_save_regs->hcr_control = Get_OpReg(hcr_control);
9768         ohci_save_regs->hcr_cmd_status = Get_OpReg(hcr_cmd_status);
9769         ohci_save_regs->hcr_intr_enable = Get_OpReg(hcr_intr_enable);
9770         ohci_save_regs->hcr_periodic_strt = Get_OpReg(hcr_periodic_strt);
9771         ohci_save_regs->hcr_frame_interval = Get_OpReg(hcr_frame_interval);
9772         ohci_save_regs->hcr_HCCA = Get_OpReg(hcr_HCCA);
9773         ohci_save_regs->hcr_bulk_head = Get_OpReg(hcr_bulk_head);
9774         ohci_save_regs->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head);
9775 
9776         USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9777             "ohci_do_soft_reset: Save reg = 0x%p", (void *)ohci_save_regs);
9778 
9779         /* Disable all list processing and interrupts */
9780         Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
9781             HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
9782 
9783         Set_OpReg(hcr_intr_disable, HCR_INTR_SO |
9784             HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE |
9785             HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE);
9786 
9787         /* Wait for few milliseconds */
9788         drv_usecwait(OHCI_TIMEWAIT);
9789 
9790         /* Root hub interrupt pipe timeout id */
9791         rh_timer_id = ohcip->ohci_root_hub.rh_intr_pipe_timer_id;
9792 
9793         /* Stop the root hub interrupt timer */
9794         if (rh_timer_id) {
9795                 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 0;
9796                 ohcip->ohci_root_hub.rh_intr_pipe_state =
9797                     OHCI_PIPE_STATE_IDLE;
9798 
9799                 mutex_exit(&ohcip->ohci_int_mutex);
9800                 (void) untimeout(rh_timer_id);
9801                 mutex_enter(&ohcip->ohci_int_mutex);
9802         }
9803 
9804         /* Transfer timeout id */
9805         xfer_timer_id = ohcip->ohci_timer_id;
9806 
9807         /* Stop the global transfer timer */
9808         if (xfer_timer_id) {
9809                 ohcip->ohci_timer_id = 0;
9810                 mutex_exit(&ohcip->ohci_int_mutex);
9811                 (void) untimeout(xfer_timer_id);
9812                 mutex_enter(&ohcip->ohci_int_mutex);
9813         }
9814 
9815         /* Process any pending HCCA DoneHead */
9816         done_head = (ohci_td_t *)(uintptr_t)
9817             (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK);
9818 
9819         if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
9820                 /* Reset the done head to NULL */
9821                 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL);
9822 
9823                 ohci_traverse_done_list(ohcip, done_head);
9824         }
9825 
9826         /* Process any pending hcr_done_head value */
9827         done_head = (ohci_td_t *)(uintptr_t)
9828             (Get_OpReg(hcr_done_head) & HCCA_DONE_HEAD_MASK);
9829         if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
9830 
9831                 ohci_traverse_done_list(ohcip, done_head);
9832         }
9833 
9834         /* Do soft reset of ohci host controller */
9835         Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
9836 
9837         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9838             "ohci_do_soft_reset: Reset in progress");
9839 
9840         /* Wait for reset to complete */
9841         drv_usecwait(OHCI_RESET_TIMEWAIT);
9842 
9843         /* Reset HCCA HcFrameNumber */
9844         Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000);
9845 
9846         /*
9847          * Restore previous saved HC register value
9848          * into the current HC registers.
9849          */
9850         Set_OpReg(hcr_periodic_strt, (uint32_t)
9851             ohci_save_regs->hcr_periodic_strt);
9852 
9853         Set_OpReg(hcr_frame_interval, (uint32_t)
9854             ohci_save_regs->hcr_frame_interval);
9855 
9856         Set_OpReg(hcr_done_head, 0x0);
9857 
9858         Set_OpReg(hcr_bulk_curr, 0x0);
9859 
9860         Set_OpReg(hcr_bulk_head, (uint32_t)
9861             ohci_save_regs->hcr_bulk_head);
9862 
9863         Set_OpReg(hcr_ctrl_curr, 0x0);
9864 
9865         Set_OpReg(hcr_ctrl_head, (uint32_t)
9866             ohci_save_regs->hcr_ctrl_head);
9867 
9868         Set_OpReg(hcr_periodic_curr, 0x0);
9869 
9870         Set_OpReg(hcr_HCCA, (uint32_t)
9871             ohci_save_regs->hcr_HCCA);
9872 
9873         Set_OpReg(hcr_intr_status, 0x0);
9874 
9875         /*
9876          * Set HcInterruptEnable to enable all interrupts except
9877          * Root Hub Status change interrupt.
9878          */
9879         Set_OpReg(hcr_intr_enable,
9880             HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE |
9881             HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE);
9882 
9883         /* Start Control and Bulk list processing */
9884         Set_OpReg(hcr_cmd_status, (HCR_STATUS_CLF | HCR_STATUS_BLF));
9885 
9886         /*
9887          * Start up Control, Bulk, Periodic and Isochronous lists
9888          * processing.
9889          */
9890         Set_OpReg(hcr_control, (uint32_t)
9891             (ohci_save_regs->hcr_control & (~HCR_CONTROL_HCFS)));
9892 
9893         /*
9894          * Deallocate the space that allocated for saving
9895          * HC registers.
9896          */
9897         kmem_free((void *) ohci_save_regs, sizeof (ohci_regs_t));
9898 
9899         /* Resume the host controller */
9900         Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
9901             (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESUME));
9902 
9903         /* Wait for resume to complete */
9904         drv_usecwait(OHCI_RESUME_TIMEWAIT);
9905 
9906         /* Set the Host Controller Functional State to Operational */
9907         Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
9908             (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT));
9909 
9910         /* Wait 10ms for HC to start sending SOF */
9911         drv_usecwait(OHCI_TIMEWAIT);
9912 
9913         /*
9914          * Get the current usb frame number before waiting for few
9915          * milliseconds.
9916          */
9917         before_frame_number = ohci_get_current_frame_number(ohcip);
9918 
9919         /* Wait for few milliseconds */
9920         drv_usecwait(OHCI_TIMEWAIT);
9921 
9922         /*
9923          * Get the current usb frame number after waiting for few
9924          * milliseconds.
9925          */
9926         after_frame_number = ohci_get_current_frame_number(ohcip);
9927 
9928         USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9929             "ohci_do_soft_reset: Before Frm No 0x%llx After Frm No 0x%llx",
9930             (unsigned long long)before_frame_number,
9931             (unsigned long long)after_frame_number);
9932 
9933         if (after_frame_number <= before_frame_number) {
9934 
9935                 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9936                     "ohci_do_soft_reset: Soft reset failed");
9937 
9938                 return (USB_FAILURE);
9939         }
9940 
9941         /* Start the timer for the root hub interrupt pipe polling */
9942         if (rh_timer_id) {
9943                 ohcip->ohci_root_hub.rh_intr_pipe_timer_id =
9944                     timeout(ohci_handle_root_hub_status_change,
9945                     (void *)ohcip, drv_usectohz(OHCI_RH_POLL_TIME));
9946 
9947                 ohcip->ohci_root_hub.
9948                     rh_intr_pipe_state = OHCI_PIPE_STATE_ACTIVE;
9949         }
9950 
9951         /* Start the global timer */
9952         if (xfer_timer_id) {
9953                 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler,
9954                     (void *)ohcip, drv_sectohz(1));
9955         }
9956 
9957         return (USB_SUCCESS);
9958 }
9959 
9960 
9961 /*
9962  * ohci_get_current_frame_number:
9963  *
9964  * Get the current software based usb frame number.
9965  */
9966 usb_frame_number_t
9967 ohci_get_current_frame_number(ohci_state_t *ohcip)
9968 {
9969         usb_frame_number_t      usb_frame_number;
9970         usb_frame_number_t      ohci_fno, frame_number;
9971         ohci_save_intr_sts_t    *ohci_intr_sts =
9972             &ohcip->ohci_save_intr_sts;
9973 
9974         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9975 
9976         /*
9977          * Sync HCCA area only if this function
9978          * is invoked in non interrupt context.
9979          */
9980         if (!(ohci_intr_sts->ohci_intr_flag &
9981             OHCI_INTR_HANDLING)) {
9982 
9983                 /* Sync HCCA area */
9984                 Sync_HCCA(ohcip);
9985         }
9986 
9987         ohci_fno = ohcip->ohci_fno;
9988         frame_number = Get_HCCA(ohcip->ohci_hccap->HccaFrameNo);
9989 
9990         /*
9991          * Calculate current software based usb frame number.
9992          *
9993          * This code accounts for the fact that frame number is
9994          * updated by the Host Controller before the ohci driver
9995          * gets an FrameNumberOverflow (FNO) interrupt that will
9996          * adjust Frame higher part.
9997          *
9998          * Refer ohci specification 1.0a, section 5.4, page 86.
9999          */
10000         usb_frame_number = ((frame_number & 0x7FFF) | ohci_fno) +
10001             (((frame_number & 0xFFFF) ^ ohci_fno) & 0x8000);
10002 
10003         return (usb_frame_number);
10004 }
10005 
10006 
10007 /*
10008  * ohci_cpr_cleanup:
10009  *
10010  * Cleanup ohci state and other ohci specific informations across
10011  * Check Point Resume (CPR).
10012  */
10013 static  void
10014 ohci_cpr_cleanup(ohci_state_t *ohcip)
10015 {
10016         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10017 
10018         /* Reset software part of usb frame number */
10019         ohcip->ohci_fno = 0;
10020 
10021         /* Reset Schedule Overrrun Error Counter */
10022         ohcip->ohci_so_error = 0;
10023 
10024         /* Reset HCCA HcFrameNumber */
10025         Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000);
10026 }
10027 
10028 
10029 /*
10030  * ohci_get_xfer_attrs:
10031  *
10032  * Get the attributes of a particular xfer.
10033  */
10034 static usb_req_attrs_t
10035 ohci_get_xfer_attrs(
10036         ohci_state_t            *ohcip,
10037         ohci_pipe_private_t     *pp,
10038         ohci_trans_wrapper_t    *tw)
10039 {
10040         usb_ep_descr_t          *eptd = &pp->pp_pipe_handle->p_ep;
10041         usb_req_attrs_t         attrs = 0;
10042 
10043         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10044             "ohci_get_xfer_attrs:");
10045 
10046         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10047 
10048         switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
10049         case USB_EP_ATTR_CONTROL:
10050                 attrs = ((usb_ctrl_req_t *)
10051                     tw->tw_curr_xfer_reqp)->ctrl_attributes;
10052                 break;
10053         case USB_EP_ATTR_BULK:
10054                 attrs = ((usb_bulk_req_t *)
10055                     tw->tw_curr_xfer_reqp)->bulk_attributes;
10056                 break;
10057         case USB_EP_ATTR_INTR:
10058                 attrs = ((usb_intr_req_t *)
10059                     tw->tw_curr_xfer_reqp)->intr_attributes;
10060                 break;
10061         case USB_EP_ATTR_ISOCH:
10062                 attrs = ((usb_isoc_req_t *)
10063                     tw->tw_curr_xfer_reqp)->isoc_attributes;
10064                 break;
10065         }
10066 
10067         return (attrs);
10068 }
10069 
10070 
10071 /*
10072  * ohci_allocate_periodic_in_resource
10073  *
10074  * Allocate interrupt/isochronous request structure for the
10075  * interrupt/isochronous IN transfer.
10076  */
10077 static int
10078 ohci_allocate_periodic_in_resource(
10079         ohci_state_t            *ohcip,
10080         ohci_pipe_private_t     *pp,
10081         ohci_trans_wrapper_t    *tw,
10082         usb_flags_t             flags)
10083 {
10084         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10085         uchar_t                 ep_attr = ph->p_ep.bmAttributes;
10086         usb_intr_req_t          *curr_intr_reqp;
10087         usb_isoc_req_t          *curr_isoc_reqp;
10088         usb_opaque_t            client_periodic_in_reqp;
10089         size_t                  length = 0;
10090 
10091         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10092             "ohci_allocate_periodic_in_resource:"
10093             "pp = 0x%p tw = 0x%p flags = 0x%x", (void *)pp, (void *)tw, flags);
10094 
10095         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10096         ASSERT(tw->tw_curr_xfer_reqp == NULL);
10097 
10098         /* Get the client periodic in request pointer */
10099         client_periodic_in_reqp = pp->pp_client_periodic_in_reqp;
10100 
10101         /*
10102          * If it a periodic IN request and periodic request is NULL,
10103          * allocate corresponding usb periodic IN request for the
10104          * current periodic polling request and copy the information
10105          * from the saved periodic request structure.
10106          */
10107         if ((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) {
10108 
10109                 if (client_periodic_in_reqp) {
10110 
10111                         /* Get the interrupt transfer length */
10112                         length = ((usb_intr_req_t *)
10113                             client_periodic_in_reqp)->intr_len;
10114 
10115                         curr_intr_reqp = usba_hcdi_dup_intr_req(
10116                             ph->p_dip, (usb_intr_req_t *)
10117                             client_periodic_in_reqp, length, flags);
10118                 } else {
10119                         curr_intr_reqp = usb_alloc_intr_req(
10120                             ph->p_dip, length, flags);
10121                 }
10122 
10123                 if (curr_intr_reqp == NULL) {
10124 
10125                         USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10126                             "ohci_allocate_periodic_in_resource: Interrupt "
10127                             "request structure allocation failed");
10128 
10129                         return (USB_NO_RESOURCES);
10130                 }
10131 
10132                 if (client_periodic_in_reqp == NULL) {
10133                         /* For polled mode */
10134                         curr_intr_reqp->
10135                             intr_attributes = USB_ATTRS_SHORT_XFER_OK;
10136                         curr_intr_reqp->
10137                             intr_len = ph->p_ep.wMaxPacketSize;
10138                 } else {
10139                         /* Check and save the timeout value */
10140                         tw->tw_timeout = (curr_intr_reqp->intr_attributes &
10141                             USB_ATTRS_ONE_XFER) ?
10142                             curr_intr_reqp->intr_timeout: 0;
10143                 }
10144 
10145                 tw->tw_curr_xfer_reqp = (usb_opaque_t)curr_intr_reqp;
10146                 tw->tw_length = curr_intr_reqp->intr_len;
10147         } else {
10148                 ASSERT(client_periodic_in_reqp != NULL);
10149 
10150                 curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip,
10151                     (usb_isoc_req_t *)client_periodic_in_reqp, flags);
10152 
10153                 if (curr_isoc_reqp == NULL) {
10154 
10155                         USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10156                             "ohci_allocate_periodic_in_resource: Isochronous"
10157                             "request structure allocation failed");
10158 
10159                         return (USB_NO_RESOURCES);
10160                 }
10161 
10162                 /*
10163                  * Save the client's isochronous request pointer and
10164                  * length of isochronous transfer in transfer wrapper.
10165                  * The dup'ed request is saved in pp_client_periodic_in_reqp
10166                  */
10167                 tw->tw_curr_xfer_reqp =
10168                     (usb_opaque_t)pp->pp_client_periodic_in_reqp;
10169                 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp;
10170         }
10171 
10172         mutex_enter(&ph->p_mutex);
10173         ph->p_req_count++;
10174         mutex_exit(&ph->p_mutex);
10175 
10176         pp->pp_state = OHCI_PIPE_STATE_ACTIVE;
10177 
10178         return (USB_SUCCESS);
10179 }
10180 
10181 
10182 /*
10183  * ohci_wait_for_sof:
10184  *
10185  * Wait for couple of SOF interrupts
10186  */
10187 static int
10188 ohci_wait_for_sof(ohci_state_t  *ohcip)
10189 {
10190         usb_frame_number_t      before_frame_number, after_frame_number;
10191         clock_t                 sof_time_wait;
10192         int                     rval, sof_wait_count;
10193 
10194         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10195             "ohci_wait_for_sof");
10196 
10197         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10198 
10199         rval = ohci_state_is_operational(ohcip);
10200 
10201         if (rval != USB_SUCCESS) {
10202 
10203                 return (rval);
10204         }
10205 
10206         /* Get the number of clock ticks to wait */
10207         sof_time_wait = drv_sectohz(OHCI_MAX_SOF_TIMEWAIT);
10208 
10209         sof_wait_count = 0;
10210 
10211         /*
10212          * Get the current usb frame number before waiting for the
10213          * SOF interrupt event.
10214          */
10215         before_frame_number = ohci_get_current_frame_number(ohcip);
10216 
10217         while (sof_wait_count < MAX_SOF_WAIT_COUNT) {
10218                 /* Enable the SOF interrupt */
10219                 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
10220 
10221                 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF);
10222 
10223                 /* Wait for the SOF or timeout event */
10224                 rval = cv_reltimedwait(&ohcip->ohci_SOF_cv,
10225                     &ohcip->ohci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
10226 
10227                 /*
10228                  * Get the current usb frame number after woken up either
10229                  * from SOF interrupt or timer expired event.
10230                  */
10231                 after_frame_number = ohci_get_current_frame_number(ohcip);
10232 
10233                 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10234                     "ohci_wait_for_sof: before 0x%llx, after 0x%llx",
10235                     (unsigned long long)before_frame_number,
10236                     (unsigned long long)after_frame_number);
10237 
10238                 /*
10239                  * Return failure, if we are woken up becuase of timer expired
10240                  * event and if usb frame number has not been changed.
10241                  */
10242                 if ((rval == -1) &&
10243                     (after_frame_number <= before_frame_number)) {
10244 
10245                         if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) {
10246 
10247                                 USB_DPRINTF_L0(PRINT_MASK_LISTS,
10248                                     ohcip->ohci_log_hdl, "No SOF interrupts");
10249 
10250                                 /* Set host controller soft state to error */
10251                                 ohcip->ohci_hc_soft_state =
10252                                     OHCI_CTLR_ERROR_STATE;
10253 
10254                                 return (USB_FAILURE);
10255                         }
10256 
10257                         /* Get new usb frame number */
10258                         after_frame_number = before_frame_number =
10259                             ohci_get_current_frame_number(ohcip);
10260                 }
10261 
10262                 ASSERT(after_frame_number >= before_frame_number);
10263 
10264                 before_frame_number = after_frame_number;
10265                 sof_wait_count++;
10266         }
10267 
10268         return (USB_SUCCESS);
10269 }
10270 
10271 
10272 /*
10273  * ohci_pipe_cleanup
10274  *
10275  * Cleanup ohci pipe.
10276  */
10277 static void
10278 ohci_pipe_cleanup(
10279         ohci_state_t            *ohcip,
10280         usba_pipe_handle_data_t *ph)
10281 {
10282         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10283         usb_ep_descr_t          *eptd = &ph->p_ep;
10284         usb_cr_t                completion_reason;
10285         uint_t                  pipe_state = pp->pp_state;
10286         uint_t                  bit = 0;
10287 
10288         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10289             "ohci_pipe_cleanup: ph = 0x%p", (void *)ph);
10290 
10291         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10292 
10293         switch (pipe_state) {
10294         case OHCI_PIPE_STATE_CLOSE:
10295                 if (OHCI_NON_PERIODIC_ENDPOINT(eptd)) {
10296 
10297                         bit = ((eptd->bmAttributes &
10298                             USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ?
10299                             HCR_CONTROL_CLE: HCR_CONTROL_BLE;
10300 
10301                         Set_OpReg(hcr_control,
10302                             (Get_OpReg(hcr_control) & ~(bit)));
10303 
10304                         /* Wait for the next SOF */
10305                         (void) ohci_wait_for_sof(ohcip);
10306 
10307                         break;
10308                 }
10309                 /* FALLTHROUGH */
10310         case OHCI_PIPE_STATE_RESET:
10311         case OHCI_PIPE_STATE_STOP_POLLING:
10312                 /*
10313                  * Set the sKip bit to stop all transactions on
10314                  * this pipe
10315                  */
10316                 ohci_modify_sKip_bit(ohcip, pp, SET_sKip,
10317                     OHCI_FLAGS_SLEEP | OHCI_FLAGS_DMA_SYNC);
10318 
10319                 break;
10320         default:
10321                 return;
10322         }
10323 
10324         /*
10325          * Wait for processing all completed transfers and
10326          * to send results to upstream.
10327          */
10328         ohci_wait_for_transfers_completion(ohcip, pp);
10329 
10330         /* Save the data toggle information */
10331         ohci_save_data_toggle(ohcip, ph);
10332 
10333         /*
10334          * Traverse the list of TD's on this endpoint and
10335          * these TD's have outstanding transfer requests.
10336          * Since the list processing is stopped, these tds
10337          * can be deallocated.
10338          */
10339         ohci_traverse_tds(ohcip, ph);
10340 
10341         /*
10342          * If all of the endpoint's TD's have been deallocated,
10343          * then the DMA mappings can be torn down. If not there
10344          * are some TD's on the  done list that have not been
10345          * processed. Tag these TD's  so that they are thrown
10346          * away when the done list is processed.
10347          */
10348         ohci_done_list_tds(ohcip, ph);
10349 
10350         /* Do callbacks for all unfinished requests */
10351         ohci_handle_outstanding_requests(ohcip, pp);
10352 
10353         /* Free DMA resources */
10354         ohci_free_dma_resources(ohcip, ph);
10355 
10356         switch (pipe_state) {
10357         case OHCI_PIPE_STATE_CLOSE:
10358                 completion_reason = USB_CR_PIPE_CLOSING;
10359                 break;
10360         case OHCI_PIPE_STATE_RESET:
10361         case OHCI_PIPE_STATE_STOP_POLLING:
10362                 /* Set completion reason */
10363                 completion_reason = (pipe_state ==
10364                     OHCI_PIPE_STATE_RESET) ?
10365                     USB_CR_PIPE_RESET: USB_CR_STOPPED_POLLING;
10366 
10367                 /* Restore the data toggle information */
10368                 ohci_restore_data_toggle(ohcip, ph);
10369 
10370                 /*
10371                  * Clear the sKip bit to restart all the
10372                  * transactions on this pipe.
10373                  */
10374                 ohci_modify_sKip_bit(ohcip, pp,
10375                     CLEAR_sKip, OHCI_FLAGS_NOSLEEP);
10376 
10377                 /* Set pipe state to idle */
10378                 pp->pp_state = OHCI_PIPE_STATE_IDLE;
10379 
10380                 break;
10381         }
10382 
10383         ASSERT((Get_ED(pp->pp_ept->hced_tailp) & HC_EPT_TD_TAIL) ==
10384             (Get_ED(pp->pp_ept->hced_headp) & HC_EPT_TD_HEAD));
10385 
10386         ASSERT((pp->pp_tw_head == NULL) && (pp->pp_tw_tail == NULL));
10387 
10388         /*
10389          * Do the callback for the original client
10390          * periodic IN request.
10391          */
10392         if ((OHCI_PERIODIC_ENDPOINT(eptd)) &&
10393             ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) ==
10394             USB_EP_DIR_IN)) {
10395 
10396                 ohci_do_client_periodic_in_req_callback(
10397                     ohcip, pp, completion_reason);
10398         }
10399 }
10400 
10401 
10402 /*
10403  * ohci_wait_for_transfers_completion:
10404  *
10405  * Wait for processing all completed transfers and to send results
10406  * to upstream.
10407  */
10408 static void
10409 ohci_wait_for_transfers_completion(
10410         ohci_state_t            *ohcip,
10411         ohci_pipe_private_t     *pp)
10412 {
10413         ohci_trans_wrapper_t    *head_tw = pp->pp_tw_head;
10414         ohci_trans_wrapper_t    *next_tw;
10415         ohci_td_t               *tailp, *headp, *nextp;
10416         ohci_td_t               *head_td, *next_td;
10417         ohci_ed_t               *ept = pp->pp_ept;
10418         int                     rval;
10419 
10420         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10421             "ohci_wait_for_transfers_completion: pp = 0x%p", (void *)pp);
10422 
10423         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10424 
10425         headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10426             Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD));
10427 
10428         tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10429             Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL));
10430 
10431         rval = ohci_state_is_operational(ohcip);
10432 
10433         if (rval != USB_SUCCESS) {
10434 
10435                 return;
10436         }
10437 
10438         pp->pp_count_done_tds = 0;
10439 
10440         /* Process the transfer wrappers for this pipe */
10441         next_tw = head_tw;
10442         while (next_tw) {
10443                 head_td = (ohci_td_t *)next_tw->tw_hctd_head;
10444                 next_td = head_td;
10445 
10446                 if (head_td) {
10447                         /*
10448                          * Walk through each TD for this transfer
10449                          * wrapper. If a TD still exists, then it
10450                          * is currently on the done list.
10451                          */
10452                         while (next_td) {
10453 
10454                                 nextp = headp;
10455 
10456                                 while (nextp != tailp) {
10457 
10458                                         /* TD is on the ED */
10459                                         if (nextp == next_td) {
10460                                                 break;
10461                                         }
10462 
10463                                         nextp = (ohci_td_t *)
10464                                             (ohci_td_iommu_to_cpu(ohcip,
10465                                             (Get_TD(nextp->hctd_next_td) &
10466                                             HC_EPT_TD_TAIL)));
10467                                 }
10468 
10469                                 if (nextp == tailp) {
10470                                         pp->pp_count_done_tds++;
10471                                 }
10472 
10473                                 next_td = ohci_td_iommu_to_cpu(ohcip,
10474                                     Get_TD(next_td->hctd_tw_next_td));
10475                         }
10476                 }
10477 
10478                 next_tw = next_tw->tw_next;
10479         }
10480 
10481         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10482             "ohci_wait_for_transfers_completion: count_done_tds = 0x%x",
10483             pp->pp_count_done_tds);
10484 
10485         if (!pp->pp_count_done_tds) {
10486 
10487                 return;
10488         }
10489 
10490         (void) cv_reltimedwait(&pp->pp_xfer_cmpl_cv, &ohcip->ohci_int_mutex,
10491             drv_sectohz(OHCI_XFER_CMPL_TIMEWAIT), TR_CLOCK_TICK);
10492 
10493         if (pp->pp_count_done_tds) {
10494 
10495                 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10496                     "ohci_wait_for_transfers_completion: No transfers "
10497                     "completion confirmation received for 0x%x requests",
10498                     pp->pp_count_done_tds);
10499         }
10500 }
10501 
10502 
10503 /*
10504  * ohci_check_for_transfers_completion:
10505  *
10506  * Check whether anybody is waiting for transfers completion event. If so, send
10507  * this event and also stop initiating any new transfers on this pipe.
10508  */
10509 static void
10510 ohci_check_for_transfers_completion(
10511         ohci_state_t            *ohcip,
10512         ohci_pipe_private_t     *pp)
10513 {
10514         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10515             "ohci_check_for_transfers_completion: pp = 0x%p", (void *)pp);
10516 
10517         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10518 
10519         if ((pp->pp_state == OHCI_PIPE_STATE_STOP_POLLING) &&
10520             (pp->pp_error == USB_CR_NO_RESOURCES) &&
10521             (pp->pp_cur_periodic_req_cnt == 0)) {
10522 
10523                 /* Reset pipe error to zero */
10524                 pp->pp_error = 0;
10525 
10526                 /* Do callback for original request */
10527                 ohci_do_client_periodic_in_req_callback(
10528                     ohcip, pp, USB_CR_NO_RESOURCES);
10529         }
10530 
10531         if (pp->pp_count_done_tds) {
10532 
10533                 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10534                     "ohci_check_for_transfers_completion:"
10535                     "count_done_tds = 0x%x", pp->pp_count_done_tds);
10536 
10537                 /* Decrement the done td count */
10538                 pp->pp_count_done_tds--;
10539 
10540                 if (!pp->pp_count_done_tds) {
10541                         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10542                             "ohci_check_for_transfers_completion:"
10543                             "Sent transfers completion event pp = 0x%p",
10544                             (void *)pp);
10545 
10546                         /* Send the transfer completion signal */
10547                         cv_signal(&pp->pp_xfer_cmpl_cv);
10548                 }
10549         }
10550 }
10551 
10552 
10553 /*
10554  * ohci_save_data_toggle:
10555  *
10556  * Save the data toggle information.
10557  */
10558 static void
10559 ohci_save_data_toggle(
10560         ohci_state_t            *ohcip,
10561         usba_pipe_handle_data_t *ph)
10562 {
10563         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10564         usb_ep_descr_t          *eptd = &ph->p_ep;
10565         uint_t                  data_toggle;
10566         usb_cr_t                error = pp->pp_error;
10567         ohci_ed_t               *ed = pp->pp_ept;
10568         ohci_td_t               *headp, *tailp;
10569 
10570         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10571             "ohci_save_data_toggle: ph = 0x%p", (void *)ph);
10572 
10573         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10574 
10575         /* Reset the pipe error value */
10576         pp->pp_error = USB_CR_OK;
10577 
10578         /* Return immediately if it is a control or isoc pipe */
10579         if (((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
10580             USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes &
10581             USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) {
10582 
10583                 return;
10584         }
10585 
10586         headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10587             Get_ED(ed->hced_headp) & (uint32_t)HC_EPT_TD_HEAD));
10588 
10589         tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10590             Get_ED(ed->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL));
10591 
10592         /*
10593          * Retrieve the data toggle information either from the endpoint
10594          * (ED) or from the transfer descriptor (TD) depending on the
10595          * situation.
10596          */
10597         if ((Get_ED(ed->hced_headp) & HC_EPT_Halt) || (headp == tailp)) {
10598 
10599                 /* Get the data toggle information from the endpoint */
10600                 data_toggle = (Get_ED(ed->hced_headp) &
10601                     HC_EPT_Carry)? DATA1:DATA0;
10602         } else {
10603                 /*
10604                  * Retrieve the data toggle information depending on the
10605                  * master data toggle information saved in  the transfer
10606                  * descriptor (TD) at the head of the endpoint (ED).
10607                  *
10608                  * Check for master data toggle information .
10609                  */
10610                 if (Get_TD(headp->hctd_ctrl) & HC_TD_MS_DT) {
10611                         /* Get the data toggle information from td */
10612                         data_toggle = (Get_TD(headp->hctd_ctrl) &
10613                             HC_TD_DT_1) ? DATA1:DATA0;
10614                 } else {
10615                         /* Get the data toggle information from the endpoint */
10616                         data_toggle = (Get_ED(ed->hced_headp) &
10617                             HC_EPT_Carry)? DATA1:DATA0;
10618                 }
10619         }
10620 
10621         /*
10622          * If error is STALL, then, set
10623          * data toggle to zero.
10624          */
10625         if (error == USB_CR_STALL) {
10626                 data_toggle = DATA0;
10627         }
10628 
10629         /*
10630          * Save the data toggle information
10631          * in the usb device structure.
10632          */
10633         mutex_enter(&ph->p_mutex);
10634         usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
10635             data_toggle);
10636         mutex_exit(&ph->p_mutex);
10637 }
10638 
10639 
10640 /*
10641  * ohci_restore_data_toggle:
10642  *
10643  * Restore the data toggle information.
10644  */
10645 static void
10646 ohci_restore_data_toggle(
10647         ohci_state_t            *ohcip,
10648         usba_pipe_handle_data_t *ph)
10649 {
10650         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10651         usb_ep_descr_t          *eptd = &ph->p_ep;
10652         uint_t                  data_toggle = 0;
10653 
10654         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10655             "ohci_restore_data_toggle: ph = 0x%p", (void *)ph);
10656 
10657         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10658 
10659         /*
10660          * Return immediately if it is a control or isoc pipe.
10661          */
10662         if (((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
10663             USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes &
10664             USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) {
10665 
10666                 return;
10667         }
10668 
10669         mutex_enter(&ph->p_mutex);
10670 
10671         data_toggle = usba_hcdi_get_data_toggle(ph->p_usba_device,
10672             ph->p_ep.bEndpointAddress);
10673         usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
10674             0);
10675 
10676         mutex_exit(&ph->p_mutex);
10677 
10678         /*
10679          * Restore the data toggle bit depending on the
10680          * previous data toggle information.
10681          */
10682         if (data_toggle) {
10683                 Set_ED(pp->pp_ept->hced_headp,
10684                     Get_ED(pp->pp_ept->hced_headp) | HC_EPT_Carry);
10685         } else {
10686                 Set_ED(pp->pp_ept->hced_headp,
10687                     Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry));
10688         }
10689 }
10690 
10691 
10692 /*
10693  * ohci_handle_outstanding_requests
10694  * NOTE: This function is also called from POLLED MODE.
10695  *
10696  * Deallocate interrupt/isochronous request structure for the
10697  * interrupt/isochronous IN transfer. Do the callbacks for all
10698  * unfinished requests.
10699  */
10700 void
10701 ohci_handle_outstanding_requests(
10702         ohci_state_t            *ohcip,
10703         ohci_pipe_private_t     *pp)
10704 {
10705         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10706         usb_ep_descr_t  *eptd = &ph->p_ep;
10707         ohci_trans_wrapper_t    *curr_tw;
10708         ohci_trans_wrapper_t    *next_tw;
10709         usb_opaque_t            curr_xfer_reqp;
10710 
10711         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10712             "ohci_handle_outstanding_requests: pp = 0x%p", (void *)pp);
10713 
10714         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10715 
10716         /*
10717          * Deallocate all the pre-allocated interrupt requests
10718          */
10719         next_tw = pp->pp_tw_head;
10720 
10721         while (next_tw) {
10722                 curr_tw = next_tw;
10723                 next_tw = curr_tw->tw_next;
10724 
10725                 curr_xfer_reqp = curr_tw->tw_curr_xfer_reqp;
10726 
10727                 /* Deallocate current interrupt request */
10728                 if (curr_xfer_reqp) {
10729 
10730                         if ((OHCI_PERIODIC_ENDPOINT(eptd)) &&
10731                             (curr_tw->tw_direction == HC_TD_IN)) {
10732 
10733                                 /* Decrement periodic in request count */
10734                                 pp->pp_cur_periodic_req_cnt--;
10735 
10736                                 ohci_deallocate_periodic_in_resource(
10737                                     ohcip, pp, curr_tw);
10738                         } else {
10739                                 ohci_hcdi_callback(ph,
10740                                     curr_tw, USB_CR_FLUSHED);
10741                         }
10742                 }
10743         }
10744 }
10745 
10746 
10747 /*
10748  * ohci_deallocate_periodic_in_resource
10749  *
10750  * Deallocate interrupt/isochronous request structure for the
10751  * interrupt/isochronous IN transfer.
10752  */
10753 static void
10754 ohci_deallocate_periodic_in_resource(
10755         ohci_state_t            *ohcip,
10756         ohci_pipe_private_t     *pp,
10757         ohci_trans_wrapper_t    *tw)
10758 {
10759         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10760         uchar_t                 ep_attr = ph->p_ep.bmAttributes;
10761         usb_opaque_t            curr_xfer_reqp;
10762 
10763         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10764             "ohci_deallocate_periodic_in_resource: "
10765             "pp = 0x%p tw = 0x%p", (void *)pp, (void *)tw);
10766 
10767         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10768 
10769         curr_xfer_reqp = tw->tw_curr_xfer_reqp;
10770 
10771         /* Check the current periodic in request pointer */
10772         if (curr_xfer_reqp) {
10773                 /*
10774                  * Reset periodic in request usb isoch
10775                  * packet request pointers to null.
10776                  */
10777                 tw->tw_curr_xfer_reqp = NULL;
10778                 tw->tw_curr_isoc_pktp = NULL;
10779 
10780                 mutex_enter(&ph->p_mutex);
10781                 ph->p_req_count--;
10782                 mutex_exit(&ph->p_mutex);
10783 
10784                 /*
10785                  * Free pre-allocated interrupt
10786                  * or isochronous requests.
10787                  */
10788                 switch (ep_attr & USB_EP_ATTR_MASK) {
10789                 case USB_EP_ATTR_INTR:
10790                         usb_free_intr_req(
10791                             (usb_intr_req_t *)curr_xfer_reqp);
10792                         break;
10793                 case USB_EP_ATTR_ISOCH:
10794                         usb_free_isoc_req(
10795                             (usb_isoc_req_t *)curr_xfer_reqp);
10796                         break;
10797                 }
10798         }
10799 }
10800 
10801 
10802 /*
10803  * ohci_do_client_periodic_in_req_callback
10804  *
10805  * Do callback for the original client periodic IN request.
10806  */
10807 static void
10808 ohci_do_client_periodic_in_req_callback(
10809         ohci_state_t            *ohcip,
10810         ohci_pipe_private_t     *pp,
10811         usb_cr_t                completion_reason)
10812 {
10813         usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10814 
10815         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10816             "ohci_do_client_periodic_in_req_callback: "
10817             "pp = 0x%p cc = 0x%x", (void *)pp, completion_reason);
10818 
10819         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10820 
10821         /*
10822          * Check for Interrupt/Isochronous IN, whether we need to do
10823          * callback for the original client's periodic IN request.
10824          */
10825         if (pp->pp_client_periodic_in_reqp) {
10826                 ASSERT(pp->pp_cur_periodic_req_cnt == 0);
10827                 ohci_hcdi_callback(ph, NULL, completion_reason);
10828         }
10829 }
10830 
10831 
10832 /*
10833  * ohci_hcdi_callback()
10834  *
10835  * Convenience wrapper around usba_hcdi_cb() other than root hub.
10836  */
10837 static void
10838 ohci_hcdi_callback(
10839         usba_pipe_handle_data_t *ph,
10840         ohci_trans_wrapper_t    *tw,
10841         usb_cr_t                completion_reason)
10842 {
10843         ohci_state_t            *ohcip = ohci_obtain_state(
10844             ph->p_usba_device->usb_root_hub_dip);
10845         uchar_t                 attributes = ph->p_ep.bmAttributes &
10846             USB_EP_ATTR_MASK;
10847         ohci_pipe_private_t     *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10848         usb_opaque_t            curr_xfer_reqp;
10849         uint_t                  pipe_state = 0;
10850 
10851         USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10852             "ohci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x",
10853             (void *)ph, (void *)tw, completion_reason);
10854 
10855         ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10856 
10857         /* Set the pipe state as per completion reason */
10858         switch (completion_reason) {
10859         case USB_CR_OK:
10860                 pipe_state = pp->pp_state;
10861                 break;
10862         case USB_CR_NO_RESOURCES:
10863         case USB_CR_NOT_SUPPORTED:
10864         case USB_CR_STOPPED_POLLING:
10865         case USB_CR_PIPE_RESET:
10866                 pipe_state = OHCI_PIPE_STATE_IDLE;
10867                 break;
10868         case USB_CR_PIPE_CLOSING:
10869                 break;
10870         default:
10871                 /*
10872                  * Set the pipe state to error
10873                  * except for the isoc pipe.
10874                  */
10875                 if (attributes != USB_EP_ATTR_ISOCH) {
10876                         pipe_state = OHCI_PIPE_STATE_ERROR;
10877                         pp->pp_error = completion_reason;
10878                 }
10879                 break;
10880 
10881         }
10882 
10883         pp->pp_state = pipe_state;
10884 
10885         if (tw && tw->tw_curr_xfer_reqp) {
10886                 curr_xfer_reqp = tw->tw_curr_xfer_reqp;
10887                 tw->tw_curr_xfer_reqp = NULL;
10888                 tw->tw_curr_isoc_pktp = NULL;
10889         } else {
10890                 ASSERT(pp->pp_client_periodic_in_reqp != NULL);
10891 
10892                 curr_xfer_reqp = pp->pp_client_periodic_in_reqp;
10893                 pp->pp_client_periodic_in_reqp = NULL;
10894         }
10895 
10896         ASSERT(curr_xfer_reqp != NULL);
10897 
10898         mutex_exit(&ohcip->ohci_int_mutex);
10899 
10900         usba_hcdi_cb(ph, curr_xfer_reqp, completion_reason);
10901 
10902         mutex_enter(&ohcip->ohci_int_mutex);
10903 }
10904 
10905 
10906 /*
10907  * ohci kstat functions
10908  */
10909 
10910 /*
10911  * ohci_create_stats:
10912  *
10913  * Allocate and initialize the ohci kstat structures
10914  */
10915 static void
10916 ohci_create_stats(ohci_state_t  *ohcip)
10917 {
10918         char                    kstatname[KSTAT_STRLEN];
10919         const char              *dname = ddi_driver_name(ohcip->ohci_dip);
10920         char                    *usbtypes[USB_N_COUNT_KSTATS] =
10921             {"ctrl", "isoch", "bulk", "intr"};
10922         uint_t                  instance = ohcip->ohci_instance;
10923         ohci_intrs_stats_t      *isp;
10924         int                     i;
10925 
10926         if (OHCI_INTRS_STATS(ohcip) == NULL) {
10927                 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs",
10928                     dname, instance);
10929                 OHCI_INTRS_STATS(ohcip) = kstat_create("usba", instance,
10930                     kstatname, "usb_interrupts", KSTAT_TYPE_NAMED,
10931                     sizeof (ohci_intrs_stats_t) / sizeof (kstat_named_t),
10932                     KSTAT_FLAG_PERSISTENT);
10933 
10934                 if (OHCI_INTRS_STATS(ohcip)) {
10935                         isp = OHCI_INTRS_STATS_DATA(ohcip);
10936                         kstat_named_init(&isp->ohci_hcr_intr_total,
10937                             "Interrupts Total", KSTAT_DATA_UINT64);
10938                         kstat_named_init(&isp->ohci_hcr_intr_not_claimed,
10939                             "Not Claimed", KSTAT_DATA_UINT64);
10940                         kstat_named_init(&isp->ohci_hcr_intr_so,
10941                             "Schedule Overruns", KSTAT_DATA_UINT64);
10942                         kstat_named_init(&isp->ohci_hcr_intr_wdh,
10943                             "Writeback Done Head", KSTAT_DATA_UINT64);
10944                         kstat_named_init(&isp->ohci_hcr_intr_sof,
10945                             "Start Of Frame", KSTAT_DATA_UINT64);
10946                         kstat_named_init(&isp->ohci_hcr_intr_rd,
10947                             "Resume Detected", KSTAT_DATA_UINT64);
10948                         kstat_named_init(&isp->ohci_hcr_intr_ue,
10949                             "Unrecoverable Error", KSTAT_DATA_UINT64);
10950                         kstat_named_init(&isp->ohci_hcr_intr_fno,
10951                             "Frame No. Overflow", KSTAT_DATA_UINT64);
10952                         kstat_named_init(&isp->ohci_hcr_intr_rhsc,
10953                             "Root Hub Status Change", KSTAT_DATA_UINT64);
10954                         kstat_named_init(&isp->ohci_hcr_intr_oc,
10955                             "Change In Ownership", KSTAT_DATA_UINT64);
10956 
10957                         OHCI_INTRS_STATS(ohcip)->ks_private = ohcip;
10958                         OHCI_INTRS_STATS(ohcip)->ks_update = nulldev;
10959                         kstat_install(OHCI_INTRS_STATS(ohcip));
10960                 }
10961         }
10962 
10963         if (OHCI_TOTAL_STATS(ohcip) == NULL) {
10964                 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total",
10965                     dname, instance);
10966                 OHCI_TOTAL_STATS(ohcip) = kstat_create("usba", instance,
10967                     kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1,
10968                     KSTAT_FLAG_PERSISTENT);
10969 
10970                 if (OHCI_TOTAL_STATS(ohcip)) {
10971                         kstat_install(OHCI_TOTAL_STATS(ohcip));
10972                 }
10973         }
10974 
10975         for (i = 0; i < USB_N_COUNT_KSTATS; i++) {
10976                 if (ohcip->ohci_count_stats[i] == NULL) {
10977                         (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s",
10978                             dname, instance, usbtypes[i]);
10979                         ohcip->ohci_count_stats[i] = kstat_create("usba",
10980                             instance, kstatname, "usb_byte_count",
10981                             KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT);
10982 
10983                         if (ohcip->ohci_count_stats[i]) {
10984                                 kstat_install(ohcip->ohci_count_stats[i]);
10985                         }
10986                 }
10987         }
10988 }
10989 
10990 
10991 /*
10992  * ohci_destroy_stats:
10993  *
10994  * Clean up ohci kstat structures
10995  */
10996 static void
10997 ohci_destroy_stats(ohci_state_t *ohcip)
10998 {
10999         int     i;
11000 
11001         if (OHCI_INTRS_STATS(ohcip)) {
11002                 kstat_delete(OHCI_INTRS_STATS(ohcip));
11003                 OHCI_INTRS_STATS(ohcip) = NULL;
11004         }
11005 
11006         if (OHCI_TOTAL_STATS(ohcip)) {
11007                 kstat_delete(OHCI_TOTAL_STATS(ohcip));
11008                 OHCI_TOTAL_STATS(ohcip) = NULL;
11009         }
11010 
11011         for (i = 0; i < USB_N_COUNT_KSTATS; i++) {
11012                 if (ohcip->ohci_count_stats[i]) {
11013                         kstat_delete(ohcip->ohci_count_stats[i]);
11014                         ohcip->ohci_count_stats[i] = NULL;
11015                 }
11016         }
11017 }
11018 
11019 
11020 /*
11021  * ohci_do_intrs_stats:
11022  *
11023  * ohci status information
11024  */
11025 static void
11026 ohci_do_intrs_stats(
11027         ohci_state_t    *ohcip,
11028         int             val)
11029 {
11030         if (OHCI_INTRS_STATS(ohcip)) {
11031                 OHCI_INTRS_STATS_DATA(ohcip)->ohci_hcr_intr_total.value.ui64++;
11032                 switch (val) {
11033                         case HCR_INTR_SO:
11034                                 OHCI_INTRS_STATS_DATA(ohcip)->
11035                                     ohci_hcr_intr_so.value.ui64++;
11036                                 break;
11037                         case HCR_INTR_WDH:
11038                                 OHCI_INTRS_STATS_DATA(ohcip)->
11039                                     ohci_hcr_intr_wdh.value.ui64++;
11040                                 break;
11041                         case HCR_INTR_SOF:
11042                                 OHCI_INTRS_STATS_DATA(ohcip)->
11043                                     ohci_hcr_intr_sof.value.ui64++;
11044                                 break;
11045                         case HCR_INTR_RD:
11046                                 OHCI_INTRS_STATS_DATA(ohcip)->
11047                                     ohci_hcr_intr_rd.value.ui64++;
11048                                 break;
11049                         case HCR_INTR_UE:
11050                                 OHCI_INTRS_STATS_DATA(ohcip)->
11051                                     ohci_hcr_intr_ue.value.ui64++;
11052                                 break;
11053                         case HCR_INTR_FNO:
11054                                 OHCI_INTRS_STATS_DATA(ohcip)->
11055                                     ohci_hcr_intr_fno.value.ui64++;
11056                                 break;
11057                         case HCR_INTR_RHSC:
11058                                 OHCI_INTRS_STATS_DATA(ohcip)->
11059                                     ohci_hcr_intr_rhsc.value.ui64++;
11060                                 break;
11061                         case HCR_INTR_OC:
11062                                 OHCI_INTRS_STATS_DATA(ohcip)->
11063                                     ohci_hcr_intr_oc.value.ui64++;
11064                                 break;
11065                         default:
11066                                 OHCI_INTRS_STATS_DATA(ohcip)->
11067                                     ohci_hcr_intr_not_claimed.value.ui64++;
11068                                 break;
11069                 }
11070         }
11071 }
11072 
11073 
11074 /*
11075  * ohci_do_byte_stats:
11076  *
11077  * ohci data xfer information
11078  */
11079 static void
11080 ohci_do_byte_stats(
11081         ohci_state_t    *ohcip,
11082         size_t          len,
11083         uint8_t         attr,
11084         uint8_t         addr)
11085 {
11086         uint8_t         type = attr & USB_EP_ATTR_MASK;
11087         uint8_t         dir = addr & USB_EP_DIR_MASK;
11088 
11089         if (dir == USB_EP_DIR_IN) {
11090                 OHCI_TOTAL_STATS_DATA(ohcip)->reads++;
11091                 OHCI_TOTAL_STATS_DATA(ohcip)->nread += len;
11092                 switch (type) {
11093                         case USB_EP_ATTR_CONTROL:
11094                                 OHCI_CTRL_STATS(ohcip)->reads++;
11095                                 OHCI_CTRL_STATS(ohcip)->nread += len;
11096                                 break;
11097                         case USB_EP_ATTR_BULK:
11098                                 OHCI_BULK_STATS(ohcip)->reads++;
11099                                 OHCI_BULK_STATS(ohcip)->nread += len;
11100                                 break;
11101                         case USB_EP_ATTR_INTR:
11102                                 OHCI_INTR_STATS(ohcip)->reads++;
11103                                 OHCI_INTR_STATS(ohcip)->nread += len;
11104                                 break;
11105                         case USB_EP_ATTR_ISOCH:
11106                                 OHCI_ISOC_STATS(ohcip)->reads++;
11107                                 OHCI_ISOC_STATS(ohcip)->nread += len;
11108                                 break;
11109                 }
11110         } else if (dir == USB_EP_DIR_OUT) {
11111                 OHCI_TOTAL_STATS_DATA(ohcip)->writes++;
11112                 OHCI_TOTAL_STATS_DATA(ohcip)->nwritten += len;
11113                 switch (type) {
11114                         case USB_EP_ATTR_CONTROL:
11115                                 OHCI_CTRL_STATS(ohcip)->writes++;
11116                                 OHCI_CTRL_STATS(ohcip)->nwritten += len;
11117                                 break;
11118                         case USB_EP_ATTR_BULK:
11119                                 OHCI_BULK_STATS(ohcip)->writes++;
11120                                 OHCI_BULK_STATS(ohcip)->nwritten += len;
11121                                 break;
11122                         case USB_EP_ATTR_INTR:
11123                                 OHCI_INTR_STATS(ohcip)->writes++;
11124                                 OHCI_INTR_STATS(ohcip)->nwritten += len;
11125                                 break;
11126                         case USB_EP_ATTR_ISOCH:
11127                                 OHCI_ISOC_STATS(ohcip)->writes++;
11128                                 OHCI_ISOC_STATS(ohcip)->nwritten += len;
11129                                 break;
11130                 }
11131         }
11132 }
11133 
11134 
11135 /*
11136  * ohci_print_op_regs:
11137  *
11138  * Print Host Controller's (HC) Operational registers.
11139  */
11140 static void
11141 ohci_print_op_regs(ohci_state_t *ohcip)
11142 {
11143         uint_t                  i;
11144 
11145         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11146             "\n\tOHCI%d Operational Registers\n",
11147             ddi_get_instance(ohcip->ohci_dip));
11148 
11149         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11150             "\thcr_revision: 0x%x \t\thcr_control: 0x%x",
11151             Get_OpReg(hcr_revision), Get_OpReg(hcr_control));
11152         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11153             "\thcr_cmd_status: 0x%x \t\thcr_intr_enable: 0x%x",
11154             Get_OpReg(hcr_cmd_status), Get_OpReg(hcr_intr_enable));
11155         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11156             "\thcr_intr_disable: 0x%x \thcr_HCCA: 0x%x",
11157             Get_OpReg(hcr_intr_disable), Get_OpReg(hcr_HCCA));
11158         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11159             "\thcr_periodic_curr: 0x%x \t\thcr_ctrl_head: 0x%x",
11160             Get_OpReg(hcr_periodic_curr), Get_OpReg(hcr_ctrl_head));
11161         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11162             "\thcr_ctrl_curr: 0x%x  \t\thcr_bulk_head: 0x%x",
11163             Get_OpReg(hcr_ctrl_curr), Get_OpReg(hcr_bulk_head));
11164         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11165             "\thcr_bulk_curr: 0x%x \t\thcr_done_head: 0x%x",
11166             Get_OpReg(hcr_bulk_curr), Get_OpReg(hcr_done_head));
11167         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11168             "\thcr_frame_interval: 0x%x "
11169             "\thcr_frame_remaining: 0x%x", Get_OpReg(hcr_frame_interval),
11170             Get_OpReg(hcr_frame_remaining));
11171         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11172             "\thcr_frame_number: 0x%x  \thcr_periodic_strt: 0x%x",
11173             Get_OpReg(hcr_frame_number), Get_OpReg(hcr_periodic_strt));
11174         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11175             "\thcr_transfer_ls: 0x%x \t\thcr_rh_descriptorA: 0x%x",
11176             Get_OpReg(hcr_transfer_ls), Get_OpReg(hcr_rh_descriptorA));
11177         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11178             "\thcr_rh_descriptorB: 0x%x \thcr_rh_status: 0x%x",
11179             Get_OpReg(hcr_rh_descriptorB), Get_OpReg(hcr_rh_status));
11180 
11181         USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11182             "\tRoot hub port status");
11183 
11184         for (i = 0; i < (Get_OpReg(hcr_rh_descriptorA) & HCR_RHA_NDP); i++) {
11185                 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11186                     "\thcr_rh_portstatus 0x%x: 0x%x ", i,
11187                     Get_OpReg(hcr_rh_portstatus[i]));
11188         }
11189 }
11190 
11191 
11192 /*
11193  * ohci_print_ed:
11194  */
11195 static void
11196 ohci_print_ed(
11197         ohci_state_t    *ohcip,
11198         ohci_ed_t       *ed)
11199 {
11200         uint_t          ctrl = Get_ED(ed->hced_ctrl);
11201 
11202         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11203             "ohci_print_ed: ed = 0x%p", (void *)ed);
11204 
11205         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11206             "\thced_ctrl: 0x%x %s", ctrl,
11207             ((Get_ED(ed->hced_headp) & HC_EPT_Halt) ? "halted": ""));
11208         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11209             "\ttoggle carry: 0x%x", Get_ED(ed->hced_headp) & HC_EPT_Carry);
11210 
11211         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11212             "\tctrl: 0x%x", Get_ED(ed->hced_ctrl));
11213         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11214             "\ttailp: 0x%x", Get_ED(ed->hced_tailp));
11215         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11216             "\theadp: 0x%x", Get_ED(ed->hced_headp));
11217         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11218             "\tnext: 0x%x", Get_ED(ed->hced_next));
11219         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11220             "\tprev: 0x%x", Get_ED(ed->hced_prev));
11221         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11222             "\tnode: 0x%x", Get_ED(ed->hced_node));
11223         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11224             "\treclaim_next: 0x%x", Get_ED(ed->hced_reclaim_next));
11225         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11226             "\treclaim_frame: 0x%x", Get_ED(ed->hced_reclaim_frame));
11227         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11228             "\tstate: 0x%x", Get_ED(ed->hced_state));
11229 }
11230 
11231 
11232 /*
11233  * ohci_print_td:
11234  */
11235 static void
11236 ohci_print_td(
11237         ohci_state_t    *ohcip,
11238         ohci_td_t       *td)
11239 {
11240         uint_t          i;
11241         uint_t          ctrl = Get_TD(td->hctd_ctrl);
11242 
11243         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11244             "ohci_print_td: td = 0x%p", (void *)td);
11245 
11246         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11247             "\tPID: 0x%x ", ctrl & HC_TD_PID);
11248         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11249             "\tDelay Intr: 0x%x ", ctrl & HC_TD_DI);
11250         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11251             "\tData Toggle: 0x%x ", ctrl & HC_TD_DT);
11252         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11253             "\tError Count: 0x%x ", ctrl & HC_TD_EC);
11254 
11255         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11256             "\tctrl: 0x%x ", Get_TD(td->hctd_ctrl));
11257         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11258             "\tcbp: 0x%x ", Get_TD(td->hctd_cbp));
11259         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11260             "\tnext_td: 0x%x ", Get_TD(td->hctd_next_td));
11261         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11262             "\tbuf_end: 0x%x ", Get_TD(td->hctd_buf_end));
11263 
11264         for (i = 0; i < 4; i++) {
11265                 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11266                     "\toffset[%d]: 0x%x ", i, Get_TD(td->hctd_offsets[i]));
11267         }
11268 
11269         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11270             "\ttrans_wrapper: 0x%x ", Get_TD(td->hctd_trans_wrapper));
11271         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11272             "\tstate: 0x%x ", Get_TD(td->hctd_state));
11273         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11274             "\ttw_next_td: 0x%x ", Get_TD(td->hctd_tw_next_td));
11275         USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11276             "\tctrl_phase: 0x%x ", Get_TD(td->hctd_ctrl_phase));
11277 }
11278 
11279 /*
11280  * quiesce(9E) entry point.
11281  *
11282  * This function is called when the system is single-threaded at high
11283  * PIL with preemption disabled. Therefore, this function must not be
11284  * blocked.
11285  *
11286  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
11287  * DDI_FAILURE indicates an error condition and should almost never happen.
11288  *
11289  * define as a wrapper for sparc, or warlock will complain.
11290  */
11291 #ifdef  __sparc
11292 int
11293 ohci_quiesce(dev_info_t *dip)
11294 {
11295         return (ddi_quiesce_not_supported(dip));
11296 }
11297 #else
11298 int
11299 ohci_quiesce(dev_info_t *dip)
11300 {
11301         ohci_state_t    *ohcip = ohci_obtain_state(dip);
11302 
11303         if (ohcip == NULL)
11304                 return (DDI_FAILURE);
11305 
11306 #ifndef lint
11307         _NOTE(NO_COMPETING_THREADS_NOW);
11308 #endif
11309 
11310         if (ohcip->ohci_flags & OHCI_INTR) {
11311 
11312                 /* Disable all HC ED list processing */
11313                 Set_OpReg(hcr_control,
11314                     (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
11315                     HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
11316 
11317                 /* Disable all HC interrupts */
11318                 Set_OpReg(hcr_intr_disable,
11319                     (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE));
11320 
11321                 /* Disable Master and SOF interrupts */
11322                 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF));
11323 
11324                 /* Set the Host Controller Functional State to Reset */
11325                 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
11326                     (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET));
11327 
11328                 /*
11329                  * Workaround for ULI1575 chipset. Following OHCI Operational
11330                  * Memory Registers are not cleared to their default value
11331                  * on reset. Explicitly set the registers to default value.
11332                  */
11333                 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
11334                     ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
11335                         Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
11336                         Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
11337                         Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
11338                         Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
11339                         Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
11340                         Set_OpReg(hcr_frame_interval,
11341                             HCR_FRAME_INTERVAL_DEFAULT);
11342                         Set_OpReg(hcr_periodic_strt,
11343                             HCR_PERIODIC_START_DEFAULT);
11344                 }
11345 
11346                 ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE;
11347         }
11348 
11349         /* Unmap the OHCI registers */
11350         if (ohcip->ohci_regs_handle) {
11351                 /* Reset the host controller */
11352                 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
11353         }
11354 
11355 #ifndef lint
11356         _NOTE(COMPETING_THREADS_NOW);
11357 #endif
11358         return (DDI_SUCCESS);
11359 }
11360 #endif  /* __sparc */