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