1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
  24  * All rights reserved.
  25  */
  26 
  27 /*
  28  * hci1394_async.c
  29  *    These routines manipulate the 1394 asynchronous dma engines.  This
  30  *    includes incoming and outgoing reads, writes, and locks and their
  31  *    associated responses.
  32  */
  33 
  34 #include <sys/conf.h>
  35 #include <sys/ddi.h>
  36 #include <sys/modctl.h>
  37 #include <sys/stat.h>
  38 #include <sys/sunddi.h>
  39 #include <sys/cmn_err.h>
  40 #include <sys/kmem.h>
  41 #include <sys/types.h>
  42 #include <sys/note.h>
  43 
  44 #include <sys/1394/h1394.h>
  45 #include <sys/1394/adapters/hci1394.h>
  46 
  47 
  48 /*
  49  * ASYNC_ARRESP_ACK_ERROR is or'd into the error status when we get an ACK error
  50  * on an ARRESP.  Since the 1394 response code overlaps with the OpenHCI ACK/EVT
  51  * errors, we use this to distinguish between the errors in process_arresp().
  52  */
  53 #define ASYNC_ARRESP_ACK_ERROR          0x8000
  54 
  55 /* Macro's to help extract 48-bit 1394 address into a uint64_t */
  56 #define HCI1394_TO_ADDR_HI(data) (((uint64_t)((data) & 0xFFFF)) << 32)
  57 #define HCI1394_TO_ADDR_LO(data) ((uint64_t)((data) & 0xFFFFFFFF))
  58 
  59 /*
  60  * Macro to convert a byte stream into a big endian quadlet or octlet or back
  61  * the other way. 1394 arithmetic lock operations are done on big endian
  62  * quadlets or octlets. compare swaps and bit masks are done on a byte streams.
  63  * All data is treated as byte streams over the bus. These macros will convert
  64  * the data to a big endian "integer" on x86 plaforms if the operation is an
  65  * arithmetic lock operation.  It will do nothing if it is not on x86 or is not
  66  * an arithmetic lock operation.
  67  */
  68 #ifdef _LITTLE_ENDIAN
  69 #define HCI1394_ARITH_LOCK_SWAP32(tcode, data) \
  70         (((tcode) == CMD1394_LOCK_FETCH_ADD) || \
  71         ((tcode) == CMD1394_LOCK_BOUNDED_ADD) || \
  72         ((tcode) == CMD1394_LOCK_WRAP_ADD)) ? \
  73         (ddi_swap32(data)) : (data)
  74 #define HCI1394_ARITH_LOCK_SWAP64(tcode, data) \
  75         (((tcode) == CMD1394_LOCK_FETCH_ADD) || \
  76         ((tcode) == CMD1394_LOCK_BOUNDED_ADD) || \
  77         ((tcode) == CMD1394_LOCK_WRAP_ADD)) ? \
  78         (ddi_swap64(data)) : (data)
  79 #else
  80 #define HCI1394_ARITH_LOCK_SWAP32(tcode, data) (data)
  81 #define HCI1394_ARITH_LOCK_SWAP64(tcode, data) (data)
  82 #endif
  83 
  84 
  85 
  86 static int hci1394_async_arresp_read(hci1394_async_handle_t async_handle,
  87     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
  88     uint_t *size);
  89 static int hci1394_async_arresp_size_get(uint_t tcode, hci1394_q_handle_t q,
  90     uint32_t *addr, uint_t *size);
  91 
  92 static int hci1394_async_arreq_read(hci1394_async_handle_t async_handle,
  93     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
  94     uint_t *size);
  95 static int hci1394_async_arreq_read_qrd(hci1394_async_handle_t async_handle,
  96     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
  97 static int hci1394_async_arreq_read_qwr(hci1394_async_handle_t async_handle,
  98     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
  99 static int hci1394_async_arreq_read_brd(hci1394_async_handle_t async_handle,
 100     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
 101 static int hci1394_async_arreq_read_bwr(hci1394_async_handle_t async_handle,
 102     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
 103 static int hci1394_async_arreq_read_lck(hci1394_async_handle_t async_handle,
 104     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size);
 105 static int hci1394_async_arreq_read_phy(hci1394_async_handle_t async_handle,
 106     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size,
 107     boolean_t *bus_reset_token);
 108 
 109 static void hci1394_async_hcicmd_init(hci1394_async_handle_t async_handle,
 110     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv,
 111     hci1394_async_cmd_t **hcicmd);
 112 
 113 static void hci1394_async_atreq_start(void *async, uint32_t command_ptr);
 114 static void hci1394_async_arresp_start(void *async, uint32_t command_ptr);
 115 static void hci1394_async_arreq_start(void *async, uint32_t command_ptr);
 116 static void hci1394_async_atresp_start(void *async, uint32_t command_ptr);
 117 
 118 static void hci1394_async_atreq_wake(void *async);
 119 static void hci1394_async_arresp_wake(void *async);
 120 static void hci1394_async_arreq_wake(void *async);
 121 static void hci1394_async_atresp_wake(void *async);
 122 
 123 static void hci1394_async_atreq_flush(hci1394_async_handle_t async_handle);
 124 static void hci1394_async_arresp_flush(hci1394_async_handle_t async_handle);
 125 static void hci1394_async_arreq_flush(hci1394_async_handle_t async_handle);
 126 static void hci1394_async_atresp_flush(hci1394_async_handle_t async_handle);
 127 static void hci1394_async_pending_list_flush(hci1394_async_handle_t
 128     async_handle);
 129 
 130 static void hci1394_async_pending_timeout(hci1394_tlist_node_t *node,
 131     void *arg);
 132 static uint_t hci1394_async_timeout_calc(hci1394_async_handle_t async_handle,
 133     uint_t current_time);
 134 
 135 /*
 136  * hci1394_async_init()
 137  *    Initialize the async DMA engines and state. We init the tlabels; ATREQ
 138  *    pending Q; and ATREQ, ARRESP, ARREQ, and ATRESP Q's. init() returns a
 139  *    handle to be used in rest of the functions.
 140  */
 141 int
 142 hci1394_async_init(hci1394_drvinfo_t *drvinfo,
 143     hci1394_ohci_handle_t ohci_handle, hci1394_csr_handle_t csr_handle,
 144     hci1394_async_handle_t *async_handle)
 145 {
 146         hci1394_tlist_timer_t timer_info;
 147         hci1394_q_info_t qinfo;
 148         hci1394_async_t *async;
 149         int status;
 150 
 151 
 152         ASSERT(drvinfo != NULL);
 153         ASSERT(ohci_handle != NULL);
 154         ASSERT(csr_handle != NULL);
 155         ASSERT(async_handle != NULL);
 156         TNF_PROBE_0_DEBUG(hci1394_async_init_enter, HCI1394_TNF_HAL_STACK, "");
 157 
 158         /* alloc the space to keep track of the list */
 159         async = kmem_alloc(sizeof (hci1394_async_t), KM_SLEEP);
 160 
 161         /* copy in parms to our local state */
 162         async->as_drvinfo = drvinfo;
 163         async->as_ohci = ohci_handle;
 164         async->as_csr = csr_handle;
 165         async->as_flushing_arreq = B_FALSE;
 166         async->as_phy_reset = 0xFFFFFFFF;
 167         mutex_init(&async->as_atomic_lookup, NULL, MUTEX_DRIVER,
 168             drvinfo->di_iblock_cookie);
 169 
 170         /*
 171          * Initialize the tlabels. Reclaim a bad tlabel after the split timeout
 172          * has gone by. This time is in reference to the point the transaction
 173          * has been marked as bad. Therefore the tlabel will be reclaimed at
 174          * twice the split_timeout. (i.e. if the split timeout was set to 100mS
 175          * and the transaction has timed out, 100mS has already gone by. We need
 176          * to wait for 100mS more before we can reuse the tlabel. Therefore, the
 177          * reclaim time is split_timeout and not split_timeout * 2. The split
 178          * timeout is stored as the number of bus cycles.  We need to convert
 179          * this to nS since the reclaim time is passed as nS.
 180          */
 181         hci1394_tlabel_init(drvinfo, OHCI_BUS_CYCLE_TO_nS(
 182             hci1394_csr_split_timeout_get(csr_handle)), &async->as_tlabel);
 183 
 184         /*
 185          * Initialize ATREQ pending list. A pended ATREQ will be timed out after
 186          * "split_timeout" has gone by. split timeout is in bus cycles so we
 187          * need to convert that to nS for the tlist timer info. We will set the
 188          * timer resolution to 1/2 of the timeout so that we will have a worst
 189          * case timeout of split timeout + (1/2 * split timeout).  See
 190          * hci1394_tlist.h for more information about this.
 191          */
 192         timer_info.tlt_timeout =
 193             OHCI_BUS_CYCLE_TO_nS(hci1394_csr_split_timeout_get(csr_handle));
 194         timer_info.tlt_timer_resolution = timer_info.tlt_timeout / 2;
 195         timer_info.tlt_callback = hci1394_async_pending_timeout;
 196         timer_info.tlt_callback_arg = async;
 197         hci1394_tlist_init(drvinfo, &timer_info, &async->as_pending_list);
 198 
 199         /* Initialize ATREQ Q */
 200         qinfo.qi_desc_size = ASYNC_ATREQ_DESC_SIZE;
 201         qinfo.qi_data_size = ASYNC_ATREQ_DATA_SIZE;
 202         qinfo.qi_mode = HCI1394_ATQ;
 203         qinfo.qi_start = hci1394_async_atreq_start;
 204         qinfo.qi_wake = hci1394_async_atreq_wake;
 205         qinfo.qi_callback_arg = async;
 206         status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
 207             &async->as_atreq_q);
 208         if (status != DDI_SUCCESS) {
 209                 mutex_destroy(&async->as_atomic_lookup);
 210                 hci1394_tlist_fini(&async->as_pending_list);
 211                 hci1394_tlabel_fini(&async->as_tlabel);
 212                 kmem_free(async, sizeof (hci1394_async_t));
 213                 *async_handle = NULL;
 214                 TNF_PROBE_0(hci1394_async_q_init_fail, HCI1394_TNF_HAL_ERROR,
 215                     "");
 216                 TNF_PROBE_0_DEBUG(hci1394_async_init_exit,
 217                     HCI1394_TNF_HAL_STACK, "");
 218                 return (DDI_FAILURE);
 219         }
 220 
 221         /* Initialize ARRESP Q */
 222         qinfo.qi_desc_size = ASYNC_ARRESP_DESC_SIZE;
 223         qinfo.qi_data_size = ASYNC_ARRESP_DATA_SIZE;
 224         qinfo.qi_mode = HCI1394_ARQ;
 225         qinfo.qi_start = hci1394_async_arresp_start;
 226         qinfo.qi_wake = hci1394_async_arresp_wake;
 227         qinfo.qi_callback_arg = async;
 228         status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
 229             &async->as_arresp_q);
 230         if (status != DDI_SUCCESS) {
 231                 mutex_destroy(&async->as_atomic_lookup);
 232                 hci1394_tlist_fini(&async->as_pending_list);
 233                 hci1394_tlabel_fini(&async->as_tlabel);
 234                 hci1394_q_fini(&async->as_atreq_q);
 235                 kmem_free(async, sizeof (hci1394_async_t));
 236                 *async_handle = NULL;
 237                 TNF_PROBE_0(hci1394_async_q_init_fail, HCI1394_TNF_HAL_ERROR,
 238                     "");
 239                 TNF_PROBE_0_DEBUG(hci1394_async_init_exit,
 240                     HCI1394_TNF_HAL_STACK, "");
 241                 return (DDI_FAILURE);
 242         }
 243 
 244         /* Initialize ARREQ Q */
 245         qinfo.qi_desc_size = ASYNC_ARREQ_DESC_SIZE;
 246         qinfo.qi_data_size = ASYNC_ARREQ_DATA_SIZE;
 247         qinfo.qi_mode = HCI1394_ARQ;
 248         qinfo.qi_start = hci1394_async_arreq_start;
 249         qinfo.qi_wake = hci1394_async_arreq_wake;
 250         qinfo.qi_callback_arg = async;
 251         status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
 252             &async->as_arreq_q);
 253         if (status != DDI_SUCCESS) {
 254                 mutex_destroy(&async->as_atomic_lookup);
 255                 hci1394_tlist_fini(&async->as_pending_list);
 256                 hci1394_tlabel_fini(&async->as_tlabel);
 257                 hci1394_q_fini(&async->as_atreq_q);
 258                 hci1394_q_fini(&async->as_arresp_q);
 259                 kmem_free(async, sizeof (hci1394_async_t));
 260                 *async_handle = NULL;
 261                 TNF_PROBE_0(hci1394_async_q_init_fail, HCI1394_TNF_HAL_ERROR,
 262                     "");
 263                 TNF_PROBE_0_DEBUG(hci1394_async_init_exit,
 264                     HCI1394_TNF_HAL_STACK, "");
 265                 return (DDI_FAILURE);
 266         }
 267 
 268         /* Initialize ATRESP Q */
 269         qinfo.qi_desc_size = ASYNC_ATRESP_DESC_SIZE;
 270         qinfo.qi_data_size = ASYNC_ATRESP_DATA_SIZE;
 271         qinfo.qi_mode = HCI1394_ATQ;
 272         qinfo.qi_start = hci1394_async_atresp_start;
 273         qinfo.qi_wake = hci1394_async_atresp_wake;
 274         qinfo.qi_callback_arg = async;
 275         status = hci1394_q_init(drvinfo, async->as_ohci, &qinfo,
 276             &async->as_atresp_q);
 277         if (status != DDI_SUCCESS) {
 278                 mutex_destroy(&async->as_atomic_lookup);
 279                 hci1394_tlist_fini(&async->as_pending_list);
 280                 hci1394_tlabel_fini(&async->as_tlabel);
 281                 hci1394_q_fini(&async->as_atreq_q);
 282                 hci1394_q_fini(&async->as_arresp_q);
 283                 hci1394_q_fini(&async->as_arreq_q);
 284                 kmem_free(async, sizeof (hci1394_async_t));
 285                 *async_handle = NULL;
 286                 TNF_PROBE_0(hci1394_async_q_init_fail, HCI1394_TNF_HAL_ERROR,
 287                     "");
 288                 TNF_PROBE_0_DEBUG(hci1394_async_init_exit,
 289                     HCI1394_TNF_HAL_STACK, "");
 290                 return (DDI_FAILURE);
 291         }
 292 
 293         *async_handle = async;
 294 
 295         TNF_PROBE_0_DEBUG(hci1394_async_init_exit, HCI1394_TNF_HAL_STACK, "");
 296 
 297         return (DDI_SUCCESS);
 298 }
 299 
 300 
 301 /*
 302  * hci1394_async_fini()
 303  *    Free's up the space allocated in init().  Notice that a pointer to the
 304  *    handle is used for the parameter.  fini() will set your handle to NULL
 305  *    before returning.
 306  */
 307 void
 308 hci1394_async_fini(hci1394_async_handle_t *async_handle)
 309 {
 310         hci1394_async_t *async;
 311 
 312 
 313         ASSERT(async_handle != NULL);
 314         TNF_PROBE_0_DEBUG(hci1394_async_fini_enter, HCI1394_TNF_HAL_STACK, "");
 315 
 316         async = (hci1394_async_t *)*async_handle;
 317 
 318         mutex_destroy(&async->as_atomic_lookup);
 319         hci1394_tlabel_fini(&async->as_tlabel);
 320         hci1394_tlist_fini(&async->as_pending_list);
 321         hci1394_q_fini(&async->as_atreq_q);
 322         hci1394_q_fini(&async->as_atresp_q);
 323         hci1394_q_fini(&async->as_arreq_q);
 324         hci1394_q_fini(&async->as_arresp_q);
 325 
 326         kmem_free(async, sizeof (hci1394_async_t));
 327 
 328         /* set handle to null.  This helps catch bugs. */
 329         *async_handle = NULL;
 330 
 331         TNF_PROBE_0_DEBUG(hci1394_async_fini_exit, HCI1394_TNF_HAL_STACK, "");
 332 }
 333 
 334 
 335 /*
 336  * hci1394_async_suspend()
 337  *    The system is getting ready to be suspended.  Make sure that all of
 338  *    the Q's are clean and that the there are no scheduled timeouts in the
 339  *    pending Q.
 340  */
 341 void
 342 hci1394_async_suspend(hci1394_async_handle_t async_handle)
 343 {
 344         ASSERT(async_handle != NULL);
 345         TNF_PROBE_0_DEBUG(hci1394_async_suspend_enter,
 346             HCI1394_TNF_HAL_STACK, "");
 347 
 348         /* Flush out async DMA Q's */
 349         hci1394_async_flush(async_handle);
 350 
 351         /* Cancel any scheduled pending timeouts */
 352         hci1394_tlist_timeout_cancel(async_handle->as_pending_list);
 353 
 354         TNF_PROBE_0_DEBUG(hci1394_async_suspend_exit,
 355             HCI1394_TNF_HAL_STACK, "");
 356 }
 357 
 358 
 359 /*
 360  * hci1394_async_resume()
 361  *    Re-setup the DMA Q's during a resume after a successful suspend. The
 362  *    tlabels will be re-initialized during the bus reset and the pending Q will
 363  *    be flushed during the suspend.
 364  */
 365 int
 366 hci1394_async_resume(hci1394_async_handle_t async_handle)
 367 {
 368         ASSERT(async_handle != NULL);
 369         TNF_PROBE_0_DEBUG(hci1394_async_resume_enter,
 370             HCI1394_TNF_HAL_STACK, "");
 371 
 372         hci1394_q_resume(async_handle->as_atreq_q);
 373         hci1394_q_resume(async_handle->as_atresp_q);
 374         hci1394_q_resume(async_handle->as_arreq_q);
 375         hci1394_q_resume(async_handle->as_arresp_q);
 376 
 377         TNF_PROBE_0_DEBUG(hci1394_async_resume_exit,
 378             HCI1394_TNF_HAL_STACK, "");
 379 
 380         return (DDI_SUCCESS);
 381 }
 382 
 383 
 384 /*
 385  * hci1394_async_cmd_overhead()
 386  *    Return the size of the HAL private area to attach to every alloced 1394
 387  *    framework command.  This allows us to track command state without having
 388  *    to alloc memory every time a command comes down the pipe.
 389  */
 390 uint_t
 391 hci1394_async_cmd_overhead()
 392 {
 393         return (sizeof (hci1394_async_cmd_t));
 394 }
 395 
 396 
 397 /*
 398  * hci1394_async_flush()
 399  *    Flush out the Async Q's and the ATREQ pending list.  This is called every
 400  *    bus reset so that we're sync'd up with the HW and when shutting down or
 401  *    suspending to make sure we cleanup after all commands.
 402  */
 403 void
 404 hci1394_async_flush(hci1394_async_handle_t async_handle)
 405 {
 406         ASSERT(async_handle != NULL);
 407         TNF_PROBE_0_DEBUG(hci1394_async_flush_enter, HCI1394_TNF_HAL_STACK, "");
 408 
 409         hci1394_async_atreq_flush(async_handle);
 410         hci1394_async_arresp_flush(async_handle);
 411         hci1394_async_pending_list_flush(async_handle);
 412         hci1394_async_arreq_flush(async_handle);
 413         hci1394_async_atresp_flush(async_handle);
 414         hci1394_tlabel_reset(async_handle->as_tlabel);
 415 
 416         TNF_PROBE_0_DEBUG(hci1394_async_flush_exit, HCI1394_TNF_HAL_STACK, "");
 417 }
 418 
 419 
 420 /*
 421  * hci1394_async_pending_timeout_update()
 422  *    Update the timeout for the pending list. This updates both the pending
 423  *    list timeout and time we wait to reclaim  bad tlabels.  timeout is the
 424  *    time in nS so we do not have to do any conversions. This routine will be
 425  *    called when the CSR split timeout registers are updated.
 426  */
 427 void
 428 hci1394_async_pending_timeout_update(hci1394_async_handle_t async_handle,
 429     hrtime_t timeout)
 430 {
 431         ASSERT(async_handle != NULL);
 432         TNF_PROBE_0_DEBUG(hci1394_async_pending_timeout_update_enter,
 433             HCI1394_TNF_HAL_STACK, "");
 434         hci1394_tlist_timeout_update(async_handle->as_pending_list, timeout);
 435         hci1394_tlabel_set_reclaim_time(async_handle->as_tlabel, timeout);
 436         TNF_PROBE_0_DEBUG(hci1394_async_pending_timeout_update_exit,
 437             HCI1394_TNF_HAL_STACK, "");
 438 }
 439 
 440 
 441 /*
 442  * hci1394_async_atreq_process()
 443  *    Process an atreq, if one has completed. This is called during interrupt
 444  *    processing and will process a completed atreq. It returns status if an
 445  *    atreq was processed so that the ISR knows that it needs to be called
 446  *    again to see if another ATREQ has completed. flush_q set to B_TRUE tells
 447  *    this routine to process all commands regardless of their completion
 448  *    status.  This is used during bus reset processing to remove all commands
 449  *    from the Q.
 450  *
 451  *    There are a few race conditions that we have to watch for in atreq/arresp.
 452  *    They all have to do with pended responses so they are not applicable in
 453  *    the ARREQ/ATRESP engine (since ATRESP's can't be pended).
 454  *
 455  *    Since the race conditions only exist for pended responses, we will only
 456  *    talk about that sequence here. We're also going to simplify the discussion
 457  *    so what the code does, so it won't exactly match what we say (e.g. we
 458  *    don't always setup a timeout for every single command, etc.)
 459  *
 460  *    After Q'ing up an ATREQ, we will process the result of that command in
 461  *    one of a couple different paths. A normal condition would be that we Q up
 462  *    a command, we get an ATREQ complete interrupt and look at the ATREQ
 463  *    result. In the case it has been pended, we setup a timeout to wait for the
 464  *    response. If we receive the response before the timeout, the command is
 465  *    done and we send the response up the chain, if we do not, the command is
 466  *    done and we send a timeout notification up the chain.
 467  *
 468  *    The first race condition is when we get the timeout at the same time as
 469  *    the response. At first glance a mutex around the command state would
 470  *    solve this problem. But on a multi-processor machine, we may have the
 471  *    ARRESP interrupt handler(ISR) running on one processor and the timeout on
 472  *    another. This means that the command state could change between two
 473  *    reads while in the ISR. This means we need to have a little more complex
 474  *    logic around changing the command state and have to be careful how and
 475  *    when we do this.
 476  *
 477  *    The second race condition is that we could see the ARRESP before we
 478  *    process the ATREQ. We could be processing a few ARRESP from previous
 479  *    ATREQ's when the ATREQ completes and then the ARRESP comes in.  Since we
 480  *    already are in the interrupt handler, the ATREQ complete will not preempt
 481  *    us.
 482  *
 483  *    We will never see a race condition between the ATREQ interrupt for a
 484  *    command and the pending timeout since the command is not being timed until
 485  *    this routine is run for that command.
 486  */
 487 int
 488 hci1394_async_atreq_process(hci1394_async_handle_t async_handle,
 489     boolean_t flush_q, boolean_t *request_available)
 490 {
 491         hci1394_async_cmd_t *hcicmd;
 492         hci1394_q_cmd_t *qcmd;
 493         int cmd_status;
 494 
 495 
 496         ASSERT(async_handle != NULL);
 497         ASSERT(request_available != NULL);
 498 
 499         TNF_PROBE_0_DEBUG(hci1394_async_atreq_process_enter,
 500             HCI1394_TNF_HAL_STACK, "");
 501 
 502         /*
 503          * Get the next ATREQ that has completed (if one has). Space is free'd
 504          * up in atreq_q and atreq_data_q as part of this function call.
 505          */
 506         hci1394_q_at_next(async_handle->as_atreq_q, flush_q, &qcmd);
 507 
 508         /*
 509          * See if there were anymore requests on ATREQ Q. A NULL means there
 510          * were no completed commands left on the Q
 511          */
 512         if (qcmd == NULL) {
 513                 *request_available = B_FALSE;
 514                 TNF_PROBE_0_DEBUG(hci1394_async_atreq_process_exit,
 515                     HCI1394_TNF_HAL_STACK, "");
 516                 return (DDI_SUCCESS);
 517         }
 518 
 519         /* There is a completed ATREQ, setup the HAL command pointer */
 520         *request_available = B_TRUE;
 521         hcicmd = (hci1394_async_cmd_t *)qcmd->qc_arg;
 522 
 523         TNF_PROBE_1_DEBUG(hci1394_atreq_ack, HCI1394_TNF_HAL, "", tnf_uint,
 524             atreq_ack, qcmd->qc_status);
 525 
 526         /* save away the command completed timestamp for the services layer */
 527         hcicmd->ac_priv->ack_tstamp = qcmd->qc_timestamp;
 528 
 529         /*
 530          * Make sure this command has not already been processed. This command
 531          * may have already received a response.  If the ACK was not an ACK
 532          * pending, we have a HW error (i.e. The target HW sent a response to a
 533          * non-pended request). There is a race condition where the software
 534          * will see and complete a response before processing it's ACK Pending.
 535          * This can only happen for ACK pendings. We have seen this race
 536          * condition and response to a non-pended request during real-world
 537          * testing :-)
 538          */
 539         if (hcicmd->ac_state != HCI1394_CMD_STATE_IN_PROGRESS) {
 540                 /*
 541                  * we already processed the ARRESP in arresp_process(), it
 542                  * better have been ACK pended. Otherwise the target device
 543                  * performed an illegal action.
 544                  */
 545                 if (qcmd->qc_status == OHCI_ACK_PENDING) {
 546                         /*
 547                          * Tell source that their command has completed. We're
 548                          * done with this command.
 549                          * NOTE: We use ac_status which was set in
 550                          * process_arresp()
 551                          */
 552                         h1394_cmd_is_complete(
 553                             async_handle->as_drvinfo->di_sl_private,
 554                             hcicmd->ac_cmd, H1394_AT_REQ,
 555                             hcicmd->ac_status);
 556                         TNF_PROBE_0_DEBUG(hci1394_async_atreq_process_exit,
 557                             HCI1394_TNF_HAL_STACK, "");
 558                         return (DDI_SUCCESS);
 559                 /*
 560                  * This is a HW error.  Process the ACK like we never saw the
 561                  * response. We will do this below.
 562                  */
 563                 } else {
 564                         TNF_PROBE_1(hci1394_async_ack_fail,
 565                             HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
 566                             "response sent to non-pended ack");
 567                 }
 568         }
 569 
 570         /*
 571          * if we got an ack pending, add it to the pending list and leave. We
 572          * will either get an ARRESP or the pending list will timeout the
 573          * response.
 574          */
 575         if (qcmd->qc_status == OHCI_ACK_PENDING) {
 576                 hcicmd->ac_state = HCI1394_CMD_STATE_PENDING;
 577                 /* Add this command to the pending list */
 578                 hcicmd->ac_plist_node.tln_addr = hcicmd;
 579                 hci1394_tlist_add(async_handle->as_pending_list,
 580                     &hcicmd->ac_plist_node);
 581                 TNF_PROBE_0_DEBUG(hci1394_async_atreq_process_exit,
 582                     HCI1394_TNF_HAL_STACK, "");
 583                 return (DDI_SUCCESS);
 584         }
 585 
 586         /*
 587          * setup our return command status based on the ACK from the HW. See the
 588          * OpenHCI 1.0 spec (table 3.2 on pg. 18) for more information about
 589          * these ACK/EVT's.
 590          */
 591         switch (qcmd->qc_status) {
 592         case OHCI_ACK_COMPLETE:
 593                 cmd_status = H1394_CMD_SUCCESS;
 594                 break;
 595 
 596         /*
 597          * we can get a nostatus during a bus reset (i.e. we shutdown the AT
 598          * engine before it flushed all the commands)
 599          */
 600         case OHCI_EVT_FLUSHED:
 601         case OHCI_EVT_NO_STATUS:
 602                 cmd_status = H1394_CMD_EBUSRESET;
 603                 break;
 604 
 605         case OHCI_EVT_MISSING_ACK:
 606         case OHCI_EVT_TIMEOUT:
 607                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 608                     "", tnf_uint, nodeid,
 609                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 610                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 611                     tnf_uint, atreq_ack, qcmd->qc_status);
 612                 cmd_status = H1394_CMD_ETIMEOUT;
 613                 break;
 614 
 615         case OHCI_ACK_BUSY_X:
 616         case OHCI_ACK_BUSY_A:
 617         case OHCI_ACK_BUSY_B:
 618                 cmd_status = H1394_CMD_EDEVICE_BUSY;
 619                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 620                     "", tnf_uint, nodeid,
 621                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 622                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 623                     tnf_uint, atreq_ack, qcmd->qc_status);
 624                 break;
 625 
 626         case OHCI_ACK_TARDY:
 627                 cmd_status = H1394_CMD_EDEVICE_POWERUP;
 628                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 629                     "", tnf_uint, nodeid,
 630                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 631                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 632                     tnf_uint, atreq_ack, qcmd->qc_status);
 633                 break;
 634 
 635         case OHCI_ACK_DATA_ERROR:
 636                 cmd_status = H1394_CMD_EDATA_ERROR;
 637                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 638                     "", tnf_uint, nodeid,
 639                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 640                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 641                     tnf_uint, atreq_ack, qcmd->qc_status);
 642                 break;
 643 
 644         case OHCI_ACK_TYPE_ERROR:
 645                 cmd_status = H1394_CMD_ETYPE_ERROR;
 646                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 647                     "", tnf_uint, nodeid,
 648                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 649                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 650                     tnf_uint, atreq_ack, qcmd->qc_status);
 651                 break;
 652 
 653         case OHCI_ACK_CONFLICT_ERROR:
 654                 cmd_status = H1394_CMD_ERSRC_CONFLICT;
 655                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 656                     "", tnf_uint, nodeid,
 657                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 658                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 659                     tnf_uint, atreq_ack, qcmd->qc_status);
 660                 break;
 661 
 662         case OHCI_ACK_ADDRESS_ERROR:
 663                 cmd_status = H1394_CMD_EADDR_ERROR;
 664                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 665                     "", tnf_uint, nodeid,
 666                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 667                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 668                     tnf_uint, atreq_ack, qcmd->qc_status);
 669                 break;
 670 
 671         case OHCI_EVT_UNDERRUN:
 672         case OHCI_EVT_DATA_READ:
 673         case OHCI_EVT_TCODE_ERR:
 674         case OHCI_EVT_DESCRIPTOR_READ:
 675         case OHCI_EVT_UNKNOWN:
 676         default:
 677                 cmd_status = H1394_CMD_EUNKNOWN_ERROR;
 678                 TNF_PROBE_3(hci1394_atreq_ack_err, HCI1394_TNF_HAL_ERROR,
 679                     "", tnf_uint, nodeid,
 680                     IEEE1394_NODE_NUM(hcicmd->ac_tlabel.tbi_destination),
 681                     tnf_uint, tx_tlabel, hcicmd->ac_tlabel.tbi_tlabel,
 682                     tnf_uint, atreq_ack, qcmd->qc_status);
 683                 break;
 684         }
 685 
 686         /*
 687          * Free the tlabel that was used for this transfer. We will not try and
 688          * free the tlabel in the case that we already received a response or if
 689          * we did not allocate one (PHY packet). If we already received a
 690          * response, the tlabel would have been free'd in
 691          * hci1394_async_arresp_process().
 692          */
 693         if ((hcicmd->ac_state == HCI1394_CMD_STATE_IN_PROGRESS) &&
 694             (hcicmd->ac_tlabel_alloc == B_TRUE)) {
 695                 hci1394_tlabel_free(async_handle->as_tlabel,
 696                     &hcicmd->ac_tlabel);
 697         }
 698 
 699         /*
 700          * if we got anything other than and ACK pending, we are done w/ this
 701          * transaction.
 702          */
 703         hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
 704 
 705         /* tell the services layer that the command has completed */
 706         h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
 707             hcicmd->ac_cmd, H1394_AT_REQ, cmd_status);
 708 
 709         TNF_PROBE_0_DEBUG(hci1394_async_atreq_process_exit,
 710             HCI1394_TNF_HAL_STACK, "");
 711 
 712         return (DDI_SUCCESS);
 713 }
 714 
 715 
 716 /*
 717  * hci1394_async_arresp_process()
 718  *    Process an arresp, if one has completed. This is called during interrupt
 719  *    processing and will process a completed arresp. It returns status if an
 720  *    arresp was processed so that the ISR knows that it needs to be called
 721  *    again to see if another ARRESP has completed.
 722  */
 723 int
 724 hci1394_async_arresp_process(hci1394_async_handle_t async_handle,
 725     boolean_t *response_available)
 726 {
 727         hci1394_async_cmd_t *hcicmd;
 728         uint32_t *addr;
 729         int cmd_status;
 730         uint_t tcode;
 731         uint_t size;
 732         int status;
 733 
 734 
 735         ASSERT(async_handle != NULL);
 736         ASSERT(response_available != NULL);
 737 
 738         TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_enter,
 739             HCI1394_TNF_HAL_STACK, "");
 740 
 741         /*
 742          * See if there were any responses on ARRESP Q. A NULL means there
 743          * were no responses on the Q. This call does NOT free up space. We
 744          * need to do that later after we figure out how much space the
 745          * response takes up.
 746          */
 747         hci1394_q_ar_next(async_handle->as_arresp_q, &addr);
 748         if (addr == NULL) {
 749                 *response_available = B_FALSE;
 750                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_exit,
 751                     HCI1394_TNF_HAL_STACK, "");
 752                 return (DDI_SUCCESS);
 753         }
 754 
 755         /*
 756          * We got a response. Lock out pending timeout callback from marking
 757          * tlabel bad.
 758          */
 759         *response_available = B_TRUE;
 760         mutex_enter(&async_handle->as_atomic_lookup);
 761 
 762         /*
 763          * Read in the response into the 1394 framework command. We could get a
 764          * NULL for a command if we got a response with an error (i.e. tlabel
 765          * that didn't match a request) This would be a successful read but with
 766          * a NULL hcicmd returned. If we ever get a DDI_FAILURE, we will
 767          * shutdown.
 768          */
 769         status = hci1394_async_arresp_read(async_handle,
 770             (hci1394_basic_pkt_t *)addr, &tcode, &hcicmd, &size);
 771         if (status != DDI_SUCCESS) {
 772                 mutex_exit(&async_handle->as_atomic_lookup);
 773                 h1394_error_detected(async_handle->as_drvinfo->di_sl_private,
 774                     H1394_SELF_INITIATED_SHUTDOWN, NULL);
 775                 cmn_err(CE_WARN, "hci1394(%d): driver shutdown: "
 776                     "unrecoverable error interrupt detected",
 777                     async_handle->as_drvinfo->di_instance);
 778                 hci1394_shutdown(async_handle->as_drvinfo->di_dip);
 779                 TNF_PROBE_0(hci1394_async_arresp_read_fail,
 780                     HCI1394_TNF_HAL_ERROR, "");
 781                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_exit,
 782                     HCI1394_TNF_HAL_STACK, "");
 783                 return (DDI_FAILURE);
 784         }
 785 
 786         /* Free up the arresp Q space, we are done with the data */
 787         hci1394_q_ar_free(async_handle->as_arresp_q, size);
 788 
 789         /*
 790          * if we did not get a valid command response (i.e. we got a bad tlabel
 791          * or something like that) we don't have anything else to do.  We will
 792          * say that we processed a response and will return successfully. We
 793          * still may have other responses on the Q.
 794          */
 795         if (hcicmd == NULL) {
 796                 mutex_exit(&async_handle->as_atomic_lookup);
 797                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_exit,
 798                     HCI1394_TNF_HAL_STACK, "");
 799                 return (DDI_SUCCESS);
 800         }
 801 
 802         TNF_PROBE_1_DEBUG(hci1394_arresp_resp, HCI1394_TNF_HAL, "", tnf_uint,
 803             atresp_resp, hcicmd->ac_status);
 804 
 805         /*
 806          * Make sure this is in the pending list. There is a small chance that
 807          * we will see the response before we see the ACK PENDING. If it is the
 808          * expected case, it is in the pending list.  We will remove it since
 809          * we are done with the command.
 810          *
 811          * NOTE: there is a race condition here with the pending timeout.  Look
 812          * at the comments before hci1394_async_atreq_process() for more info.
 813          */
 814         if (hcicmd->ac_state == HCI1394_CMD_STATE_PENDING) {
 815                 /* remove this transfer from our the pending list */
 816                 status = hci1394_tlist_delete(async_handle->as_pending_list,
 817                     &hcicmd->ac_plist_node);
 818                 if (status != DDI_SUCCESS) {
 819                         mutex_exit(&async_handle->as_atomic_lookup);
 820                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_exit,
 821                             HCI1394_TNF_HAL_STACK, "");
 822                         return (DDI_SUCCESS);
 823                 }
 824         }
 825 
 826         /* allow pending timeout callback to mark tlabel as bad */
 827         mutex_exit(&async_handle->as_atomic_lookup);
 828 
 829         /*
 830          * We got a valid response that we were able to read in. Free the tlabel
 831          * that was used for this transfer.
 832          */
 833         hci1394_tlabel_free(async_handle->as_tlabel, &hcicmd->ac_tlabel);
 834 
 835         /*
 836          * Setup our return command status based on the RESP or ACK or SW error.
 837          * See the IEEE1394-1995 spec (6.2.4.10 on pg. 159) for more information
 838          * on response codes. See the OpenHCI 1.0 spec (table 3.2 on pg. 18) for
 839          * more information about ACK/EVT's. ac_status could have an IEEE1394
 840          * response in it, a 1394 EVT/ACK, or a special cmd1394 error for a
 841          * device error caught in SW (e.g. for a block read request that got a
 842          * quadlet read response). We use a special mask to separate the
 843          * ACK/EVT's from the responses (ASYNC_ARRESP_ACK_ERROR).
 844          */
 845         switch (hcicmd->ac_status) {
 846         case IEEE1394_RESP_COMPLETE:
 847                 cmd_status = H1394_CMD_SUCCESS;
 848                 break;
 849         case IEEE1394_RESP_DATA_ERROR:
 850                 cmd_status = H1394_CMD_EDATA_ERROR;
 851                 break;
 852         case IEEE1394_RESP_TYPE_ERROR:
 853                 cmd_status = H1394_CMD_ETYPE_ERROR;
 854                 break;
 855         case IEEE1394_RESP_CONFLICT_ERROR:
 856                 cmd_status = H1394_CMD_ERSRC_CONFLICT;
 857                 break;
 858         case IEEE1394_RESP_ADDRESS_ERROR:
 859                 cmd_status = H1394_CMD_EADDR_ERROR;
 860                 break;
 861         case H1394_CMD_EDEVICE_ERROR:
 862                 cmd_status = H1394_CMD_EDEVICE_ERROR;
 863                 break;
 864         case OHCI_ACK_DATA_ERROR | ASYNC_ARRESP_ACK_ERROR:
 865                 cmd_status = H1394_CMD_EDATA_ERROR;
 866                 break;
 867         case OHCI_ACK_TYPE_ERROR | ASYNC_ARRESP_ACK_ERROR:
 868                 cmd_status = H1394_CMD_ETYPE_ERROR;
 869                 break;
 870         case OHCI_EVT_UNDERRUN | ASYNC_ARRESP_ACK_ERROR:
 871         case OHCI_EVT_DATA_READ | ASYNC_ARRESP_ACK_ERROR:
 872         case OHCI_EVT_TCODE_ERR | ASYNC_ARRESP_ACK_ERROR:
 873                 cmd_status = H1394_CMD_EUNKNOWN_ERROR;
 874                 break;
 875         default:
 876                 cmd_status = H1394_CMD_EUNKNOWN_ERROR;
 877                 TNF_PROBE_1(hci1394_async_ack_err, HCI1394_TNF_HAL_ERROR,
 878                     "", tnf_uint, arresp_resp, hcicmd->ac_status);
 879                 break;
 880         }
 881 
 882         /*
 883          * if we have already processed the atreq and put it on the pending Q
 884          * (normal case), tell the services layer it completed.
 885          */
 886         if (hcicmd->ac_state == HCI1394_CMD_STATE_PENDING) {
 887                 /* Set state indicating that we are done with this cmd */
 888                 hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
 889 
 890                 /* tell the services lyaer the command has completed */
 891                 h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
 892                     hcicmd->ac_cmd, H1394_AT_REQ, cmd_status);
 893 
 894         /*
 895          * We have not seen the atreq status yet.  We will call
 896          * h1394_command_is_complete() in atreq_process() in case we did not get
 897          * an ack pending (target HW error -> this is based on real world
 898          * experience :-))
 899          */
 900         } else {
 901                 /* Set state indicating that we are done with this cmd */
 902                 hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
 903 
 904                 /* save away the status for atreq_process() */
 905                 hcicmd->ac_status = cmd_status;
 906         }
 907 
 908         TNF_PROBE_0_DEBUG(hci1394_async_arresp_process_exit,
 909             HCI1394_TNF_HAL_STACK, "");
 910 
 911         return (DDI_SUCCESS);
 912 }
 913 
 914 
 915 /*
 916  * hci1394_async_arreq_process()
 917  *    Process an arreq, if one has arrived. This is called during interrupt
 918  *    processing and will process an arreq that has arrived. It returns status
 919  *    if an arreq was processed so that the ISR knows that it needs to be
 920  *    called again to see if another ARREQ has arrived.
 921  */
 922 int
 923 hci1394_async_arreq_process(hci1394_async_handle_t async_handle,
 924     boolean_t *request_available)
 925 {
 926         hci1394_async_cmd_t *hcicmd;
 927         uint32_t *addr;
 928         uint_t tcode;
 929         uint_t size;
 930         int status;
 931 
 932 
 933         ASSERT(async_handle != NULL);
 934         ASSERT(request_available != NULL);
 935 
 936         TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_enter,
 937             HCI1394_TNF_HAL_STACK, "");
 938 
 939         /*
 940          * See if there were any requests on ARREQ Q. A NULL means there
 941          * were no requests on the Q. This call does NOT free up space. We
 942          * need to do that later after we figure out how much space the
 943          * request takes up.
 944          */
 945         hci1394_q_ar_next(async_handle->as_arreq_q, &addr);
 946         if (addr == NULL) {
 947                 *request_available = B_FALSE;
 948                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_exit,
 949                     HCI1394_TNF_HAL_STACK, "");
 950                 return (DDI_SUCCESS);
 951         }
 952 
 953         /*
 954          * We got a request. Read the request into a 1394 framework command.
 955          * We could get a NULL for a command if we got a request with an error
 956          * (i.e. ARREQ ACK was not ack pending or ack complete). This would be a
 957          * successful read but with a NULL hcicmd returned. If we ever get a
 958          * DDI_FAILURE, we will shutdown.
 959          */
 960         *request_available = B_TRUE;
 961         status = hci1394_async_arreq_read(async_handle,
 962             (hci1394_basic_pkt_t *)addr, &tcode, &hcicmd, &size);
 963         if (status != DDI_SUCCESS) {
 964                 h1394_error_detected(async_handle->as_drvinfo->di_sl_private,
 965                     H1394_SELF_INITIATED_SHUTDOWN, NULL);
 966                 cmn_err(CE_WARN, "hci1394(%d): driver shutdown: "
 967                     "unrecoverable error interrupt detected",
 968                     async_handle->as_drvinfo->di_instance);
 969                 hci1394_shutdown(async_handle->as_drvinfo->di_dip);
 970                 TNF_PROBE_0(hci1394_async_arreq_read_fail,
 971                     HCI1394_TNF_HAL_ERROR, "");
 972                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_exit,
 973                     HCI1394_TNF_HAL_STACK, "");
 974                 return (DDI_FAILURE);
 975         }
 976 
 977         /* Free up the arreq Q space, we are done with the data */
 978         hci1394_q_ar_free(async_handle->as_arreq_q, size);
 979 
 980         /*
 981          * if we did not get a valid request (i.e. The ARREQ had a bad ACK
 982          * or something like that) we don't have anything else to do.  We will
 983          * say that we processed a request and will return successfully. We
 984          * still may have other requests on the Q.
 985          */
 986         if (hcicmd == NULL) {
 987                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_exit,
 988                     HCI1394_TNF_HAL_STACK, "");
 989                 return (DDI_SUCCESS);
 990         }
 991 
 992         /*
 993          * If as_flushing_arreq is set, we do not want to send any requests up
 994          * to the Services Layer. We are flushing the ARREQ until we see a bus
 995          * reset token that matches the current bus generation. Free up the
 996          * alloc'd command and return success.
 997          */
 998         if (async_handle->as_flushing_arreq == B_TRUE) {
 999                 hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
1000                     hcicmd->ac_priv);
1001                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_exit,
1002                     HCI1394_TNF_HAL_STACK, "");
1003                 return (DDI_SUCCESS);
1004         }
1005 
1006         TNF_PROBE_1_DEBUG(hci1394_arreq_ack, HCI1394_TNF_HAL, "", tnf_uint,
1007             arreq_ack, hcicmd->ac_status);
1008 
1009         /*
1010          * We got a valid request that we were able to read in. Call into the
1011          * services layer based on the type of request.
1012          */
1013         switch (tcode) {
1014         case IEEE1394_TCODE_READ_QUADLET:
1015         case IEEE1394_TCODE_READ_BLOCK:
1016                 h1394_read_request(async_handle->as_drvinfo->di_sl_private,
1017                     hcicmd->ac_cmd);
1018                 break;
1019         case IEEE1394_TCODE_WRITE_QUADLET:
1020         case IEEE1394_TCODE_WRITE_BLOCK:
1021                 h1394_write_request(async_handle->as_drvinfo->di_sl_private,
1022                     hcicmd->ac_cmd);
1023                 break;
1024         case IEEE1394_TCODE_LOCK:
1025                 h1394_lock_request(async_handle->as_drvinfo->di_sl_private,
1026                     hcicmd->ac_cmd);
1027                 break;
1028         case IEEE1394_TCODE_PHY:
1029                 /*
1030                  * OpenHCI only handles 1 PHY quadlet at a time. If a selfid
1031                  * packet was received with multiple quadlets, we will treat
1032                  * each quadlet as a separate call.  We do not notify the
1033                  * services layer through the normal command interface, we will
1034                  * treat it like a command internally and then free up the
1035                  * command ourselves when we are done with it.
1036                  */
1037                 h1394_phy_packet(async_handle->as_drvinfo->di_sl_private,
1038                     &hcicmd->ac_cmd->cmd_u.q.quadlet_data, 1,
1039                     hcicmd->ac_priv->recv_tstamp);
1040                 /* free alloc'd command */
1041                 hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
1042                     hcicmd->ac_priv);
1043                 break;
1044         default:
1045                 /* free alloc'd command */
1046                 hci1394_async_response_complete(async_handle, hcicmd->ac_cmd,
1047                     hcicmd->ac_priv);
1048                 TNF_PROBE_1(hci1394_async_arreq_tcode_err,
1049                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_tcode, tcode);
1050                 break;
1051         }
1052 
1053         TNF_PROBE_0_DEBUG(hci1394_async_arreq_process_exit,
1054             HCI1394_TNF_HAL_STACK, "");
1055 
1056         return (DDI_SUCCESS);
1057 }
1058 
1059 
1060 /*
1061  * hci1394_async_atresp_process()
1062  *    Process an atresp, if one has completed. This is called during interrupt
1063  *    processing and will process a completed atresp. It returns status if an
1064  *    atresp was processed so that the ISR knows that it needs to be called
1065  *    again to see if another ATRESP has completed. flush_q set to B_TRUE tells
1066  *    this routine to process all commands regardless of their completion
1067  *    status.  This is used during bus reset processing to remove all commands
1068  *    from the Q.
1069  */
1070 int
1071 hci1394_async_atresp_process(hci1394_async_handle_t async_handle,
1072     boolean_t flush_q, boolean_t *response_available)
1073 {
1074         hci1394_async_cmd_t *hcicmd;
1075         hci1394_q_cmd_t *qcmd;
1076         int cmd_status;
1077 
1078 
1079         ASSERT(async_handle != NULL);
1080         ASSERT(response_available != NULL);
1081 
1082         TNF_PROBE_0_DEBUG(hci1394_async_atresp_process_enter,
1083             HCI1394_TNF_HAL_STACK, "");
1084 
1085         /*
1086          * Get the next ATRESP that has completed (if one has). Space is free'd
1087          * up in atresp_q and atresp_data_q as part of this function call.
1088          */
1089         hci1394_q_at_next(async_handle->as_atresp_q, flush_q, &qcmd);
1090 
1091         /*
1092          * See if there were anymore requests on ATRESP Q. A NULL means there
1093          * were no completed commands left on the Q.
1094          */
1095         if (qcmd == NULL) {
1096                 *response_available = B_FALSE;
1097                 TNF_PROBE_0_DEBUG(hci1394_async_atresp_process_exit,
1098                     HCI1394_TNF_HAL_STACK, "");
1099                 return (DDI_SUCCESS);
1100         }
1101 
1102         /* There is a completed ATRESP, setup the HAL command pointer */
1103         *response_available = B_TRUE;
1104         hcicmd = (hci1394_async_cmd_t *)qcmd->qc_arg;
1105 
1106         TNF_PROBE_1_DEBUG(hci1394_atresp_ack, HCI1394_TNF_HAL, "", tnf_uint,
1107             atresp_ack, qcmd->qc_status);
1108 
1109         /* save away the command completed timestamp for the services layer */
1110         hcicmd->ac_priv->ack_tstamp = qcmd->qc_timestamp;
1111 
1112         /*
1113          * setup our return command status based on the ACK from the HW. See the
1114          * OpenHCI 1.0 spec (table 3.2 on pg. 18) for more information about
1115          * these ACK/EVT's.
1116          */
1117         switch (qcmd->qc_status) {
1118         case OHCI_ACK_COMPLETE:
1119                 cmd_status = H1394_CMD_SUCCESS;
1120                 break;
1121 
1122         /*
1123          * we can get a nostatus during a bus reset (i.e. we shutdown the AT
1124          * engine before it flushed all the commands)
1125          */
1126         case OHCI_EVT_FLUSHED:
1127         case OHCI_EVT_NO_STATUS:
1128                 cmd_status = H1394_CMD_EBUSRESET;
1129                 break;
1130 
1131         case OHCI_EVT_MISSING_ACK:
1132         case OHCI_EVT_TIMEOUT:
1133                 cmd_status = H1394_CMD_ETIMEOUT;
1134                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1135                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1136                 break;
1137 
1138         case OHCI_ACK_BUSY_X:
1139         case OHCI_ACK_BUSY_A:
1140         case OHCI_ACK_BUSY_B:
1141                 cmd_status = H1394_CMD_EDEVICE_BUSY;
1142                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1143                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1144                 break;
1145 
1146         case OHCI_ACK_TARDY:
1147                 cmd_status = H1394_CMD_EDEVICE_POWERUP;
1148                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1149                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1150                 break;
1151 
1152         case OHCI_ACK_DATA_ERROR:
1153                 cmd_status = H1394_CMD_EDATA_ERROR;
1154                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1155                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1156                 break;
1157 
1158         case OHCI_ACK_TYPE_ERROR:
1159                 cmd_status = H1394_CMD_ETYPE_ERROR;
1160                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1161                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1162                 break;
1163 
1164         case OHCI_ACK_CONFLICT_ERROR:
1165                 cmd_status = H1394_CMD_ERSRC_CONFLICT;
1166                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1167                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1168                 break;
1169 
1170         case OHCI_ACK_ADDRESS_ERROR:
1171                 cmd_status = H1394_CMD_EADDR_ERROR;
1172                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1173                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1174                 break;
1175 
1176         case OHCI_EVT_UNKNOWN:
1177                 cmd_status = H1394_CMD_EUNKNOWN_ERROR;
1178                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1179                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1180                 break;
1181 
1182         case OHCI_EVT_UNDERRUN:
1183         case OHCI_EVT_DATA_READ:
1184         case OHCI_EVT_TCODE_ERR:
1185         case OHCI_EVT_DESCRIPTOR_READ:
1186         default:
1187                 cmd_status = H1394_CMD_EUNKNOWN_ERROR;
1188                 TNF_PROBE_1(hci1394_atresp_ack_err, HCI1394_TNF_HAL_ERROR,
1189                     "", tnf_uint, atresp_ack, qcmd->qc_status);
1190                 break;
1191         }
1192 
1193         /* tell the services layer that the command has completed */
1194         h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
1195             hcicmd->ac_cmd, H1394_AT_RESP, cmd_status);
1196 
1197         TNF_PROBE_0_DEBUG(hci1394_async_atresp_process_exit,
1198             HCI1394_TNF_HAL_STACK, "");
1199 
1200         return (DDI_SUCCESS);
1201 }
1202 
1203 
1204 /*
1205  * hci1394_async_arresp_read()
1206  *    Read ARRESP in from memory into 1394 Framework command. We read the tcode
1207  *    which tells us which kind of arresp the packet is, get the size of the
1208  *    response, read in the sender, tlabel, and response code, and then
1209  *    lookup the command based on the sender and tlabel. Once we get the command
1210  *    (corresponding to the ATREQ), we will copy the rest of the response into
1211  *    that command.
1212  *
1213  *    The only time this routine should return DDI_FAILURE is if it was unable
1214  *    to maintain a good state in the ARRESP Q (i.e. an unknown response was
1215  *    received and we can not cleanup after it.)  If we detect a recoverable
1216  *    error, and it doesn't make sense to pass the response up to the Services
1217  *    Layer, we should return DDI_SUCCESS with hcicmd = NULL.
1218  */
1219 static int
1220 hci1394_async_arresp_read(hci1394_async_handle_t async_handle,
1221     hci1394_basic_pkt_t *pkt,  uint_t *tcode, hci1394_async_cmd_t **hcicmd,
1222     uint_t *size)
1223 {
1224         hci1394_tlabel_info_t ac_tlabel;
1225         h1394_cmd_priv_t *cmd_priv;
1226         cmd1394_cmd_t *cmd;
1227         uint32_t *status_addr;
1228         uint_t data_length;
1229         uint32_t quadlet;
1230         void *command;
1231         uint_t rcode;
1232         uint_t ack;
1233         int status;
1234 
1235 
1236         ASSERT(async_handle != NULL);
1237         ASSERT(pkt != NULL);
1238         ASSERT(tcode != NULL);
1239         ASSERT(hcicmd != NULL);
1240         ASSERT(size != NULL);
1241 
1242         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_enter,
1243             HCI1394_TNF_HAL_STACK, "");
1244 
1245         /* read in the arresp tcode */
1246         quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q1);
1247         *tcode = HCI1394_DESC_TCODE_GET(quadlet);
1248 
1249         /* Get the size of the arresp */
1250         status = hci1394_async_arresp_size_get(*tcode,
1251             async_handle->as_arresp_q, &pkt->q1, size);
1252         if (status != DDI_SUCCESS) {
1253                 TNF_PROBE_0(hci1394_async_arresp_read_size_fail,
1254                     HCI1394_TNF_HAL_ERROR, "");
1255                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1256                     HCI1394_TNF_HAL_STACK, "");
1257                 return (DDI_FAILURE);
1258         }
1259 
1260         /* Read in the tlabel, destination, and rcode (response code) */
1261         quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q1);
1262         ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1263         quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, &pkt->q2);
1264         ac_tlabel.tbi_destination = HCI1394_DESC_DESTID_GET(quadlet);
1265         rcode = HCI1394_DESC_RCODE_GET(quadlet);
1266 
1267         /* Lookup the ATREQ framework command this response goes with */
1268         hci1394_tlabel_lookup(async_handle->as_tlabel, &ac_tlabel, &command);
1269 
1270         /*
1271          * If there is not a cooresponding ATREQ command, this is an error. We
1272          * will ignore this response but still return success so we cleanup
1273          * after it and go on with other arresp's. This could happend if a
1274          * response was sent after the command has timed out or if the target
1275          * device is misbehaving. (we have seen both cases)
1276          */
1277         *hcicmd = (hci1394_async_cmd_t *)command;
1278         if ((*hcicmd) == NULL) {
1279                 TNF_PROBE_2(hci1394_invalid_tlabel, HCI1394_TNF_HAL_ERROR,
1280                     "", tnf_uint, nodeid,
1281                     IEEE1394_NODE_NUM(ac_tlabel.tbi_destination), tnf_uint,
1282                     rx_tlabel, ac_tlabel.tbi_tlabel);
1283                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1284                     HCI1394_TNF_HAL_STACK, "");
1285                 return (DDI_SUCCESS);
1286         }
1287 
1288         /*
1289          * copy the response code into the hal private command space. Setup
1290          * shortcuts to the 1394 framework command (cmd) and the HAL/SL private
1291          * area (cmd_priv). A command is made up of 4 parts. There is the public
1292          * part which is accessable to the target driver, there is the Services
1293          * Layer private part which is only accessible to the services layer,
1294          * there is the SL/HAL private area which is where the SL and HAL share
1295          * information about a particular command, and there is the HAL private
1296          * area where we keep track of our command specific state information.
1297          */
1298         (*hcicmd)->ac_status = rcode;
1299         cmd = (*hcicmd)->ac_cmd;
1300         cmd_priv = (*hcicmd)->ac_priv;
1301 
1302         /*
1303          * Calculate the address where the status of the ARRESP and timestamp is
1304          * kept at.  It is the last quadlet in the response. Save away the
1305          * timestamp.
1306          */
1307         status_addr = (uint32_t *)((uintptr_t)pkt + (uintptr_t)*size -
1308             (uintptr_t)IEEE1394_QUADLET);
1309         quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q, status_addr);
1310         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1311 
1312         /*
1313          * if we did not get an ACK_COMPLETE, we will use the ack error instead
1314          * of the response in the packet for our status. We use special mask to
1315          * separate the reponses from the ACKs (ASYNC_ARRESP_ACK_ERROR). We will
1316          * return success with hcicmd set to the command so that this error gets
1317          * sent up to the Services Layer.
1318          */
1319         ack = HCI1394_DESC_EVT_GET(quadlet);
1320         if (ack != OHCI_ACK_COMPLETE) {
1321                 /* use the ack error instead of rcode for the command status */
1322                 (*hcicmd)->ac_status = ack | ASYNC_ARRESP_ACK_ERROR;
1323                 TNF_PROBE_1(hci1394_arresp_bad_ack, HCI1394_TNF_HAL_ERROR,
1324                     "", tnf_uint, arresp_ack, ack);
1325                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1326                     HCI1394_TNF_HAL_STACK, "");
1327                 return (DDI_SUCCESS);
1328         }
1329 
1330         TNF_PROBE_1_DEBUG(hci1394_atrresp_resp, HCI1394_TNF_HAL, "", tnf_uint,
1331             arresp_resp, rcode);
1332 
1333         /*
1334          * If we get to this point we have gotten a valid ACK on the response
1335          * and have matched up the response with an ATREQ. Now we check the
1336          * response code. If it is not resp_complete, we do not have anything
1337          * left to look at in the response. Return successfully.
1338          */
1339         if (rcode != IEEE1394_RESP_COMPLETE) {
1340                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1341                     HCI1394_TNF_HAL_STACK, "");
1342                 return (DDI_SUCCESS);
1343         }
1344 
1345         /*
1346          * Read the rest of the response (based on which kind of response it is)
1347          * into the 1394 framework command. In all of the different responses,
1348          * we check to make sure the response matches the original request. We
1349          * originally did not have this check but found a device or two which
1350          * did not behave very well and would cause us to corrupt our commands.
1351          * Now we check :-) We will return success when we get this error since
1352          * we can recover from it.
1353          */
1354         switch (*tcode) {
1355         case IEEE1394_TCODE_WRITE_RESP:
1356                 /*
1357                  * make sure the ATREQ was a quadlet/block write. The same
1358                  * response is sent back for those two type of ATREQs.
1359                  */
1360                 if ((cmd->cmd_type != CMD1394_ASYNCH_WR_QUAD) &&
1361                     (cmd->cmd_type != CMD1394_ASYNCH_WR_BLOCK)) {
1362                         (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1363                         TNF_PROBE_2(hci1394_async_arresp_lockresp_fail,
1364                             HCI1394_TNF_HAL_STACK, "", tnf_string, errmsg,
1365                             "Invalid response sent for write request", tnf_uint,
1366                             arresp_tcode, *tcode);
1367                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1368                             HCI1394_TNF_HAL_STACK, "");
1369                         return (DDI_SUCCESS);
1370                 }
1371                 break;
1372 
1373         case IEEE1394_TCODE_READ_QUADLET_RESP:
1374                 /* make sure the ATREQ was a quadlet read */
1375                 if (cmd->cmd_type != CMD1394_ASYNCH_RD_QUAD) {
1376                         (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1377                         TNF_PROBE_2(hci1394_async_arresp_lockresp_fail,
1378                             HCI1394_TNF_HAL_STACK, "", tnf_string, errmsg,
1379                             "Invalid response sent for qrd request", tnf_uint,
1380                             arresp_tcode, *tcode);
1381                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1382                             HCI1394_TNF_HAL_STACK, "");
1383                         return (DDI_SUCCESS);
1384                 }
1385 
1386                 /*
1387                  * read the quadlet read response in.  Data is treated as a byte
1388                  * stream.
1389                  */
1390                 hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1391                     (uint8_t *)&cmd->cmd_u.q.quadlet_data,
1392                     (uint8_t *)&pkt->q4, IEEE1394_QUADLET);
1393                 break;
1394 
1395         case IEEE1394_TCODE_READ_BLOCK_RESP:
1396                 /* make sure the ATREQ was a block read */
1397                 if (cmd->cmd_type != CMD1394_ASYNCH_RD_BLOCK) {
1398                         (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1399                         TNF_PROBE_2(hci1394_async_arresp_lockresp_fail,
1400                             HCI1394_TNF_HAL_STACK, "", tnf_string, errmsg,
1401                             "Invalid response sent for brd request", tnf_uint,
1402                             arresp_tcode, *tcode);
1403                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1404                             HCI1394_TNF_HAL_STACK, "");
1405                         return (DDI_SUCCESS);
1406                 }
1407 
1408                 /*
1409                  * read in the data length.  Make sure the data length is the
1410                  * same size as the read block request size that went out.
1411                  */
1412                 quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q,
1413                     &pkt->q4);
1414                 data_length = HCI1394_DESC_DATALEN_GET(quadlet);
1415                 if (data_length != cmd_priv->mblk.length) {
1416                         (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1417                         TNF_PROBE_3(hci1394_async_arresp_brdsz_fail,
1418                             HCI1394_TNF_HAL_STACK, "", tnf_string,
1419                             errmsg, "Block read response size is bad",
1420                             tnf_uint, requested_size, cmd_priv->mblk.length,
1421                             tnf_uint, response_size, data_length);
1422                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1423                             HCI1394_TNF_HAL_STACK, "");
1424                         return (DDI_SUCCESS);
1425                 }
1426 
1427                 /* Copy the read block data into the command mblk */
1428                 hci1394_q_ar_copy_to_mblk(async_handle->as_arresp_q,
1429                     (uint8_t *)&pkt->q5, &cmd_priv->mblk);
1430                 break;
1431 
1432         case IEEE1394_TCODE_LOCK_RESP:
1433                 /* read in the data length */
1434                 quadlet = hci1394_q_ar_get32(async_handle->as_arresp_q,
1435                     &pkt->q4);
1436                 data_length = HCI1394_DESC_DATALEN_GET(quadlet);
1437 
1438                 if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
1439                         /*
1440                          * read in the data length.  Make sure the data length
1441                          * is the valid for a lock32 response (1 quadlet)
1442                          */
1443                         if (data_length != IEEE1394_QUADLET) {
1444                                 (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1445                                 TNF_PROBE_2(hci1394_async_arresp_l32sz_fail,
1446                                     HCI1394_TNF_HAL_STACK, "", tnf_string,
1447                                     errmsg, "Invalid size for lock32 response",
1448                                     tnf_uint, data_size, data_length);
1449                                 TNF_PROBE_0_DEBUG(
1450                                     hci1394_async_arresp_read_exit,
1451                                     HCI1394_TNF_HAL_STACK, "");
1452                                 return (DDI_SUCCESS);
1453                         }
1454 
1455                         /*
1456                          * read the lock32 response in. Data is treated as a
1457                          * byte stream unless it is an arithmetic lock
1458                          * operation. In that case we treat data like a 32-bit
1459                          * word.
1460                          */
1461                         hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1462                             (uint8_t *)&cmd->cmd_u.l32.old_value,
1463                             (uint8_t *)&pkt->q5, IEEE1394_QUADLET);
1464                         cmd->cmd_u.l32.old_value = HCI1394_ARITH_LOCK_SWAP32(
1465                             cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.old_value);
1466 
1467                 } else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
1468                         /*
1469                          * read in the data length.  Make sure the data length
1470                          * is the valid for a lock64 response (1 octlet)
1471                          */
1472                         if (data_length != IEEE1394_OCTLET) {
1473                                 (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1474                                 TNF_PROBE_2(hci1394_async_arresp_l64sz_fail,
1475                                     HCI1394_TNF_HAL_STACK, "", tnf_string,
1476                                     errmsg, "Invalid size for lock64 response",
1477                                     tnf_uint, data_size, data_length);
1478                                 TNF_PROBE_0_DEBUG(
1479                                     hci1394_async_arresp_read_exit,
1480                                     HCI1394_TNF_HAL_STACK, "");
1481                                 return (DDI_SUCCESS);
1482                         }
1483 
1484                         /*
1485                          * read the lock64 response in. Data is treated as a
1486                          * byte stream unless it is an arithmetic lock
1487                          * operation. In that case we treat data like a 64-bit
1488                          * word.
1489                          */
1490                         hci1394_q_ar_rep_get8(async_handle->as_arresp_q,
1491                             (uint8_t *)&cmd->cmd_u.l64.old_value,
1492                             (uint8_t *)&pkt->q5, IEEE1394_OCTLET);
1493                         cmd->cmd_u.l64.old_value = HCI1394_ARITH_LOCK_SWAP64(
1494                             cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.old_value);
1495 
1496                 /*
1497                  * we sent out a request that was NOT a lock request and got
1498                  * back a lock response.
1499                  */
1500                 } else {
1501                         (*hcicmd)->ac_status = H1394_CMD_EDEVICE_ERROR;
1502                         TNF_PROBE_2(hci1394_async_arresp_lockresp_fail,
1503                             HCI1394_TNF_HAL_STACK, "", tnf_string, errmsg,
1504                             "Invalid response sent for lock request", tnf_uint,
1505                             arresp_tcode, *tcode);
1506                         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1507                             HCI1394_TNF_HAL_STACK, "");
1508                         return (DDI_SUCCESS);
1509                 }
1510                 break;
1511 
1512         default:
1513                 /* we got a tcode that we don't know about. Return error */
1514                 TNF_PROBE_2(hci1394_async_arresp_tcode_err,
1515                     HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
1516                     "unknown ARRESP received", tnf_uint, arresp_tcode, *tcode);
1517                 TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1518                     HCI1394_TNF_HAL_STACK, "");
1519                 return (DDI_FAILURE);
1520         }
1521 
1522         TNF_PROBE_0_DEBUG(hci1394_async_arresp_read_exit,
1523             HCI1394_TNF_HAL_STACK, "");
1524 
1525         return (DDI_SUCCESS);
1526 }
1527 
1528 
1529 /*
1530  * hci1394_async_arreq_read()
1531  *    Read ARREQ in from memory into a 1394 Framework command. Allocate a 1394
1532  *    framework command, read in the ARREQ, and before passing it up to the
1533  *    services layer, see if it was a valid broadcast request.
1534  *
1535  *    The only time this routine should return DDI_FAILURE is if it was unable
1536  *    to maintain a good state in the ARREQ Q (i.e. an unknown request was
1537  *    received and we can not cleanup after it.)  If we detect a recoverable
1538  *    error we should return DDI_SUCCESS with hcicmd = NULL.
1539  */
1540 static int
1541 hci1394_async_arreq_read(hci1394_async_handle_t async_handle,
1542     hci1394_basic_pkt_t *pkt, uint_t *tcode, hci1394_async_cmd_t **hcicmd,
1543     uint_t *size)
1544 {
1545         h1394_cmd_priv_t *cmd_priv;
1546         boolean_t is_reset_token;
1547         cmd1394_cmd_t *cmd;
1548         uint32_t quadlet;
1549         int status;
1550 
1551 
1552         ASSERT(async_handle != NULL);
1553         ASSERT(pkt != NULL);
1554         ASSERT(tcode != NULL);
1555         ASSERT(hcicmd != NULL);
1556         ASSERT(size != NULL);
1557 
1558         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_enter,
1559             HCI1394_TNF_HAL_STACK, "");
1560 
1561         /* read in the arresp tcode */
1562         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1563         *tcode = HCI1394_DESC_TCODE_GET(quadlet);
1564 
1565         /*
1566          * Allocated 1394 framework command.  The Services layer takes care of
1567          * cacheing commands. This is called during interrupt processing so we
1568          * do not want to sleep.
1569          */
1570         status = h1394_alloc_cmd(async_handle->as_drvinfo->di_sl_private,
1571             H1394_ALLOC_CMD_NOSLEEP, &cmd, &cmd_priv);
1572         if (status != DDI_SUCCESS) {
1573                 TNF_PROBE_0(hci1394_async_arreq_read_cmdalloc_fail,
1574                     HCI1394_TNF_HAL_ERROR, "");
1575                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1576                     HCI1394_TNF_HAL_STACK, "");
1577                 return (DDI_FAILURE);
1578         }
1579 
1580         /* Initialize the HAL private command info */
1581         hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, hcicmd);
1582 
1583         /*
1584          * There are two generations in the command structure, one in the public
1585          * space and one in the HAL/SL private shared space. We need to fill in
1586          * both.  We only use the private one internally.
1587          */
1588         cmd_priv->bus_generation = async_handle->as_drvinfo->di_gencnt;
1589         cmd->bus_generation = async_handle->as_drvinfo->di_gencnt;
1590 
1591         /*
1592          * Read the request (based on which kind of request it is) into the 1394
1593          * framework command.
1594          */
1595         switch (*tcode) {
1596         case IEEE1394_TCODE_READ_QUADLET:
1597                 /*
1598                  * We got a ARREQ quadlet read request. Read in the packet.
1599                  * If there is a problem with the packet (i.e. we don't get
1600                  * DDI_SUCCESS), we will free up the command and return NULL in
1601                  * hcicmd to indicate that we did not get a valid ARREQ to
1602                  * process.
1603                  */
1604                 status = hci1394_async_arreq_read_qrd(async_handle, pkt,
1605                     *hcicmd, size);
1606                 if (status != DDI_SUCCESS) {
1607                         hci1394_async_response_complete(async_handle, cmd,
1608                             cmd_priv);
1609                         *hcicmd = NULL;
1610                         TNF_PROBE_0(hci1394_async_arreq_read_qrd_fail,
1611                             HCI1394_TNF_HAL_ERROR, "");
1612                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1613                             HCI1394_TNF_HAL_STACK, "");
1614                         return (DDI_SUCCESS);
1615                 }
1616                 break;
1617 
1618         case IEEE1394_TCODE_WRITE_QUADLET:
1619                 /*
1620                  * We got a ARREQ quadlet write request. Read in the packet.
1621                  * If there is a problem with the packet (i.e. we don't get
1622                  * DDI_SUCCESS), we will free up the command and return NULL in
1623                  * hcicmd to indicate that we did not get a valid ARREQ to
1624                  * process.
1625                  */
1626                 status = hci1394_async_arreq_read_qwr(async_handle, pkt,
1627                     *hcicmd, size);
1628                 if (status != DDI_SUCCESS) {
1629                         hci1394_async_response_complete(async_handle, cmd,
1630                             cmd_priv);
1631                         *hcicmd = NULL;
1632                         TNF_PROBE_0(hci1394_async_arreq_read_qwr_fail,
1633                             HCI1394_TNF_HAL_ERROR, "");
1634                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1635                             HCI1394_TNF_HAL_STACK, "");
1636                         return (DDI_SUCCESS);
1637                 }
1638                 break;
1639 
1640         case IEEE1394_TCODE_READ_BLOCK:
1641                 /*
1642                  * We got a ARREQ block read request. Read in the packet.
1643                  * If there is a problem with the packet (i.e. we don't get
1644                  * DDI_SUCCESS), we will free up the command and return NULL in
1645                  * hcicmd to indicate that we did not get a valid ARREQ to
1646                  * process.
1647                  */
1648                 status = hci1394_async_arreq_read_brd(async_handle, pkt,
1649                     *hcicmd, size);
1650                 if (status != DDI_SUCCESS) {
1651                         hci1394_async_response_complete(async_handle, cmd,
1652                             cmd_priv);
1653                         *hcicmd = NULL;
1654                         TNF_PROBE_0(hci1394_async_arreq_read_brd_fail,
1655                             HCI1394_TNF_HAL_ERROR, "");
1656                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1657                             HCI1394_TNF_HAL_STACK, "");
1658                         return (DDI_SUCCESS);
1659                 }
1660                 break;
1661 
1662         case IEEE1394_TCODE_WRITE_BLOCK:
1663                 /*
1664                  * We got a ARREQ block write request. Read in the packet.
1665                  * If there is a problem with the packet (i.e. we don't get
1666                  * DDI_SUCCESS), we will free up the command and return NULL in
1667                  * hcicmd to indicate that we did not get a valid ARREQ to
1668                  * process.
1669                  */
1670                 status = hci1394_async_arreq_read_bwr(async_handle, pkt,
1671                     *hcicmd, size);
1672                 if (status != DDI_SUCCESS) {
1673                         hci1394_async_response_complete(async_handle, cmd,
1674                             cmd_priv);
1675                         *hcicmd = NULL;
1676                         TNF_PROBE_0(hci1394_async_arreq_read_bwr_fail,
1677                             HCI1394_TNF_HAL_ERROR, "");
1678                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1679                             HCI1394_TNF_HAL_STACK, "");
1680                         return (DDI_SUCCESS);
1681                 }
1682                 break;
1683 
1684         case IEEE1394_TCODE_LOCK:
1685                 /*
1686                  * We got a ARREQ lock request. Read in the packet.
1687                  * If there is a problem with the packet (i.e. we don't get
1688                  * DDI_SUCCESS), we will free up the command and return NULL in
1689                  * hcicmd to indicate that we did not get a valid ARREQ to
1690                  * process.
1691                  */
1692                 status = hci1394_async_arreq_read_lck(async_handle, pkt,
1693                     *hcicmd, size);
1694                 if (status != DDI_SUCCESS) {
1695                         hci1394_async_response_complete(async_handle, cmd,
1696                             cmd_priv);
1697                         *hcicmd = NULL;
1698                         TNF_PROBE_0(hci1394_async_arreq_read_lck_fail,
1699                             HCI1394_TNF_HAL_ERROR, "");
1700                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1701                             HCI1394_TNF_HAL_STACK, "");
1702                         return (DDI_SUCCESS);
1703                 }
1704                 break;
1705 
1706         case IEEE1394_TCODE_PHY:
1707                 /*
1708                  * We got a PHY packet in the ARREQ buffer. Read in the packet.
1709                  * If there is a problem with the packet (i.e. we don't get
1710                  * DDI_SUCCESS), we will free up the command and return NULL in
1711                  * hcicmd to indicate that we did not get a valid ARREQ to
1712                  * process.
1713                  */
1714                 status = hci1394_async_arreq_read_phy(async_handle, pkt,
1715                     *hcicmd, size, &is_reset_token);
1716                 if (status != DDI_SUCCESS) {
1717                         hci1394_async_response_complete(async_handle, cmd,
1718                             cmd_priv);
1719                         *hcicmd = NULL;
1720                         TNF_PROBE_0(hci1394_async_arreq_read_phy_fail,
1721                             HCI1394_TNF_HAL_ERROR, "");
1722                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1723                             HCI1394_TNF_HAL_STACK, "");
1724                         return (DDI_SUCCESS);
1725                 }
1726 
1727                 /*
1728                  * If we got a bus reset token, free up the command and return
1729                  * NULL in hcicmd to indicate that we did not get a valid ARREQ
1730                  * to process.
1731                  */
1732                 if (is_reset_token == B_TRUE) {
1733                         hci1394_async_response_complete(async_handle, cmd,
1734                             cmd_priv);
1735                         *hcicmd = NULL;
1736                         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1737                             HCI1394_TNF_HAL_STACK, "");
1738                         return (DDI_SUCCESS);
1739                 }
1740                 break;
1741 
1742         default:
1743                 /* we got a tcode that we don't know about. Return error */
1744                 TNF_PROBE_2(hci1394_async_arreq_tcode_err,
1745                     HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
1746                     "unknown ARREQ received", tnf_uint, arreq_tcode, *tcode);
1747                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1748                     HCI1394_TNF_HAL_STACK, "");
1749                 return (DDI_FAILURE);
1750         }
1751 
1752         /*
1753          * If this command was broadcast and it was not a write, drop the
1754          * command since it's an invalid request. We will free up the command
1755          * and return NULL in hcicmd to indicate that we did not get a valid
1756          * ARREQ to process.
1757          */
1758         if ((((*hcicmd)->ac_dest & IEEE1394_NODE_NUM_MASK) ==
1759             IEEE1394_BROADCAST_NODEID) && ((*tcode !=
1760             IEEE1394_TCODE_WRITE_QUADLET) && (*tcode !=
1761             IEEE1394_TCODE_WRITE_BLOCK))) {
1762                 hci1394_async_response_complete(async_handle, cmd, cmd_priv);
1763                 *hcicmd = NULL;
1764                 TNF_PROBE_0(hci1394_async_arreq_read_bcast_fail,
1765                     HCI1394_TNF_HAL_ERROR, "");
1766                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1767                     HCI1394_TNF_HAL_STACK, "");
1768                 return (DDI_SUCCESS);
1769 
1770         /*
1771          * It is a valid broadcast command, set that field in the public
1772          * command structure.
1773          */
1774         } else if ((((*hcicmd)->ac_dest & IEEE1394_NODE_NUM_MASK) ==
1775             IEEE1394_BROADCAST_NODEID)) {
1776                 cmd->broadcast = 1;
1777         }
1778 
1779         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
1780             HCI1394_TNF_HAL_STACK, "");
1781 
1782         return (DDI_SUCCESS);
1783 }
1784 
1785 
1786 /*
1787  * hci1394_async_arreq_read_qrd()
1788  *    Read ARREQ quadlet read into the 1394 Framework command. This routine will
1789  *    return DDI_FAILURE if it was not able to read the request succesfully.
1790  */
1791 static int
1792 hci1394_async_arreq_read_qrd(hci1394_async_handle_t async_handle,
1793     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1794 {
1795         h1394_cmd_priv_t *cmd_priv;
1796         cmd1394_cmd_t *cmd;
1797         uint32_t quadlet;
1798 
1799 
1800         ASSERT(async_handle != NULL);
1801         ASSERT(pkt != NULL);
1802         ASSERT(hcicmd != NULL);
1803         ASSERT(size != NULL);
1804         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qrd_enter,
1805             HCI1394_TNF_HAL_STACK, "");
1806 
1807         /* Setup shortcuts, command type, and size of request */
1808         cmd = hcicmd->ac_cmd;
1809         cmd_priv = hcicmd->ac_priv;
1810         cmd->cmd_type = CMD1394_ASYNCH_RD_QUAD;
1811         *size = DESC_SZ_AR_READQUAD_REQ;
1812 
1813         /*
1814          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1815          * calculate the ATRESP timeout for when we send it.
1816          */
1817         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
1818         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1819         cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1820         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1821         hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1822             cmd_priv->recv_tstamp);
1823 
1824         /*
1825          * if the ARREQ ACK was bad, we were unable to successfully read in this
1826          * request.  Return failure.
1827          */
1828         if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1829             (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1830                 TNF_PROBE_1(hci1394_async_arreq_qrd_ack_fail,
1831                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_ack,
1832                     hcicmd->ac_status);
1833                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qrd_exit,
1834                     HCI1394_TNF_HAL_STACK, "");
1835                 return (DDI_FAILURE);
1836         }
1837 
1838         /*
1839          * Read in the tlabel and destination. We don't use an mblk for this
1840          * request.
1841          */
1842         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1843         hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1844         hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1845         hcicmd->ac_mblk_alloc = B_FALSE;
1846 
1847         /*
1848          * Read in the sender so we know who to send the ATRESP to and read in
1849          * the 1394 48-bit address for this request.
1850          */
1851         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1852         cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1853         cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1854         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1855         cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1856 
1857         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qrd_exit,
1858             HCI1394_TNF_HAL_STACK, "");
1859 
1860         return (DDI_SUCCESS);
1861 }
1862 
1863 
1864 /*
1865  * hci1394_async_arreq_read_qwr()
1866  *    Read ARREQ quadlet write into the 1394 Framework command. This routine
1867  *    will return DDI_FAILURE if it was not able to read the request
1868  *    succesfully.
1869  */
1870 static int
1871 hci1394_async_arreq_read_qwr(hci1394_async_handle_t async_handle,
1872     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1873 {
1874         h1394_cmd_priv_t *cmd_priv;
1875         cmd1394_cmd_t *cmd;
1876         uint32_t quadlet;
1877 
1878 
1879         ASSERT(async_handle != NULL);
1880         ASSERT(pkt != NULL);
1881         ASSERT(hcicmd != NULL);
1882         ASSERT(size != NULL);
1883         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qwr_enter,
1884             HCI1394_TNF_HAL_STACK, "");
1885 
1886         /* Setup shortcuts, command type, and size of request */
1887         cmd = hcicmd->ac_cmd;
1888         cmd_priv = hcicmd->ac_priv;
1889         cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
1890         *size = DESC_SZ_AR_WRITEQUAD_REQ;
1891 
1892         /*
1893          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1894          * calculate the ATRESP timeout for when we send it.
1895          */
1896         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q5);
1897         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1898         cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1899         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1900         hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1901             cmd_priv->recv_tstamp);
1902 
1903         /*
1904          * if the ARREQ ACK was bad, we were unable to successfully read in this
1905          * request.  Return failure.
1906          */
1907         if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1908             (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1909                 TNF_PROBE_1(hci1394_async_arreq_qwr_ack_fail,
1910                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_ack,
1911                     hcicmd->ac_status);
1912                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qwr_exit,
1913                     HCI1394_TNF_HAL_STACK, "");
1914                 return (DDI_FAILURE);
1915         }
1916 
1917         /*
1918          * Read in the tlabel and destination. We don't use an mblk for this
1919          * request.
1920          */
1921         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
1922         hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
1923         hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
1924         hcicmd->ac_mblk_alloc = B_FALSE;
1925 
1926         /*
1927          * Read in the sender so we know who to send the ATRESP to. Read in
1928          * the 1394 48-bit address for this request. Copy the data quadlet into
1929          * the command.  The data quadlet is treated like a byte stream.
1930          */
1931         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
1932         cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
1933         cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
1934         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
1935         cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
1936         hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
1937             (uint8_t *)&cmd->cmd_u.q.quadlet_data, (uint8_t *)&pkt->q4,
1938             IEEE1394_QUADLET);
1939 
1940         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qwr_exit,
1941             HCI1394_TNF_HAL_STACK, "");
1942 
1943         return (DDI_SUCCESS);
1944 }
1945 
1946 
1947 /*
1948  * hci1394_async_arreq_read_brd()
1949  *    Read ARREQ block read into the 1394 Framework command. This routine will
1950  *    return DDI_FAILURE if it was not able to read the request succesfully.
1951  */
1952 static int
1953 hci1394_async_arreq_read_brd(hci1394_async_handle_t async_handle,
1954     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
1955 {
1956         h1394_cmd_priv_t *cmd_priv;
1957         cmd1394_cmd_t *cmd;
1958         uint32_t quadlet;
1959 
1960 
1961         ASSERT(async_handle != NULL);
1962         ASSERT(pkt != NULL);
1963         ASSERT(hcicmd != NULL);
1964         ASSERT(size != NULL);
1965         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_brd_enter,
1966             HCI1394_TNF_HAL_STACK, "");
1967 
1968         /* Setup shortcuts, command type, and size of request */
1969         cmd = hcicmd->ac_cmd;
1970         cmd_priv = hcicmd->ac_priv;
1971         cmd->cmd_type = CMD1394_ASYNCH_RD_BLOCK;
1972         *size = DESC_SZ_AR_READBLOCK_REQ;
1973 
1974         /*
1975          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
1976          * calculate the ATRESP timeout for when we send it.
1977          */
1978         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q5);
1979         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
1980         cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
1981         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
1982         hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
1983             cmd_priv->recv_tstamp);
1984 
1985         /*
1986          * if the ARREQ ACK was bad, we were unable to successfully read in this
1987          * request.  Return failure.
1988          */
1989         if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
1990             (hcicmd->ac_status != OHCI_ACK_PENDING)) {
1991                 TNF_PROBE_1(hci1394_async_arreq_brd_ack_fail,
1992                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_ack,
1993                     hcicmd->ac_status);
1994                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_brd_exit,
1995                     HCI1394_TNF_HAL_STACK, "");
1996                 return (DDI_FAILURE);
1997         }
1998 
1999         /* Read in the tlabel and destination */
2000         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
2001         hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
2002         hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
2003 
2004         /*
2005          * Read in the sender so we know who to send the ATRESP to. Read in
2006          * the 1394 48-bit address for this request. Read in the block data size
2007          * and allocate an mblk of that size.
2008          */
2009         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
2010         cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
2011         cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
2012         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
2013         cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
2014         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
2015         cmd->cmd_u.b.blk_length = HCI1394_DESC_DATALEN_GET(quadlet);
2016         cmd->cmd_u.b.data_block = allocb(cmd->cmd_u.b.blk_length, 0);
2017         if (cmd->cmd_u.b.data_block == NULL) {
2018                 TNF_PROBE_0(hci1394_async_arreq_brd_mblk_fail,
2019                     HCI1394_TNF_HAL_ERROR, "");
2020                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_brd_exit,
2021                     HCI1394_TNF_HAL_STACK, "");
2022                 return (DDI_FAILURE);
2023         }
2024         hcicmd->ac_mblk_alloc = B_TRUE;
2025 
2026         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_brd_exit,
2027             HCI1394_TNF_HAL_STACK, "");
2028 
2029         return (DDI_SUCCESS);
2030 }
2031 
2032 
2033 /*
2034  * hci1394_async_arreq_read_bwr()
2035  *    Read ARREQ block write into the 1394 Framework command. This routine will
2036  *    return DDI_FAILURE if it was not able to read the request succesfully.
2037  */
2038 static int
2039 hci1394_async_arreq_read_bwr(hci1394_async_handle_t async_handle,
2040     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
2041 {
2042         h1394_cmd_priv_t *cmd_priv;
2043         uint32_t *local_addr;
2044         cmd1394_cmd_t *cmd;
2045         uint32_t quadlet;
2046 
2047 
2048         ASSERT(async_handle != NULL);
2049         ASSERT(pkt != NULL);
2050         ASSERT(hcicmd != NULL);
2051         ASSERT(size != NULL);
2052         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_bwr_enter,
2053             HCI1394_TNF_HAL_STACK, "");
2054 
2055         /*
2056          * Setup shortcuts, command type, and size of request. The size of the
2057          * request is in quadlets, therefore we need to make sure we count in
2058          * the padding when figureing out the size (i.e. data may be in bytes
2059          * but the HW always pads to quadlets)
2060          */
2061         cmd = hcicmd->ac_cmd;
2062         cmd_priv = hcicmd->ac_priv;
2063         cmd->cmd_type = CMD1394_ASYNCH_WR_BLOCK;
2064         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
2065         cmd->cmd_u.b.blk_length = HCI1394_DESC_DATALEN_GET(quadlet);
2066         *size = DESC_SZ_AR_WRITEBLOCK_REQ +
2067             HCI1394_ALIGN_QUAD(cmd->cmd_u.b.blk_length);
2068 
2069         /*
2070          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
2071          * calculate the ATRESP timeout for when we send it. The status word is
2072          * the last quadlet in the packet.
2073          */
2074         local_addr = (uint32_t *)(((uintptr_t)(&pkt->q5)) +
2075             ((uintptr_t)HCI1394_ALIGN_QUAD(cmd->cmd_u.b.blk_length)));
2076         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, local_addr);
2077         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
2078         cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
2079         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
2080         hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
2081             cmd_priv->recv_tstamp);
2082 
2083         /*
2084          * if the ARREQ ACK was bad, we were unable to successfully read in this
2085          * request.  Return failure.
2086          */
2087         if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
2088             (hcicmd->ac_status != OHCI_ACK_PENDING)) {
2089                 TNF_PROBE_1(hci1394_async_arreq_bwr_ack_fail,
2090                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_ack,
2091                     hcicmd->ac_status);
2092                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_bwr_exit,
2093                     HCI1394_TNF_HAL_STACK, "");
2094                 return (DDI_FAILURE);
2095         }
2096 
2097         /* Read in the tlabel and destination */
2098         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
2099         hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
2100         hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
2101 
2102         /*
2103          * Read in the sender so we know who to send the ATRESP to. Read in
2104          * the 1394 48-bit address for this request. Read in the block data size
2105          * and allocate an mblk of that size.
2106          */
2107         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
2108         cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
2109         cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
2110         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
2111         cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
2112         cmd->cmd_u.b.data_block = allocb(cmd->cmd_u.b.blk_length, 0);
2113         if (cmd->cmd_u.b.data_block == NULL) {
2114                 TNF_PROBE_0(hci1394_async_arreq_bwr_mblk_fail,
2115                     HCI1394_TNF_HAL_ERROR, "");
2116                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_bwr_exit,
2117                     HCI1394_TNF_HAL_STACK, "");
2118                 return (DDI_FAILURE);
2119         }
2120         hcicmd->ac_mblk_alloc = B_TRUE;
2121 
2122         /* Copy ARREQ write data into mblk_t */
2123         hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
2124             (uint8_t *)cmd->cmd_u.b.data_block->b_wptr,
2125             (uint8_t *)&pkt->q5, cmd->cmd_u.b.blk_length);
2126 
2127         /* Update mblk_t wptr */
2128         cmd->cmd_u.b.data_block->b_wptr += cmd->cmd_u.b.blk_length;
2129 
2130         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_bwr_exit,
2131             HCI1394_TNF_HAL_STACK, "");
2132 
2133         return (DDI_SUCCESS);
2134 }
2135 
2136 
2137 /*
2138  * hci1394_async_arreq_read_lck()
2139  *    Read ARREQ lock request into the 1394 Framework command. This routine will
2140  *    return DDI_FAILURE if it was not able to read the request succesfully.
2141  */
2142 static int
2143 hci1394_async_arreq_read_lck(hci1394_async_handle_t async_handle,
2144     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size)
2145 {
2146         h1394_cmd_priv_t *cmd_priv;
2147         uint32_t *local_addr;
2148         cmd1394_cmd_t *cmd;
2149         uint8_t *data_addr;
2150         uint32_t quadlet;
2151         uint32_t length;
2152 
2153 
2154         ASSERT(async_handle != NULL);
2155         ASSERT(pkt != NULL);
2156         ASSERT(hcicmd != NULL);
2157         ASSERT(size != NULL);
2158         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qrd_enter,
2159             HCI1394_TNF_HAL_STACK, "");
2160 
2161         /*
2162          * Setup shortcuts, command type, and size of request. The size of the
2163          * request is in quadlets, therefore we need to make sure we count in
2164          * the padding when figuring out the size (i.e. data may be in bytes
2165          * but the HW always pads to quadlets)
2166          */
2167         cmd = hcicmd->ac_cmd;
2168         cmd_priv = hcicmd->ac_priv;
2169         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
2170         length = HCI1394_DESC_DATALEN_GET(quadlet);
2171         *size = DESC_SZ_AR_LOCK_REQ + HCI1394_ALIGN_QUAD(length);
2172 
2173         /* make sure the length is a valid lock request length */
2174         if (length == DESC_TWO_QUADS) {
2175                 cmd->cmd_type = CMD1394_ASYNCH_LOCK_32;
2176                 cmd->cmd_u.l32.lock_type = HCI1394_DESC_EXTTCODE_GET(quadlet);
2177         } else if (length == DESC_TWO_OCTLETS) {
2178                 cmd->cmd_type = CMD1394_ASYNCH_LOCK_64;
2179                 cmd->cmd_u.l64.lock_type = HCI1394_DESC_EXTTCODE_GET(quadlet);
2180         } else {
2181                 TNF_PROBE_2(hci1394_async_arreq_lck_sz_fail,
2182                     HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
2183                     "unexpected length received", tnf_uint, locklen, length);
2184                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
2185                     HCI1394_TNF_HAL_STACK, "");
2186                 return (DDI_FAILURE);
2187         }
2188 
2189         /*
2190          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
2191          * calculate the ATRESP timeout for when we send it. The status word is
2192          * the last quadlet in the packet.
2193          */
2194         local_addr = (uint32_t *)(((uintptr_t)(&pkt->q5)) +
2195             ((uintptr_t)HCI1394_ALIGN_QUAD(length)));
2196         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, local_addr);
2197         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
2198         cmd_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
2199         cmd_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
2200         hcicmd->ac_qcmd.qc_timestamp = hci1394_async_timeout_calc(async_handle,
2201             cmd_priv->recv_tstamp);
2202 
2203         /*
2204          * if the ARREQ ACK was bad, we were unable to successfully read in this
2205          * request.  Return failure.
2206          */
2207         if ((hcicmd->ac_status != OHCI_ACK_COMPLETE) &&
2208             (hcicmd->ac_status != OHCI_ACK_PENDING)) {
2209                 TNF_PROBE_1(hci1394_async_arreq_read_ack_fail,
2210                     HCI1394_TNF_HAL_ERROR, "", tnf_uint, arreq_ack,
2211                     hcicmd->ac_status);
2212                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_exit,
2213                     HCI1394_TNF_HAL_STACK, "");
2214                 return (DDI_FAILURE);
2215         }
2216 
2217         /* Read in the tlabel and destination */
2218         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q1);
2219         hcicmd->ac_dest = HCI1394_DESC_DESTID_GET(quadlet);
2220         hcicmd->ac_tlabel.tbi_tlabel = HCI1394_DESC_TLABEL_GET(quadlet);
2221         hcicmd->ac_mblk_alloc = B_FALSE;
2222 
2223         /*
2224          * Read in the sender so we know who to send the ATRESP to. Read in
2225          * the 1394 48-bit address for this request.
2226          */
2227         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
2228         cmd->nodeID = HCI1394_DESC_SRCID_GET(quadlet);
2229         cmd->cmd_addr = HCI1394_TO_ADDR_HI(quadlet);
2230         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
2231         cmd->cmd_addr |= HCI1394_TO_ADDR_LO(quadlet);
2232 
2233         /* Copy ARREQ lock data into 1394 framework command */
2234         if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
2235                 data_addr = (uint8_t *)&pkt->q5;
2236                 hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
2237                     (uint8_t *)&cmd->cmd_u.l32.arg_value, data_addr,
2238                     IEEE1394_QUADLET);
2239                 data_addr = (uint8_t *)((uintptr_t)data_addr +
2240                     (uintptr_t)IEEE1394_QUADLET);
2241                 hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
2242                     (uint8_t *)&cmd->cmd_u.l32.data_value, data_addr,
2243                     IEEE1394_QUADLET);
2244                 /*
2245                  * swap these for our correct architecture if we are doing
2246                  * arithmetic lock operations
2247                  */
2248                 cmd->cmd_u.l32.arg_value = HCI1394_ARITH_LOCK_SWAP32(
2249                     cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.arg_value);
2250                 cmd->cmd_u.l32.data_value = HCI1394_ARITH_LOCK_SWAP32(
2251                     cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.data_value);
2252         } else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
2253                 data_addr = (uint8_t *)&pkt->q5;
2254                 hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
2255                     (uint8_t *)&cmd->cmd_u.l64.arg_value, data_addr,
2256                     IEEE1394_OCTLET);
2257                 data_addr = (uint8_t *)((uintptr_t)data_addr +
2258                     (uintptr_t)IEEE1394_OCTLET);
2259                 hci1394_q_ar_rep_get8(async_handle->as_arreq_q,
2260                     (uint8_t *)&cmd->cmd_u.l64.data_value, data_addr,
2261                     IEEE1394_OCTLET);
2262 
2263                 /*
2264                  * swap these for our correct architecture if we are doing
2265                  * arithmetic lock operations
2266                  */
2267                 cmd->cmd_u.l64.arg_value = HCI1394_ARITH_LOCK_SWAP64(
2268                     cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.arg_value);
2269                 cmd->cmd_u.l64.data_value = HCI1394_ARITH_LOCK_SWAP64(
2270                     cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.data_value);
2271         }
2272 
2273         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_qrd_exit,
2274             HCI1394_TNF_HAL_STACK, "");
2275 
2276         return (DDI_SUCCESS);
2277 }
2278 
2279 
2280 /*
2281  * hci1394_async_arreq_read_phy()
2282  *    Read ARREQ PHY quadlet into the 1394 Framework command. This routine will
2283  *    return DDI_FAILURE if it was not able to read the request succesfully.
2284  */
2285 static int
2286 hci1394_async_arreq_read_phy(hci1394_async_handle_t async_handle,
2287     hci1394_basic_pkt_t *pkt, hci1394_async_cmd_t *hcicmd, uint_t *size,
2288     boolean_t *bus_reset_token)
2289 {
2290         cmd1394_cmd_t *cmd;
2291         uint32_t quadlet;
2292         uint32_t data1;
2293         uint32_t data2;
2294 
2295 
2296         ASSERT(async_handle != NULL);
2297         ASSERT(pkt != NULL);
2298         ASSERT(hcicmd != NULL);
2299         ASSERT(size != NULL);
2300         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_phy_enter,
2301             HCI1394_TNF_HAL_STACK, "");
2302 
2303         /* Setup shortcuts, command type, and size of request */
2304         cmd = hcicmd->ac_cmd;
2305         cmd->cmd_type = CMD1394_ASYNCH_WR_QUAD;
2306         *size = DESC_SZ_AR_PHY;
2307 
2308         /*
2309          * read in the ARREQ ACK/EVT, the speed, the time we received it, and
2310          * set state that we do not use an mblk for this request.
2311          */
2312         quadlet = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q4);
2313         hcicmd->ac_status = HCI1394_DESC_EVT_GET(quadlet);
2314         hcicmd->ac_priv->speed = HCI1394_DESC_AR_SPD_GET(quadlet);
2315         hcicmd->ac_priv->recv_tstamp = HCI1394_DESC_TIMESTAMP_GET(quadlet);
2316         hcicmd->ac_mblk_alloc = B_FALSE;
2317 
2318         /* Read in the PHY packet quadlet and its check quadlet */
2319         data1 = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q2);
2320         data2 = hci1394_q_ar_get32(async_handle->as_arreq_q, &pkt->q3);
2321 
2322         /*
2323          * if this is a bus reset token, save away the generation. If the bus
2324          * reset token is for the current generation, we do not need to flush
2325          * the ARREQ Q anymore.
2326          */
2327         if (hcicmd->ac_status == OHCI_EVT_BUS_RESET) {
2328                 *bus_reset_token = B_TRUE;
2329                 async_handle->as_phy_reset = HCI1394_DESC_PHYGEN_GET(data2);
2330                 if (async_handle->as_phy_reset == hci1394_ohci_current_busgen(
2331                     async_handle->as_ohci)) {
2332                         async_handle->as_flushing_arreq = B_FALSE;
2333                 }
2334                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_phy_exit,
2335                     HCI1394_TNF_HAL_STACK, "");
2336                 return (DDI_SUCCESS);
2337         }
2338 
2339         *bus_reset_token = B_FALSE;
2340 
2341         /* if there is a data error in the PHY packet, return failure */
2342         if (data1 != ~data2) {
2343                 TNF_PROBE_2(hci1394_async_arreq_phy_xor_fail,
2344                     HCI1394_TNF_HAL_ERROR, "", tnf_opaque, first_quadlet,
2345                     data1, tnf_opaque, second_quadlet, data2);
2346                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_phy_exit,
2347                     HCI1394_TNF_HAL_STACK, "");
2348                 return (DDI_FAILURE);
2349         }
2350 
2351         /* Copy the PHY quadlet to the command */
2352         cmd->cmd_u.q.quadlet_data = data1;
2353 
2354         TNF_PROBE_0_DEBUG(hci1394_async_arreq_read_phy_exit,
2355             HCI1394_TNF_HAL_STACK, "");
2356 
2357         return (DDI_SUCCESS);
2358 }
2359 
2360 
2361 /*
2362  * hci1394_async_phy()
2363  *    Queue up ATREQ phy packet.
2364  */
2365 int
2366 hci1394_async_phy(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2367     h1394_cmd_priv_t *cmd_priv, int *result)
2368 {
2369         hci1394_basic_pkt_t header;
2370         hci1394_async_cmd_t *hcicmd;
2371         int status;
2372 
2373 
2374         ASSERT(async_handle != NULL);
2375         ASSERT(cmd != NULL);
2376         ASSERT(cmd_priv != NULL);
2377         ASSERT(result != NULL);
2378 
2379         TNF_PROBE_0_DEBUG(hci1394_async_phy_enter, HCI1394_TNF_HAL_STACK, "");
2380 
2381         /*
2382          * make sure this call is during the current bus generation (i.e. no
2383          * bus resets have occured since this request was made.
2384          */
2385         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2386             async_handle->as_ohci)) {
2387                 *result = H1394_STATUS_INVALID_BUSGEN;
2388                 TNF_PROBE_0_DEBUG(hci1394_async_phy_exit,
2389                     HCI1394_TNF_HAL_STACK, "");
2390                 return (DDI_FAILURE);
2391         }
2392 
2393         /* Initialize the private HAL command structure */
2394         hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2395 
2396         /* We do not allocate a tlabel for a PHY packet */
2397         hcicmd->ac_tlabel_alloc = B_FALSE;
2398 
2399         /*
2400          * Setup the packet header information for a ATREQ PHY packet Add in
2401          * the tcode, phy quadlet, and it's 1's complement.
2402          */
2403         header.q1 = DESC_ATREQ_Q1_PHY;
2404         header.q2 = cmd->cmd_u.q.quadlet_data;
2405         header.q3 = ~header.q2;
2406 
2407         /* Write request into the ATREQ Q. If we fail, we're out of space */
2408         status = hci1394_q_at(async_handle->as_atreq_q, &hcicmd->ac_qcmd,
2409             &header, DESC_PKT_HDRLEN_AT_PHY, result);
2410         if (status != DDI_SUCCESS) {
2411                 TNF_PROBE_0(hci1394_async_phy_q_fail, HCI1394_TNF_HAL_ERROR,
2412                     "");
2413                 TNF_PROBE_0_DEBUG(hci1394_async_phy_exit,
2414                     HCI1394_TNF_HAL_STACK, "");
2415                 return (DDI_FAILURE);
2416         }
2417 
2418         TNF_PROBE_0_DEBUG(hci1394_async_phy_exit, HCI1394_TNF_HAL_STACK, "");
2419 
2420         return (DDI_SUCCESS);
2421 }
2422 
2423 
2424 /*
2425  * hci1394_async_write()
2426  *    Queue up ATREQ write. This could be either a block write or a quadlet
2427  *    write.
2428  */
2429 int
2430 hci1394_async_write(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2431     h1394_cmd_priv_t *cmd_priv, int *result)
2432 {
2433         hci1394_async_cmd_t *hcicmd;
2434         hci1394_basic_pkt_t header;
2435         int status;
2436 
2437 
2438         ASSERT(async_handle != NULL);
2439         ASSERT(cmd != NULL);
2440         ASSERT(cmd_priv != NULL);
2441         ASSERT(result != NULL);
2442 
2443         TNF_PROBE_0_DEBUG(hci1394_async_write_enter, HCI1394_TNF_HAL_STACK, "");
2444 
2445         /*
2446          * make sure this call is during the current bus generation (i.e. no
2447          * bus resets have occured since this request was made.
2448          */
2449         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2450             async_handle->as_ohci)) {
2451                 *result = H1394_STATUS_INVALID_BUSGEN;
2452                 TNF_PROBE_0_DEBUG(hci1394_async_write_exit,
2453                     HCI1394_TNF_HAL_STACK, "");
2454                 return (DDI_FAILURE);
2455         }
2456 
2457         /* Initialize the private HAL command structure */
2458         hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2459         hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2460 
2461         /* allocate a tlabel for this request */
2462         status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2463             &hcicmd->ac_tlabel);
2464         if (status != DDI_SUCCESS) {
2465                 *result = H1394_STATUS_EMPTY_TLABEL;
2466                 TNF_PROBE_0(hci1394_async_write_tlb_fail,
2467                     HCI1394_TNF_HAL_ERROR, "");
2468                 TNF_PROBE_0_DEBUG(hci1394_async_write_exit,
2469                     HCI1394_TNF_HAL_STACK, "");
2470                 return (DDI_FAILURE);
2471         }
2472 
2473         /*
2474          * Setup the packet header information for a ATREQ write packet. We
2475          * will set the tcode later on since this could be a block write or
2476          * a quadlet write. Set SRCBusId if this write is not a local bus
2477          * access. Copy in the speed, tlabel, and destination address.
2478          */
2479         header.q1 = 0;
2480         if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2481             IEEE1394_BUS_NUM_MASK) {
2482                 header.q1 |= DESC_AT_SRCBUSID;
2483         }
2484         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2485             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2486         header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2487         header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2488 
2489         /* Register this command w/ its tlabel */
2490         hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2491             hcicmd);
2492 
2493         /* If this is a quadlet write ATREQ */
2494         if (cmd->cmd_type == CMD1394_ASYNCH_WR_QUAD) {
2495                 /*
2496                  * setup the tcode for a quadlet write request and copy in
2497                  * the quadlet data. Endian issues will be taken care of in
2498                  * hci1394_q_at().
2499                  */
2500                 header.q1 |= DESC_ATREQ_Q1_QWR;
2501                 header.q4 = cmd->cmd_u.q.quadlet_data;
2502 
2503                 /*
2504                  * Write the request into the ATREQ Q. If we fail, we are out
2505                  * of space.
2506                  */
2507                 status = hci1394_q_at(async_handle->as_atreq_q,
2508                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_WRITEQUAD,
2509                     result);
2510                 if (status != DDI_SUCCESS) {
2511                         TNF_PROBE_0(hci1394_async_write_q_fail,
2512                             HCI1394_TNF_HAL_ERROR, "");
2513                         TNF_PROBE_0_DEBUG(hci1394_async_write_exit,
2514                             HCI1394_TNF_HAL_STACK, "");
2515                         return (DDI_FAILURE);
2516                 }
2517 
2518         /* This is a block write ATREQ */
2519         } else {
2520                 /* setup the tcode and the length of the block write */
2521                 header.q1 |= DESC_ATREQ_Q1_BWR;
2522                 header.q4 = HCI1394_DESC_DATALEN_SET(cmd_priv->mblk.length);
2523 
2524                 /*
2525                  * Write the request into the ATREQ Q. If we fail, we are out
2526                  * of space. The data is in a mblk(s). We use a special
2527                  * interface in the HAL/SL private command block to handle
2528                  * partial transfers out of the mblk due to packet size
2529                  * restrictions.
2530                  */
2531                 status = hci1394_q_at_with_mblk(async_handle->as_atreq_q,
2532                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_WRITEBLOCK,
2533                     &cmd_priv->mblk, result);
2534                 if (status != DDI_SUCCESS) {
2535                         TNF_PROBE_0(hci1394_async_write_qmblk_fail,
2536                             HCI1394_TNF_HAL_ERROR, "");
2537                         TNF_PROBE_0_DEBUG(hci1394_async_write_exit,
2538                             HCI1394_TNF_HAL_STACK, "");
2539                         return (DDI_FAILURE);
2540                 }
2541         }
2542 
2543         TNF_PROBE_0_DEBUG(hci1394_async_write_exit, HCI1394_TNF_HAL_STACK, "");
2544 
2545         return (DDI_SUCCESS);
2546 }
2547 
2548 
2549 /*
2550  * hci1394_async_read()
2551  *    Queue up ATREQ read. This could be either a block read or a quadlet
2552  *    read.
2553  */
2554 int
2555 hci1394_async_read(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2556     h1394_cmd_priv_t *cmd_priv, int *result)
2557 {
2558         hci1394_basic_pkt_t header;
2559         int status;
2560         hci1394_async_cmd_t *hcicmd;
2561 
2562 
2563         ASSERT(async_handle != NULL);
2564         ASSERT(cmd != NULL);
2565         ASSERT(cmd_priv != NULL);
2566         ASSERT(result != NULL);
2567 
2568         TNF_PROBE_0_DEBUG(hci1394_async_read_enter, HCI1394_TNF_HAL_STACK, "");
2569 
2570         /*
2571          * make sure this call is during the current bus generation (i.e. no
2572          * bus resets have occured since this request was made.
2573          */
2574         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2575             async_handle->as_ohci)) {
2576                 *result = H1394_STATUS_INVALID_BUSGEN;
2577                 TNF_PROBE_0_DEBUG(hci1394_async_read_exit,
2578                     HCI1394_TNF_HAL_STACK, "");
2579                 return (DDI_FAILURE);
2580         }
2581 
2582         /* Initialize the private HAL command structure */
2583         hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2584         hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2585 
2586         /* allocate a tlabel for this request */
2587         status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2588             &hcicmd->ac_tlabel);
2589         if (status != DDI_SUCCESS) {
2590                 *result = H1394_STATUS_EMPTY_TLABEL;
2591                 TNF_PROBE_0(hci1394_async_read_tlb_fail,
2592                     HCI1394_TNF_HAL_ERROR, "");
2593                 TNF_PROBE_0_DEBUG(hci1394_async_read_exit,
2594                     HCI1394_TNF_HAL_STACK, "");
2595                 return (DDI_FAILURE);
2596         }
2597 
2598         /*
2599          * Setup the packet header information for a ATREQ read packet. We
2600          * will set the tcode later on since this could be a block read or
2601          * a quadlet read. Set SRCBusId if this read is not a local bus
2602          * access. Copy in the speed, tlabel, and destination address.
2603          */
2604         header.q1 = 0;
2605         if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2606             IEEE1394_BUS_NUM_MASK) {
2607                 header.q1 |= DESC_AT_SRCBUSID;
2608         }
2609         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2610             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2611         header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2612         header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2613 
2614         /* Register this command w/ its tlabel */
2615         hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2616             hcicmd);
2617 
2618         /* If this is a quadlet read ATREQ */
2619         if (cmd->cmd_type == CMD1394_ASYNCH_RD_QUAD) {
2620                 /* setup the tcode for a quadlet read request */
2621                 header.q1 |= DESC_ATREQ_Q1_QRD;
2622                 header.q4 = 0;
2623 
2624                 /*
2625                  * Write the request into the ATREQ Q. If we fail, we are out
2626                  * of space.
2627                  */
2628                 status = hci1394_q_at(async_handle->as_atreq_q,
2629                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READQUAD,
2630                     result);
2631                 if (status != DDI_SUCCESS) {
2632                         TNF_PROBE_0(hci1394_async_read_q_fail,
2633                             HCI1394_TNF_HAL_ERROR, "");
2634                         TNF_PROBE_0_DEBUG(hci1394_async_read_exit,
2635                             HCI1394_TNF_HAL_STACK, "");
2636                         return (DDI_FAILURE);
2637                 }
2638 
2639         } else {
2640                 /* setup the tcode and the length of the block read */
2641                 header.q1 |= DESC_ATREQ_Q1_BRD;
2642                 header.q4 = HCI1394_DESC_DATALEN_SET(cmd_priv->mblk.length);
2643 
2644                 /*
2645                  * Write the request into the ATREQ Q. If we fail, we are out
2646                  * of space.
2647                  */
2648                 status = hci1394_q_at(async_handle->as_atreq_q,
2649                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READBLOCK,
2650                     result);
2651                 if (status != DDI_SUCCESS) {
2652                         TNF_PROBE_0(hci1394_async_read_qb_fail,
2653                             HCI1394_TNF_HAL_ERROR, "");
2654                         TNF_PROBE_0_DEBUG(hci1394_async_read_exit,
2655                             HCI1394_TNF_HAL_STACK, "");
2656                         return (DDI_FAILURE);
2657                 }
2658         }
2659 
2660         TNF_PROBE_0_DEBUG(hci1394_async_read_exit, HCI1394_TNF_HAL_STACK, "");
2661 
2662         return (DDI_SUCCESS);
2663 }
2664 
2665 
2666 /*
2667  * hci1394_async_lock()
2668  *    Queue up ATREQ lock. This could be either a 32-bit or 64-bit lock
2669  *    request.
2670  */
2671 int
2672 hci1394_async_lock(hci1394_async_handle_t async_handle, cmd1394_cmd_t *cmd,
2673     h1394_cmd_priv_t *cmd_priv, int *result)
2674 {
2675         hci1394_basic_pkt_t header;
2676         hci1394_async_cmd_t *hcicmd;
2677         uint32_t data32[2];
2678         uint64_t data64[2];
2679         uint8_t *datap;
2680         uint_t size;
2681         int status;
2682 
2683 
2684         ASSERT(async_handle != NULL);
2685         ASSERT(cmd != NULL);
2686         ASSERT(cmd_priv != NULL);
2687         ASSERT(result != NULL);
2688 
2689         TNF_PROBE_0_DEBUG(hci1394_async_lock_enter, HCI1394_TNF_HAL_STACK, "");
2690 
2691         /*
2692          * make sure this call is during the current bus generation (i.e. no
2693          * bus resets have occured since this request was made.
2694          */
2695         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2696             async_handle->as_ohci)) {
2697                 *result = H1394_STATUS_INVALID_BUSGEN;
2698                 TNF_PROBE_0_DEBUG(hci1394_async_lock_exit,
2699                     HCI1394_TNF_HAL_STACK, "");
2700                 return (DDI_FAILURE);
2701         }
2702 
2703         /* Initialize the private HAL command structure */
2704         hci1394_async_hcicmd_init(async_handle, cmd, cmd_priv, &hcicmd);
2705         hcicmd->ac_dest = (uint_t)(cmd->cmd_addr >> IEEE1394_ADDR_PHY_ID_SHIFT);
2706 
2707         /* allocate a tlabel for this request */
2708         status = hci1394_tlabel_alloc(async_handle->as_tlabel, hcicmd->ac_dest,
2709             &hcicmd->ac_tlabel);
2710         if (status != DDI_SUCCESS) {
2711                 *result = H1394_STATUS_EMPTY_TLABEL;
2712                 TNF_PROBE_0(hci1394_async_lock_tlb_fail,
2713                     HCI1394_TNF_HAL_ERROR, "");
2714                 TNF_PROBE_0_DEBUG(hci1394_async_lock_exit,
2715                     HCI1394_TNF_HAL_STACK, "");
2716                 return (DDI_FAILURE);
2717         }
2718 
2719         /* Register this command w/ its tlabel */
2720         hci1394_tlabel_register(async_handle->as_tlabel, &hcicmd->ac_tlabel,
2721             hcicmd);
2722 
2723         /*
2724          * Setup the packet header information for a ATREQ lock packet. Set
2725          * the tcode up as a lock request. Set SRCBusId if this lock is not a
2726          * local bus access. Copy in the speed, tlabel, and destination
2727          * address.
2728          */
2729         header.q1 = DESC_ATREQ_Q1_LCK;
2730         if ((hcicmd->ac_dest & IEEE1394_BUS_NUM_MASK) !=
2731             IEEE1394_BUS_NUM_MASK) {
2732                 header.q1 |= DESC_AT_SRCBUSID;
2733         }
2734         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2735             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2736         header.q2 = (uint32_t)(cmd->cmd_addr >> 32);
2737         header.q3 = (uint32_t)(cmd->cmd_addr & DESC_PKT_DESTOFFLO_MASK);
2738 
2739         /*
2740          * Setup the lock length based on what size lock operation we are
2741          * performing. If it isn't a lock32 or lock64, we have encountered an
2742          * internal error. Copy the lock data into a local data buffer. Perform
2743          * a byte swap if it is an arithmetic lock operation and we are on a
2744          * little endian machine.
2745          */
2746         if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
2747                 size = DESC_TWO_QUADS;
2748                 header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2749                     HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
2750                 data32[0] = HCI1394_ARITH_LOCK_SWAP32(
2751                     cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.arg_value);
2752                 data32[1] = HCI1394_ARITH_LOCK_SWAP32(
2753                     cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.data_value);
2754                 datap = (uint8_t *)data32;
2755         } else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
2756                 size = DESC_TWO_OCTLETS;
2757                 header.q4 = HCI1394_DESC_DATALEN_SET(size) |
2758                     HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
2759                 data64[0] = HCI1394_ARITH_LOCK_SWAP64(
2760                     cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.arg_value);
2761                 data64[1] = HCI1394_ARITH_LOCK_SWAP64(
2762                     cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.data_value);
2763                 datap = (uint8_t *)data64;
2764         } else {
2765                 *result = H1394_STATUS_INTERNAL_ERROR;
2766                 TNF_PROBE_0(hci1394_lock_length_fail,
2767                     HCI1394_TNF_HAL_ERROR, "");
2768                 TNF_PROBE_0_DEBUG(hci1394_async_lock_exit,
2769                     HCI1394_TNF_HAL_STACK, "");
2770                 return (DDI_FAILURE);
2771         }
2772 
2773         /* Write request into the ATREQ Q. If we fail, we're out of space */
2774         status = hci1394_q_at_with_data(async_handle->as_atreq_q,
2775             &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK, datap, size,
2776             result);
2777         if (status != DDI_SUCCESS) {
2778                 TNF_PROBE_0(hci1394_async_lock_q_fail,
2779                     HCI1394_TNF_HAL_ERROR, "");
2780                 TNF_PROBE_0_DEBUG(hci1394_async_lock_exit,
2781                     HCI1394_TNF_HAL_STACK, "");
2782                 return (DDI_FAILURE);
2783         }
2784 
2785         TNF_PROBE_0_DEBUG(hci1394_async_lock_exit, HCI1394_TNF_HAL_STACK, "");
2786 
2787         return (DDI_SUCCESS);
2788 }
2789 
2790 
2791 /*
2792  * hci1394_async_write_response()
2793  *    Send a write ATRESP. This routine should be called from the Services
2794  *    layer to send a response to a received write request (ARREQ). The same
2795  *    response is sent to a quadlet and block write request.
2796  */
2797 int
2798 hci1394_async_write_response(hci1394_async_handle_t async_handle,
2799     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
2800 {
2801         hci1394_basic_pkt_t header;
2802         int status;
2803         hci1394_async_cmd_t *hcicmd;
2804 
2805 
2806         ASSERT(async_handle != NULL);
2807         ASSERT(cmd != NULL);
2808         ASSERT(cmd_priv != NULL);
2809         ASSERT(result != NULL);
2810 
2811         TNF_PROBE_0_DEBUG(hci1394_async_write_response_enter,
2812             HCI1394_TNF_HAL_STACK, "");
2813 
2814         /*
2815          * make sure this call is during the current bus generation (i.e. no
2816          * bus resets have occured since this request was made.
2817          */
2818         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2819             async_handle->as_ohci)) {
2820                 *result = H1394_STATUS_INVALID_BUSGEN;
2821                 TNF_PROBE_0_DEBUG(hci1394_async_write_response_exit,
2822                     HCI1394_TNF_HAL_STACK, "");
2823                 return (DDI_FAILURE);
2824         }
2825 
2826         /*
2827          * setup a shortcut to the hal private command area. Copy the generation
2828          * to the Q area so that we can check the generation when the AT Q is
2829          * locked. This prevents us from loosing commands due to race
2830          * conditions.
2831          */
2832         hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2833         hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
2834 
2835         /*
2836          * Setup the packet header information for a ATRESP write packet. Set
2837          * the tcode for a write response. Set SRCBusId if the addr is not a
2838          * local bus address. Copy in the speed, tlabel, and response code.
2839          */
2840         header.q1 = DESC_ATRESP_Q1_WR;
2841         if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
2842                 header.q1 |= DESC_AT_SRCBUSID;
2843         }
2844         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2845             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2846         header.q2 = (HCI1394_DESC_DESTID_SET(cmd->nodeID) |
2847             HCI1394_DESC_RCODE_SET(cmd->cmd_result));
2848         header.q3 = 0;
2849 
2850         /* Write response into the ATRESP Q. If we fail, we're out of space */
2851         status = hci1394_q_at(async_handle->as_atresp_q, &hcicmd->ac_qcmd,
2852             &header, DESC_PKT_HDRLEN_AT_WRITE_RESP, result);
2853         if (status != DDI_SUCCESS) {
2854                 TNF_PROBE_0(hci1394_async_write_response_q_fail,
2855                     HCI1394_TNF_HAL_ERROR, "");
2856                 TNF_PROBE_0_DEBUG(hci1394_async_write_response_exit,
2857                     HCI1394_TNF_HAL_STACK, "");
2858                 return (DDI_FAILURE);
2859         }
2860 
2861         TNF_PROBE_0_DEBUG(hci1394_async_write_response_exit,
2862             HCI1394_TNF_HAL_STACK, "");
2863 
2864         return (DDI_SUCCESS);
2865 }
2866 
2867 
2868 /*
2869  * hci1394_async_read_response()
2870  *    Send a read ATRESP. This routine should be called from the Services
2871  *    layer to send a response to a received read request (ARREQ). The
2872  *    response will differ between quadlet/block read requests.
2873  */
2874 int
2875 hci1394_async_read_response(hci1394_async_handle_t async_handle,
2876     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
2877 {
2878         hci1394_basic_pkt_t header;
2879         int status;
2880         hci1394_async_cmd_t *hcicmd;
2881 
2882 
2883         ASSERT(async_handle != NULL);
2884         ASSERT(cmd != NULL);
2885         ASSERT(cmd_priv != NULL);
2886         ASSERT(result != NULL);
2887 
2888         TNF_PROBE_0_DEBUG(hci1394_async_read_response_enter,
2889             HCI1394_TNF_HAL_STACK, "");
2890 
2891         /*
2892          * make sure this call is during the current bus generation (i.e. no
2893          * bus resets have occured since this request was made.
2894          */
2895         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
2896             async_handle->as_ohci)) {
2897                 *result = H1394_STATUS_INVALID_BUSGEN;
2898                 TNF_PROBE_0_DEBUG(hci1394_async_read_response_exit,
2899                     HCI1394_TNF_HAL_STACK, "");
2900                 return (DDI_FAILURE);
2901         }
2902 
2903         /*
2904          * setup a shortcut to the hal private command area. Copy the generation
2905          * to the Q area so that we can check the generation when the AT Q is
2906          * locked. This prevents us from loosing commands due to race
2907          * conditions.
2908          */
2909         hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
2910         hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
2911 
2912         /*
2913          * Setup the packet header information for a ATRESP read packet. we
2914          * will set the tcode later based on type of read response. Set
2915          * SRCBusId if the addr is not a local bus address. Copy in the
2916          * speed, tlabel, and response code.
2917          */
2918         header.q1 = 0;
2919         if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
2920                 header.q1 |= DESC_AT_SRCBUSID;
2921         }
2922         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
2923             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
2924         header.q2 = (uint32_t)(HCI1394_DESC_DESTID_SET(cmd->nodeID) |
2925             HCI1394_DESC_RCODE_SET(cmd->cmd_result));
2926         header.q3 = 0;
2927 
2928         /* if the response is a read quadlet response */
2929         if (cmd->cmd_type == CMD1394_ASYNCH_RD_QUAD) {
2930                 /*
2931                  * setup the tcode for a quadlet read response, If the
2932                  * response code is not resp complete.
2933                  */
2934                 header.q1 |= DESC_ATRESP_Q1_QRD;
2935                 if (cmd->cmd_result == IEEE1394_RESP_COMPLETE) {
2936                         header.q4 = cmd->cmd_u.q.quadlet_data;
2937                 } else {
2938                         header.q4 = 0x0;
2939                 }
2940 
2941                 /*
2942                  * Write response into the ATRESP Q. If we fail, we're out of
2943                  * space.
2944                  */
2945                 status = hci1394_q_at(async_handle->as_atresp_q,
2946                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_READQUAD_RESP,
2947                     result);
2948                 if (status != DDI_SUCCESS) {
2949                         TNF_PROBE_0(hci1394_async_read_response_q_fail,
2950                             HCI1394_TNF_HAL_ERROR, "");
2951                         TNF_PROBE_0_DEBUG(hci1394_async_read_response_exit,
2952                             HCI1394_TNF_HAL_STACK, "");
2953                         return (DDI_FAILURE);
2954                 }
2955 
2956         /*
2957          * the response is a block read response. If the result is not a
2958          * resp complete, we are not going to send any data back.
2959          */
2960         } else if ((cmd->cmd_type == CMD1394_ASYNCH_RD_BLOCK) &&
2961             (cmd->cmd_result != IEEE1394_RESP_COMPLETE)) {
2962                 /*
2963                  * Setup the tcode for a block read response, set the data
2964                  * length to zero since we had an error.
2965                  */
2966                 header.q1 |= DESC_ATRESP_Q1_BRD;
2967                 header.q4 = 0x0;
2968 
2969                 /*
2970                  * Write response into the ATRESP Q. If we fail, we're out of
2971                  * space.
2972                  */
2973                 status = hci1394_q_at(async_handle->as_atresp_q,
2974                     &hcicmd->ac_qcmd, &header,
2975                     DESC_PKT_HDRLEN_AT_READBLOCK_RESP, result);
2976                 if (status != DDI_SUCCESS) {
2977                         TNF_PROBE_0(hci1394_async_read_response_qbf_fail,
2978                             HCI1394_TNF_HAL_ERROR, "");
2979                         TNF_PROBE_0_DEBUG(hci1394_async_read_response_exit,
2980                             HCI1394_TNF_HAL_STACK, "");
2981                         return (DDI_FAILURE);
2982                 }
2983 
2984         /*
2985          * the response is a block read response with a resp complete for the
2986          * response code. Send back the read data.
2987          */
2988         } else {
2989                 /*
2990                  * Setup the tcode for a block read response, setup the data
2991                  * length.
2992                  */
2993                 header.q1 |= DESC_ATRESP_Q1_BRD;
2994                 header.q4 = HCI1394_DESC_DATALEN_SET(cmd->cmd_u.b.blk_length);
2995 
2996                 /*
2997                  * Write response into the ATRESP Q. If we fail, we're out of
2998                  * space. Use the data in the mblk.
2999                  */
3000                 status = hci1394_q_at_with_mblk(async_handle->as_atresp_q,
3001                     &hcicmd->ac_qcmd, &header,
3002                     DESC_PKT_HDRLEN_AT_READBLOCK_RESP, &cmd_priv->mblk, result);
3003                 if (status != DDI_SUCCESS) {
3004                         TNF_PROBE_0(hci1394_async_read_response_qb_fail,
3005                             HCI1394_TNF_HAL_ERROR, "");
3006                         TNF_PROBE_0_DEBUG(hci1394_async_read_response_exit,
3007                             HCI1394_TNF_HAL_STACK, "");
3008                         return (DDI_FAILURE);
3009                 }
3010         }
3011 
3012         TNF_PROBE_0_DEBUG(hci1394_async_read_response_exit,
3013             HCI1394_TNF_HAL_STACK, "");
3014 
3015         return (DDI_SUCCESS);
3016 }
3017 
3018 
3019 /*
3020  * hci1394_async_lock_response()
3021  *    Send a lock ATRESP. This routine should be called from the Services
3022  *    layer to send a response to a received lock request (ARREQ). The
3023  *    response will differ between 32-bit/64-bit lock requests.
3024  */
3025 int
3026 hci1394_async_lock_response(hci1394_async_handle_t async_handle,
3027     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv, int *result)
3028 {
3029         hci1394_basic_pkt_t header;
3030         hci1394_async_cmd_t *hcicmd;
3031         uint32_t data32;
3032         uint64_t data64;
3033         uint8_t *datap;
3034         uint_t size;
3035         int status;
3036 
3037 
3038         ASSERT(async_handle != NULL);
3039         ASSERT(cmd != NULL);
3040         ASSERT(cmd_priv != NULL);
3041         ASSERT(result != NULL);
3042 
3043         TNF_PROBE_0_DEBUG(hci1394_async_lock_response_enter,
3044             HCI1394_TNF_HAL_STACK, "");
3045 
3046         /*
3047          * make sure this call is during the current bus generation (i.e. no
3048          * bus resets have occured since this request was made.
3049          */
3050         if (cmd_priv->bus_generation != hci1394_ohci_current_busgen(
3051             async_handle->as_ohci)) {
3052                 *result = H1394_STATUS_INVALID_BUSGEN;
3053                 TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3054                     HCI1394_TNF_HAL_STACK, "");
3055                 return (DDI_FAILURE);
3056         }
3057 
3058         /*
3059          * setup a shortcut to the hal private command area. Copy the generation
3060          * to the Q area so that we can check the generation when the AT Q is
3061          * locked. This prevents us from loosing commands due to race
3062          * conditions.
3063          */
3064         hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
3065         hcicmd->ac_qcmd.qc_generation = cmd_priv->bus_generation;
3066 
3067         /*
3068          * Setup the packet header information for a ATRESP lock packet. Set
3069          * the tcode for a lock response. Set SRCBusId if the addr is not a
3070          * local bus address. Copy in the speed, tlabel, and response code.
3071          */
3072         header.q1 = DESC_ATRESP_Q1_LCK;
3073         if ((cmd->nodeID & IEEE1394_BUS_NUM_MASK) != IEEE1394_BUS_NUM_MASK) {
3074                 header.q1 |= DESC_AT_SRCBUSID;
3075         }
3076         header.q1 |= HCI1394_DESC_AT_SPD_SET(cmd_priv->speed) |
3077             HCI1394_DESC_TLABEL_SET(hcicmd->ac_tlabel.tbi_tlabel);
3078         header.q2 = (uint32_t)(HCI1394_DESC_DESTID_SET(cmd->nodeID) |
3079             HCI1394_DESC_RCODE_SET(cmd->cmd_result));
3080         header.q3 = 0;
3081 
3082         /*
3083          * If the lock result is not a resp complete, we are not going to send
3084          * any data back.with the response.
3085          */
3086         if (cmd->cmd_result != IEEE1394_RESP_COMPLETE) {
3087                 /* set response size to 0 for error. Set the extended tcode */
3088                 size = 0;
3089                 if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
3090                         header.q4 = HCI1394_DESC_DATALEN_SET(size) |
3091                             HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
3092                 } else {
3093                         header.q4 = HCI1394_DESC_DATALEN_SET(size) |
3094                             HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
3095                 }
3096 
3097                 /*
3098                  * Write response into the ATRESP Q. If we fail, we're out of
3099                  * space.
3100                  */
3101                 status = hci1394_q_at(async_handle->as_atresp_q,
3102                     &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK_RESP,
3103                     result);
3104                 if (status != DDI_SUCCESS) {
3105                         TNF_PROBE_0(hci1394_q_alloc_fail,
3106                             HCI1394_TNF_HAL_ERROR, "");
3107                         TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3108                             HCI1394_TNF_HAL_STACK, "");
3109                         return (DDI_FAILURE);
3110                 }
3111                 TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3112                     HCI1394_TNF_HAL_STACK, "");
3113                 return (DDI_SUCCESS);
3114         }
3115 
3116         /*
3117          * if the lock result is resp complete, setup the size of the response
3118          * depending on the lock size and copy the lock response data into a
3119          * local buffer. If the lock response is an arithmetic operation, swap
3120          * the data on little endian machines. If we don't know what type of
3121          * lock operation it is, someone has corrupted the command since we
3122          * had received the ARREQ.
3123          */
3124         if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_32) {
3125                 size = IEEE1394_QUADLET;
3126                 header.q4 = HCI1394_DESC_DATALEN_SET(size) |
3127                     HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l32.lock_type);
3128                 data32 = HCI1394_ARITH_LOCK_SWAP32(
3129                     cmd->cmd_u.l32.lock_type, cmd->cmd_u.l32.old_value);
3130                 datap = (uint8_t *)&data32;
3131         } else if (cmd->cmd_type == CMD1394_ASYNCH_LOCK_64) {
3132                 size = IEEE1394_OCTLET;
3133                 header.q4 = HCI1394_DESC_DATALEN_SET(size) |
3134                     HCI1394_DESC_EXTTCODE_SET(cmd->cmd_u.l64.lock_type);
3135                 data64 = HCI1394_ARITH_LOCK_SWAP64(
3136                     cmd->cmd_u.l64.lock_type, cmd->cmd_u.l64.old_value);
3137                 datap = (uint8_t *)&data64;
3138         } else {
3139                 *result = H1394_STATUS_INTERNAL_ERROR;
3140                 TNF_PROBE_0(hci1394_lock_type_fail, HCI1394_TNF_HAL_ERROR, "");
3141                 TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3142                     HCI1394_TNF_HAL_STACK, "");
3143                 return (DDI_FAILURE);
3144         }
3145 
3146         /*
3147          * Write response into the ATRESP Q. If we fail, we're out of space.
3148          * Use the local data buffer that we copied the data to above.
3149          */
3150         status = hci1394_q_at_with_data(async_handle->as_atresp_q,
3151             &hcicmd->ac_qcmd, &header, DESC_PKT_HDRLEN_AT_LOCK_RESP, datap,
3152             size, result);
3153         if (status != DDI_SUCCESS) {
3154                 TNF_PROBE_0(hci1394_q_alloc_fail, HCI1394_TNF_HAL_ERROR, "");
3155                 TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3156                     HCI1394_TNF_HAL_STACK, "");
3157                 return (DDI_FAILURE);
3158         }
3159 
3160         TNF_PROBE_0_DEBUG(hci1394_async_lock_response_exit,
3161             HCI1394_TNF_HAL_STACK, "");
3162 
3163         return (DDI_SUCCESS);
3164 }
3165 
3166 
3167 /*
3168  * hci1394_async_response_complete()
3169  *    Free up space allocted during an ARREQ.  This is called when the target
3170  *    driver and Services Layer are done with a command which was by the HAL
3171  *    during ARREQ processing.  This routine will also free up any allocated
3172  *    mblks.
3173  *
3174  *    NOTE: a target driver can hold on to a block write ARREQ mblk by setting
3175  *    the mblk pointer to NULL.  This ONLY applies to block write ARREQs. The
3176  *    HAL will no longer track the mblk for this case.
3177  */
3178 void
3179 hci1394_async_response_complete(hci1394_async_handle_t async_handle,
3180     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv)
3181 {
3182         hci1394_async_cmd_t *hcicmd;
3183 
3184 
3185         ASSERT(async_handle != NULL);
3186         ASSERT(cmd != NULL);
3187         ASSERT(cmd_priv != NULL);
3188 
3189         TNF_PROBE_0_DEBUG(hci1394_async_response_complete_enter,
3190             HCI1394_TNF_HAL_STACK, "");
3191 
3192         hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
3193 
3194         /* If we allocated an mblk for this command */
3195         if (hcicmd->ac_mblk_alloc == B_TRUE) {
3196                 /*
3197                  * Don't free mblk if it is set to NULL. This allows a target
3198                  * driver to hold on to it in the case of a block write ARREQ.
3199                  */
3200                 if (cmd->cmd_u.b.data_block != NULL) {
3201                         freeb(cmd->cmd_u.b.data_block);
3202                 }
3203         }
3204 
3205         /* free up the 1394 framework command */
3206         (void) h1394_free_cmd((void *)async_handle->as_drvinfo->di_sl_private,
3207             &cmd);
3208 
3209         TNF_PROBE_0_DEBUG(hci1394_async_response_complete_exit,
3210             HCI1394_TNF_HAL_STACK, "");
3211 }
3212 
3213 
3214 /*
3215  * hci1394_async_pending_timeout()
3216  *    This is the ARREQ Pending timeout callback routine.  It is called from
3217  *    the tlist code. There is a race condition with the ARRESP interrupt
3218  *    handler (hci1394_async_arresp_process) which requires a mutex to
3219  *    lock around the mark of the bad tlabel.
3220  *
3221  *    Once we enter this routine, the command has timed out. If the command is
3222  *    in both the ARRESP handler and here, we will consider it to have timed
3223  *    out. That code path handles the race condition more easily.
3224  */
3225 static void
3226 hci1394_async_pending_timeout(hci1394_tlist_node_t *node, void *arg)
3227 {
3228         hci1394_async_handle_t async_handle;
3229         hci1394_async_cmd_t *hcicmd;
3230 
3231 
3232         async_handle = (hci1394_async_handle_t)arg;
3233         ASSERT(async_handle != NULL);
3234         ASSERT(node != NULL);
3235         TNF_PROBE_0_DEBUG(hci1394_async_pending_timeout_enter,
3236             HCI1394_TNF_HAL_STACK, "");
3237 
3238         hcicmd = (hci1394_async_cmd_t *)node->tln_addr;
3239 
3240         /*
3241          * We do NOT want to set the command state here. That should only be
3242          * done in the ISR. The state does nothing for us here.
3243          */
3244 
3245         /*
3246          * We want a lock around tlabel_lookup/reading data into the cmd in the
3247          * ARRESP ISR processing and a lock around the tlabel_bad in this
3248          * routine. This ensures that we will not be touching the command
3249          * structure after we pass it up to the Services Layer. If we mark it as
3250          * bad first, the lookup will fail. If we get to the lookup first, the
3251          * pending list delete will fail in arresp_process() which will tell
3252          * that guy that we are in the middle of doing the timeout processing
3253          * for this command.  The ARRESP logic will just drop the response and
3254          * continue on.
3255          */
3256         mutex_enter(&hcicmd->ac_async->as_atomic_lookup);
3257         hci1394_tlabel_bad(async_handle->as_tlabel, &hcicmd->ac_tlabel);
3258         mutex_exit(&hcicmd->ac_async->as_atomic_lookup);
3259 
3260         /* Tell the Services Layer that the command has timed out */
3261         h1394_cmd_is_complete(async_handle->as_drvinfo->di_sl_private,
3262             hcicmd->ac_cmd, H1394_AT_REQ, H1394_CMD_ETIMEOUT);
3263 
3264         TNF_PROBE_0_DEBUG(hci1394_async_pending_timeout_exit,
3265             HCI1394_TNF_HAL_STACK, "");
3266 }
3267 
3268 
3269 /*
3270  * hci1394_async_timeout_calc()
3271  *    Calculate the timeout for an ATRESP. When an ARREQ is received, this
3272  *    routine is called with the time the ARREQ was received. It returns the
3273  *    time when the ATRESP is considered to have timed out. We timeout after
3274  *    split_timeout has gone by. Split timeout and the returned value are in bus
3275  *    cycles.
3276  */
3277 static uint_t
3278 hci1394_async_timeout_calc(hci1394_async_handle_t async_handle,
3279     uint_t current_time)
3280 {
3281         uint_t split_timeout;
3282         uint_t temp;
3283         uint_t carry;
3284         uint_t z;
3285 
3286 
3287         TNF_PROBE_0_DEBUG(hci1394_async_timeout_calc_enter,
3288             HCI1394_TNF_HAL_STACK, "");
3289 
3290         /* Get the current split timeout */
3291         split_timeout = hci1394_csr_split_timeout_get(async_handle->as_csr);
3292 
3293         /*
3294          * The cycle count is broken up into two sections, the 3-bit seconds
3295          * field and the 13-bit cycle count. The cycle count is in 125uS
3296          * increments.  The maximum value of cycle count is 7999 (8000 is one
3297          * second). With 13-bits, we could store up to 8191. Therefore, we don't
3298          * have a simple 16-bit addition. Hence, the code we see below.
3299          */
3300 
3301         /*
3302          * calculate the new cycle count based on the cycle count from current
3303          * time and the split timeout. If this new value is not greater than the
3304          * maximum cycle count, we don't have a carry. Go to the next step.
3305          */
3306         temp = (current_time & OHCI_CYCLE_CNT_MASK) + (split_timeout &
3307             OHCI_CYCLE_CNT_MASK);
3308         if (temp < OHCI_MAX_CYCLE_CNT) {
3309                 carry = 0;
3310 
3311         /*
3312          * the new cycle count adds up to more than the maximum cycle count,
3313          * set the carry state and adjust the total accordingly.
3314          */
3315         } else {
3316                 temp = temp - OHCI_MAX_CYCLE_CNT;
3317                 carry = 1;
3318         }
3319 
3320         /*
3321          * The timeout time equals the seconds added with the carry (1 or 0
3322          * seconds), added with the adjusted (if necessary) cycle count.
3323          * Mask the final value to get rid of any second rollovers.
3324          */
3325         z = (current_time & OHCI_CYCLE_SEC_MASK) + (split_timeout &
3326             OHCI_CYCLE_SEC_MASK) + (carry << OHCI_CYCLE_SEC_SHIFT) + temp;
3327         z = z & OHCI_TIMESTAMP_MASK;
3328 
3329         TNF_PROBE_0_DEBUG(hci1394_async_timeout_calc_exit,
3330             HCI1394_TNF_HAL_STACK, "");
3331 
3332         return (z);
3333 }
3334 
3335 
3336 /*
3337  * hci1394_async_arresp_size_get()
3338  *    Return the size of the arresp that was received in q_handle at addr.
3339  */
3340 static int
3341 hci1394_async_arresp_size_get(uint_t tcode, hci1394_q_handle_t q_handle,
3342     uint32_t *addr, uint_t *size)
3343 {
3344         uint_t data_length;
3345         uint32_t quadlet;
3346 
3347 
3348         ASSERT(q_handle != NULL);
3349         ASSERT(addr != NULL);
3350         ASSERT(size != NULL);
3351 
3352         TNF_PROBE_0_DEBUG(hci1394_get_arresp_size_enter,
3353             HCI1394_TNF_HAL_STACK, "");
3354 
3355         if (tcode == IEEE1394_TCODE_WRITE_RESP) {
3356                 *size = DESC_PKT_HDRLEN_AT_WRITE_RESP + IEEE1394_QUADLET;
3357         } else if (tcode == IEEE1394_TCODE_READ_QUADLET_RESP) {
3358                 *size = DESC_PKT_HDRLEN_AT_READQUAD_RESP + IEEE1394_QUADLET;
3359         } else if (tcode == IEEE1394_TCODE_READ_BLOCK_RESP) {
3360                 quadlet = hci1394_q_ar_get32(q_handle, &addr[3]);
3361                 data_length = HCI1394_DESC_DATALEN_GET(quadlet);
3362                 /*
3363                  * response size is in quadlets, therefore we need to
3364                  * make sure we count in the padding when figuring out
3365                  * the size used up for this response
3366                  */
3367                 *size = DESC_PKT_HDRLEN_AT_READBLOCK_RESP +
3368                     HCI1394_ALIGN_QUAD(data_length) + IEEE1394_QUADLET;
3369         } else if (tcode == IEEE1394_TCODE_LOCK_RESP) {
3370                 quadlet = hci1394_q_ar_get32(q_handle, &addr[3]);
3371                 data_length = HCI1394_DESC_DATALEN_GET(quadlet);
3372                 /*
3373                  * response size is in quadlets, therefore we need to
3374                  * make sure we count in the padding when figuring out
3375                  * the size used up for this response
3376                  */
3377                 *size = DESC_PKT_HDRLEN_AT_LOCK_RESP +
3378                     HCI1394_ALIGN_QUAD(data_length) + IEEE1394_QUADLET;
3379         } else {
3380                 TNF_PROBE_1(hci1394_async_arresp_size_tcode_err,
3381                     HCI1394_TNF_HAL_ERROR,
3382                     "unknown ARRESP received", tnf_uint, arresp_tcode, tcode);
3383                 TNF_PROBE_0_DEBUG(hci1394_get_arresp_size_exit,
3384                     HCI1394_TNF_HAL_STACK, "");
3385                 return (DDI_FAILURE);
3386         }
3387 
3388         TNF_PROBE_0_DEBUG(hci1394_get_arresp_size_exit,
3389             HCI1394_TNF_HAL_STACK, "");
3390 
3391         return (DDI_SUCCESS);
3392 }
3393 
3394 
3395 /*
3396  * hci1394_async_pending_list_flush()
3397  *    Flush out the ATREQ pending list. All commands still on the ATREQ pending
3398  *    list are considered to be completed due to a bus reset. The ATREQ and
3399  *    ARRESP Q's should be flushed before the pending Q is flushed. The ATREQ
3400  *    could have more ACK pendings and the ARRESP could have valid responses to
3401  *    pended requests.
3402  */
3403 void
3404 hci1394_async_pending_list_flush(hci1394_async_handle_t async_handle)
3405 {
3406         hci1394_tlist_node_t *node;
3407         hci1394_async_cmd_t *hcicmd;
3408 
3409 
3410         ASSERT(async_handle != NULL);
3411 
3412         TNF_PROBE_0_DEBUG(hci1394_async_pending_list_flush_enter,
3413             HCI1394_TNF_HAL_STACK, "");
3414 
3415         do {
3416                 /*
3417                  * get the first node on the pending list. This routine also
3418                  * removes the node from the list.
3419                  */
3420                 hci1394_tlist_get(async_handle->as_pending_list, &node);
3421                 if (node != NULL) {
3422                         /* set the command state to completed */
3423                         hcicmd = (hci1394_async_cmd_t *)node->tln_addr;
3424                         hcicmd->ac_state = HCI1394_CMD_STATE_COMPLETED;
3425 
3426                         /*
3427                          * Send the command up to the Services Layer with
3428                          * completed due to the bus reset for status.
3429                          */
3430                         h1394_cmd_is_complete(
3431                             async_handle->as_drvinfo->di_sl_private,
3432                             hcicmd->ac_cmd, H1394_AT_REQ,
3433                             H1394_CMD_EBUSRESET);
3434                 }
3435         } while (node != NULL);
3436 
3437         TNF_PROBE_0_DEBUG(hci1394_async_pending_list_flush_exit,
3438             HCI1394_TNF_HAL_STACK, "");
3439 }
3440 
3441 
3442 /*
3443  * hci1394_async_atreq_start()
3444  *    Setup the command pointer for the first descriptor to be fetched and
3445  *    then set the run bit. This routine will be called the first time
3446  *    a descriptor is added to the Q.
3447  */
3448 static void
3449 hci1394_async_atreq_start(void *async, uint32_t command_ptr)
3450 {
3451         hci1394_async_handle_t async_handle;
3452         ASSERT(async != NULL);
3453         TNF_PROBE_0_DEBUG(hci1394_async_atreq_start_enter,
3454             HCI1394_TNF_HAL_STACK, "");
3455         async_handle = (hci1394_async_handle_t)async;
3456         hci1394_ohci_atreq_start(async_handle->as_ohci, command_ptr);
3457         TNF_PROBE_0_DEBUG(hci1394_async_atreq_start_exit,
3458             HCI1394_TNF_HAL_STACK, "");
3459 }
3460 
3461 
3462 /*
3463  * hci1394_async_atreq_wake()
3464  *    Set the wake bit for the ATREQ DMA engine. This routine will be called
3465  *    from the Q logic after placing a descriptor on the Q.
3466  */
3467 static void
3468 hci1394_async_atreq_wake(void *async)
3469 {
3470         hci1394_async_handle_t async_handle;
3471         ASSERT(async != NULL);
3472         TNF_PROBE_0_DEBUG(hci1394_async_atreq_wake_enter,
3473             HCI1394_TNF_HAL_STACK, "");
3474         async_handle = (hci1394_async_handle_t)async;
3475         hci1394_ohci_atreq_wake(async_handle->as_ohci);
3476         TNF_PROBE_0_DEBUG(hci1394_async_atreq_wake_exit,
3477             HCI1394_TNF_HAL_STACK, "");
3478 }
3479 
3480 
3481 /*
3482  * hci1394_async_atreq_reset()
3483  *    Reset the atreq Q.  The AT DMA engines must be stopped every bus reset.
3484  *    They will restart when the next descriptor is added to the Q. We will stop
3485  *    the DMA engine and then notify the Q logic that it has been stopped so it
3486  *    knows to do a start next time it puts a descriptor on the Q.
3487  */
3488 void
3489 hci1394_async_atreq_reset(hci1394_async_handle_t async_handle)
3490 {
3491         ASSERT(async_handle != NULL);
3492         TNF_PROBE_0_DEBUG(hci1394_async_atreq_reset_enter,
3493             HCI1394_TNF_HAL_STACK, "");
3494         hci1394_ohci_atreq_stop(async_handle->as_ohci);
3495         hci1394_q_stop(async_handle->as_atreq_q);
3496         TNF_PROBE_0_DEBUG(hci1394_async_atreq_reset_exit,
3497             HCI1394_TNF_HAL_STACK, "");
3498 }
3499 
3500 
3501 /*
3502  * hci1394_async_atreq_flush()
3503  *    Flush out the atreq Q. This routine is called during bus reset processing.
3504  *    it should be called before arresp_flush() and pending_list_flush().
3505  */
3506 static void
3507 hci1394_async_atreq_flush(hci1394_async_handle_t async_handle)
3508 {
3509         boolean_t request_available;
3510         int status;
3511 
3512         ASSERT(async_handle != NULL);
3513 
3514         TNF_PROBE_0_DEBUG(hci1394_async_atreq_flush_enter,
3515             HCI1394_TNF_HAL_STACK, "");
3516 
3517         /* Clear reqTxComplete interrupt */
3518         hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_REQ_TX_CMPLT);
3519 
3520         /*
3521          * Processes all Q'd AT requests.  If the request is pended, it is
3522          * considered complete relative the the atreq engine.
3523          * flush_pending_list() will finish up the required processing for
3524          * pended requests.
3525          */
3526         do {
3527                 /* Flush the atreq Q. Process all Q'd commands */
3528                 status = hci1394_async_atreq_process(async_handle,
3529                     B_TRUE, &request_available);
3530                 if (status != DDI_SUCCESS) {
3531                         TNF_PROBE_0(hci1394_async_atreq_process_fail,
3532                             HCI1394_TNF_HAL_ERROR, "");
3533                 }
3534         } while (request_available == B_TRUE);
3535 
3536         TNF_PROBE_0_DEBUG(hci1394_async_atreq_flush_exit,
3537             HCI1394_TNF_HAL_STACK, "");
3538 }
3539 
3540 
3541 /*
3542  * hci1394_async_arresp_start()
3543  *    Setup the command pointer for the first descriptor to be fetched and
3544  *    then set the run bit. This routine will be called the first time
3545  *    a descriptor is added to the Q.
3546  */
3547 static void
3548 hci1394_async_arresp_start(void *async, uint32_t command_ptr)
3549 {
3550         hci1394_async_handle_t async_handle;
3551         ASSERT(async != NULL);
3552         TNF_PROBE_0_DEBUG(hci1394_async_arresp_start_enter,
3553             HCI1394_TNF_HAL_STACK, "");
3554         async_handle = (hci1394_async_handle_t)async;
3555         hci1394_ohci_arresp_start(async_handle->as_ohci, command_ptr);
3556         TNF_PROBE_0_DEBUG(hci1394_async_arresp_start_exit,
3557             HCI1394_TNF_HAL_STACK, "");
3558 }
3559 
3560 
3561 /*
3562  * hci1394_async_arresp_wake()
3563  *    Set the wake bit for the ARRESP DMA engine. This routine will be called
3564  *    from the Q logic after placing a descriptor on the Q.
3565  */
3566 static void
3567 hci1394_async_arresp_wake(void *async)
3568 {
3569         hci1394_async_handle_t async_handle;
3570         ASSERT(async != NULL);
3571         TNF_PROBE_0_DEBUG(hci1394_async_arresp_wake_enter,
3572             HCI1394_TNF_HAL_STACK, "");
3573         async_handle = (hci1394_async_handle_t)async;
3574         hci1394_ohci_arresp_wake(async_handle->as_ohci);
3575         TNF_PROBE_0_DEBUG(hci1394_async_arresp_wake_exit,
3576             HCI1394_TNF_HAL_STACK, "");
3577 }
3578 
3579 
3580 /*
3581  * hci1394_async_arresp_flush()
3582  *    Flush out the arresp Q. This routine is called during bus reset
3583  *    processing. This should be called before pending_list_flush(). All
3584  *    receive responses will be processed normally. The tlabels should
3585  *    not be reset until after the ARRESP Q has been flushed. Otherwise
3586  *    we would reject valid responses.
3587  */
3588 static void
3589 hci1394_async_arresp_flush(hci1394_async_handle_t async_handle)
3590 {
3591         boolean_t response_available;
3592         int status;
3593 
3594 
3595         ASSERT(async_handle != NULL);
3596 
3597         TNF_PROBE_0_DEBUG(hci1394_async_arresp_flush_enter,
3598             HCI1394_TNF_HAL_STACK, "");
3599 
3600         /* Clear reqTxComplete interrupt */
3601         hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RSPKT);
3602 
3603         do {
3604                 /* Flush the arresp Q. Process all received commands */
3605                 status = hci1394_async_arresp_process(async_handle,
3606                     &response_available);
3607                 if (status != DDI_SUCCESS) {
3608                         TNF_PROBE_0(hci1394_async_arresp_process_fail,
3609                             HCI1394_TNF_HAL_ERROR, "");
3610                 }
3611         } while (response_available == B_TRUE);
3612 
3613         TNF_PROBE_0_DEBUG(hci1394_async_arresp_flush_enter,
3614             HCI1394_TNF_HAL_STACK, "");
3615 }
3616 
3617 
3618 /*
3619  * hci1394_async_arreq_start()
3620  *    Setup the command pointer for the first descriptor to be fetched and
3621  *    then set the run bit. This routine will be called the first time
3622  *    a descriptor is added to the Q.
3623  */
3624 static void
3625 hci1394_async_arreq_start(void *async, uint32_t command_ptr)
3626 {
3627         hci1394_async_handle_t async_handle;
3628         ASSERT(async != NULL);
3629         TNF_PROBE_0_DEBUG(hci1394_async_arreq_start_enter,
3630             HCI1394_TNF_HAL_STACK, "");
3631         async_handle = (hci1394_async_handle_t)async;
3632         hci1394_ohci_arreq_start(async_handle->as_ohci, command_ptr);
3633         TNF_PROBE_0_DEBUG(hci1394_async_arreq_start_exit,
3634             HCI1394_TNF_HAL_STACK, "");
3635 }
3636 
3637 
3638 /*
3639  * hci1394_async_arreq_wake()
3640  *    Set the wake bit for the ARREQ DMA engine. This routine will be called
3641  *    from the Q logic after placing a descriptor on the Q.
3642  */
3643 static void
3644 hci1394_async_arreq_wake(void *async)
3645 {
3646         hci1394_async_handle_t async_handle;
3647         ASSERT(async != NULL);
3648         TNF_PROBE_0_DEBUG(hci1394_async_arreq_wake_enter,
3649             HCI1394_TNF_HAL_STACK, "");
3650         async_handle = (hci1394_async_handle_t)async;
3651         hci1394_ohci_arreq_wake(async_handle->as_ohci);
3652         TNF_PROBE_0_DEBUG(hci1394_async_arreq_wake_exit,
3653             HCI1394_TNF_HAL_STACK, "");
3654 }
3655 
3656 
3657 /*
3658  * hci1394_async_arreq_flush()
3659  *    Flush the ARREQ Q. This will flush up to the bus reset token in the
3660  *    ARREQ. There is no order dependency for when routine should get called
3661  *    (relative to the other Q flushing routines)
3662  */
3663 static void
3664 hci1394_async_arreq_flush(hci1394_async_handle_t async_handle)
3665 {
3666         boolean_t request_available;
3667         int status;
3668 
3669 
3670         ASSERT(async_handle != NULL);
3671         TNF_PROBE_0_DEBUG(hci1394_async_arreq_flush_enter,
3672             HCI1394_TNF_HAL_STACK, "");
3673 
3674         /*
3675          * If the last bus reset token we have seen in
3676          * hci1394_async_arreq_read_phy() matches the current generation, the
3677          * ARREQ is already flushed.  We have nothing further to do here so
3678          * return. This can happen if we are processing ARREQ's and a bus reset
3679          * occurs. Since we are already in the ISR, we will see the token before
3680          * the bus reset handler gets to run.
3681          */
3682         if (async_handle->as_phy_reset == hci1394_ohci_current_busgen(
3683             async_handle->as_ohci)) {
3684                 TNF_PROBE_0_DEBUG(hci1394_async_arreq_flush_exit,
3685                     HCI1394_TNF_HAL_STACK, "");
3686                 return;
3687         }
3688 
3689         /*
3690          * set flag to tell hci1394_async_arreq_process() that we should not
3691          * pass ARREQ's up to the Services Layer.  This will be set to B_FALSE
3692          * in hci1394_async_arreq_read_phy() when a bus reset token matching
3693          * the current generation is found.
3694          */
3695         async_handle->as_flushing_arreq = B_TRUE;
3696 
3697         /*
3698          * Process all requests that have been received or until we find the
3699          * correct bus reset token.
3700          */
3701         do {
3702                 status = hci1394_async_arreq_process(async_handle,
3703                     &request_available);
3704                 if (status != DDI_SUCCESS) {
3705                         TNF_PROBE_0(hci1394_isr_arreq_pr_fail,
3706                             HCI1394_TNF_HAL_ERROR, "");
3707                 }
3708         } while ((request_available == B_TRUE) &&
3709             (async_handle->as_flushing_arreq == B_TRUE));
3710 
3711         /*
3712          * Clear the asserted interrupt if there are no more ARREQ's to process.
3713          * We could have ARREQ's in the Q after the bus reset token since we
3714          * will set as_flushing_arreq to FALSE when we see the correct bus reset
3715          * token in hci1394_async_arreq_read_phy(). If there are more ARREQ's,
3716          * we will process them later after finishing the reset of bus reset
3717          * processing.  That is why we will leave the interrupt asserted.
3718          */
3719         if (request_available == B_FALSE) {
3720                 hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RQPKT);
3721         }
3722 
3723         TNF_PROBE_0_DEBUG(hci1394_async_arreq_flush_exit,
3724             HCI1394_TNF_HAL_STACK, "");
3725 }
3726 
3727 
3728 /*
3729  * hci1394_async_atresp_start()
3730  *    Setup the command pointer for the first descriptor to be fetched and
3731  *    then set the run bit. This routine will be called the first time
3732  *    a descriptor is added to the Q.
3733  */
3734 static void
3735 hci1394_async_atresp_start(void *async, uint32_t command_ptr)
3736 {
3737         hci1394_async_handle_t async_handle;
3738         ASSERT(async != NULL);
3739         TNF_PROBE_0_DEBUG(hci1394_async_atresp_start_enter,
3740             HCI1394_TNF_HAL_STACK, "");
3741         async_handle = (hci1394_async_handle_t)async;
3742         hci1394_ohci_atresp_start(async_handle->as_ohci, command_ptr);
3743         TNF_PROBE_0_DEBUG(hci1394_async_atresp_start_exit,
3744             HCI1394_TNF_HAL_STACK, "");
3745 }
3746 
3747 
3748 /*
3749  * hci1394_async_atresp_wake()
3750  *    Set the wake bit for the ATRESP DMA engine. This routine will be called
3751  *    from the Q logic after placing a descriptor on the Q.
3752  */
3753 static void
3754 hci1394_async_atresp_wake(void *async)
3755 {
3756         hci1394_async_handle_t async_handle;
3757         ASSERT(async != NULL);
3758         TNF_PROBE_0_DEBUG(hci1394_async_atresp_wake_enter,
3759             HCI1394_TNF_HAL_STACK, "");
3760         async_handle = (hci1394_async_handle_t)async;
3761         hci1394_ohci_atresp_wake(async_handle->as_ohci);
3762         TNF_PROBE_0_DEBUG(hci1394_async_atresp_wake_exit,
3763             HCI1394_TNF_HAL_STACK, "");
3764 }
3765 
3766 
3767 /*
3768  * hci1394_async_atresp_reset()
3769  *    Reset the atresp Q.  The AT DMA engines must be stopped every bus reset.
3770  *    They will restart when the next descriptor is added to the Q. We will stop
3771  *    the DMA engine and then notify the Q logic that it has been stopped so it
3772  *    knows to do a start next time it puts a descriptor on the Q.
3773  */
3774 void
3775 hci1394_async_atresp_reset(hci1394_async_handle_t async_handle)
3776 {
3777         ASSERT(async_handle != NULL);
3778         TNF_PROBE_0_DEBUG(hci1394_async_atresp_reset_enter,
3779             HCI1394_TNF_HAL_STACK, "");
3780         hci1394_ohci_atresp_stop(async_handle->as_ohci);
3781         hci1394_q_stop(async_handle->as_atresp_q);
3782         TNF_PROBE_0_DEBUG(hci1394_async_atresp_reset_exit,
3783             HCI1394_TNF_HAL_STACK, "");
3784 }
3785 
3786 
3787 /*
3788  * hci1394_async_atresp_flush()
3789  *    Flush all commands out of the atresp Q. This routine will be called
3790  *    during bus reset processing. There is no order dependency for when
3791  *    routine should get called (relative to the other Q flushing routines)
3792  */
3793 static void
3794 hci1394_async_atresp_flush(hci1394_async_handle_t async_handle)
3795 {
3796         boolean_t response_available;
3797         int status;
3798 
3799         ASSERT(async_handle != NULL);
3800 
3801         TNF_PROBE_0_DEBUG(hci1394_async_atresp_flush_enter,
3802             HCI1394_TNF_HAL_STACK, "");
3803 
3804         /* Clear respTxComplete interrupt */
3805         hci1394_ohci_intr_clear(async_handle->as_ohci, OHCI_INTR_RESP_TX_CMPLT);
3806 
3807         /* Processes all AT responses */
3808         do {
3809                 /* Flush the atresp Q. Process all Q'd commands */
3810                 status = hci1394_async_atresp_process(async_handle,
3811                     B_TRUE, &response_available);
3812                 if (status != DDI_SUCCESS) {
3813                         TNF_PROBE_0(hci1394_async_atresp_process_fail,
3814                             HCI1394_TNF_HAL_ERROR, "");
3815                 }
3816         } while (response_available == B_TRUE);
3817 
3818         TNF_PROBE_0_DEBUG(hci1394_async_atresp_flush_exit,
3819             HCI1394_TNF_HAL_STACK, "");
3820 }
3821 
3822 /*
3823  * hci1394_async_hcicmd_init()
3824  *    Initialize the private HAL command structure. This should be called from
3825  *    ATREQ and ARREQ routines.
3826  */
3827 static void
3828 hci1394_async_hcicmd_init(hci1394_async_handle_t async_handle,
3829     cmd1394_cmd_t *cmd, h1394_cmd_priv_t *cmd_priv,
3830     hci1394_async_cmd_t **hcicmd)
3831 {
3832         *hcicmd = (hci1394_async_cmd_t *)cmd_priv->hal_overhead;
3833         (*hcicmd)->ac_cmd = cmd;
3834         (*hcicmd)->ac_priv = cmd_priv;
3835         (*hcicmd)->ac_async = async_handle;
3836         (*hcicmd)->ac_state = HCI1394_CMD_STATE_IN_PROGRESS;
3837         (*hcicmd)->ac_dest = 0;
3838         (*hcicmd)->ac_tlabel_alloc = B_TRUE;
3839         (*hcicmd)->ac_tlabel.tbi_tlabel = 0;
3840         (*hcicmd)->ac_tlabel.tbi_destination = 0;
3841         (*hcicmd)->ac_status = 0;
3842         (*hcicmd)->ac_qcmd.qc_timestamp = 0;
3843         (*hcicmd)->ac_qcmd.qc_arg = *hcicmd;
3844         (*hcicmd)->ac_qcmd.qc_generation = cmd_priv->bus_generation;
3845         (*hcicmd)->ac_mblk_alloc = B_FALSE;
3846 }