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 }