1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* Copyright 2010 QLogic Corporation */ 23 24 /* 25 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 26 */ 27 28 #pragma ident "Copyright 2010 QLogic Corporation; ql_iocb.c" 29 30 /* 31 * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. 32 * 33 * *********************************************************************** 34 * * ** 35 * * NOTICE ** 36 * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION ** 37 * * ALL RIGHTS RESERVED ** 38 * * ** 39 * *********************************************************************** 40 * 41 */ 42 43 #include <ql_apps.h> 44 #include <ql_api.h> 45 #include <ql_debug.h> 46 #include <ql_iocb.h> 47 #include <ql_isr.h> 48 #include <ql_xioctl.h> 49 50 /* 51 * Local Function Prototypes. 52 */ 53 static int ql_req_pkt(ql_adapter_state_t *, request_t **); 54 static void ql_continuation_iocb(ql_adapter_state_t *, ddi_dma_cookie_t *, 55 uint16_t, boolean_t); 56 static void ql_isp24xx_rcvbuf(ql_adapter_state_t *); 57 static void ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *, ql_srb_t *, void *); 58 59 /* 60 * ql_start_iocb 61 * The start IOCB is responsible for building request packets 62 * on request ring and modifying ISP input pointer. 63 * 64 * Input: 65 * ha: adapter state pointer. 66 * sp: srb structure pointer. 67 * 68 * Context: 69 * Interrupt or Kernel context, no mailbox commands allowed. 70 */ 71 void 72 ql_start_iocb(ql_adapter_state_t *vha, ql_srb_t *sp) 73 { 74 ql_link_t *link; 75 request_t *pkt; 76 uint64_t *ptr64; 77 uint32_t cnt; 78 ql_adapter_state_t *ha = vha->pha; 79 80 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 81 82 /* Acquire ring lock. */ 83 REQUEST_RING_LOCK(ha); 84 85 if (sp != NULL) { 86 /* 87 * If the pending queue is not empty maintain order 88 * by puting this srb at the tail and geting the head. 89 */ 90 if ((link = ha->pending_cmds.first) != NULL) { 91 ql_add_link_b(&ha->pending_cmds, &sp->cmd); 92 /* Remove command from pending command queue */ 93 sp = link->base_address; 94 ql_remove_link(&ha->pending_cmds, &sp->cmd); 95 } 96 } else { 97 /* Get command from pending command queue if not empty. */ 98 if ((link = ha->pending_cmds.first) == NULL) { 99 /* Release ring specific lock */ 100 REQUEST_RING_UNLOCK(ha); 101 QL_PRINT_3(CE_CONT, "(%d): empty done\n", 102 ha->instance); 103 return; 104 } 105 /* Remove command from pending command queue */ 106 sp = link->base_address; 107 ql_remove_link(&ha->pending_cmds, &sp->cmd); 108 } 109 110 /* start this request and as many others as possible */ 111 for (;;) { 112 if (ha->req_q_cnt < sp->req_cnt) { 113 /* Calculate number of free request entries. */ 114 cnt = RD16_IO_REG(ha, req_out); 115 if (ha->req_ring_index < cnt) { 116 ha->req_q_cnt = (uint16_t) 117 (cnt - ha->req_ring_index); 118 } else { 119 ha->req_q_cnt = (uint16_t)(REQUEST_ENTRY_CNT - 120 (ha->req_ring_index - cnt)); 121 } 122 if (ha->req_q_cnt != 0) { 123 ha->req_q_cnt--; 124 } 125 126 /* 127 * If no room in request ring put this srb at 128 * the head of the pending queue and exit. 129 */ 130 if (ha->req_q_cnt < sp->req_cnt) { 131 QL_PRINT_8(CE_CONT, "(%d): request ring full," 132 " req_q_cnt=%d, req_ring_index=%d\n", 133 ha->instance, ha->req_q_cnt, 134 ha->req_ring_index); 135 ql_add_link_t(&ha->pending_cmds, &sp->cmd); 136 break; 137 } 138 } 139 140 /* Check for room in outstanding command list. */ 141 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { 142 ha->osc_index++; 143 if (ha->osc_index == MAX_OUTSTANDING_COMMANDS) { 144 ha->osc_index = 1; 145 } 146 if (ha->outstanding_cmds[ha->osc_index] == NULL) { 147 break; 148 } 149 } 150 /* 151 * If no room in outstanding array put this srb at 152 * the head of the pending queue and exit. 153 */ 154 if (cnt == MAX_OUTSTANDING_COMMANDS) { 155 QL_PRINT_8(CE_CONT, "(%d): no room in outstanding " 156 "array\n", ha->instance); 157 ql_add_link_t(&ha->pending_cmds, &sp->cmd); 158 break; 159 } 160 161 /* nothing to stop us now. */ 162 ha->outstanding_cmds[ha->osc_index] = sp; 163 /* create and save a unique response identifier in the srb */ 164 sp->handle = ha->adapter_stats->ncmds << OSC_INDEX_SHIFT | 165 ha->osc_index; 166 ha->req_q_cnt -= sp->req_cnt; 167 168 /* build the iocb in the request ring */ 169 pkt = ha->request_ring_ptr; 170 sp->request_ring_ptr = pkt; 171 sp->flags |= SRB_IN_TOKEN_ARRAY; 172 173 /* Zero out packet. */ 174 ptr64 = (uint64_t *)pkt; 175 *ptr64++ = 0; *ptr64++ = 0; 176 *ptr64++ = 0; *ptr64++ = 0; 177 *ptr64++ = 0; *ptr64++ = 0; 178 *ptr64++ = 0; *ptr64 = 0; 179 180 /* Setup IOCB common data. */ 181 pkt->entry_count = (uint8_t)sp->req_cnt; 182 pkt->sys_define = (uint8_t)ha->req_ring_index; 183 /* mark the iocb with the response identifier */ 184 ddi_put32(ha->hba_buf.acc_handle, &pkt->handle, 185 (uint32_t)sp->handle); 186 187 /* Setup IOCB unique data. */ 188 (sp->iocb)(vha, sp, pkt); 189 190 sp->flags |= SRB_ISP_STARTED; 191 192 QL_PRINT_5(CE_CONT, "(%d,%d): req packet, sp=%p\n", 193 ha->instance, vha->vp_index, (void *)sp); 194 QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); 195 196 /* Sync DMA buffer. */ 197 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 198 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + 199 REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE, 200 DDI_DMA_SYNC_FORDEV); 201 202 /* Adjust ring index. */ 203 ha->req_ring_index++; 204 if (ha->req_ring_index == REQUEST_ENTRY_CNT) { 205 ha->req_ring_index = 0; 206 ha->request_ring_ptr = ha->request_ring_bp; 207 } else { 208 ha->request_ring_ptr++; 209 } 210 211 /* Reset watchdog timer */ 212 sp->wdg_q_time = sp->init_wdg_q_time; 213 214 /* 215 * Send it by setting the new ring index in the ISP Request 216 * Ring In Pointer register. This is the mechanism 217 * used to notify the isp that a new iocb has been 218 * placed on the request ring. 219 */ 220 if (CFG_IST(ha, CFG_CTRL_8021)) { 221 uint32_t w32; 222 223 w32 = ha->req_ring_index << 16 | 224 ha->function_number << 5 | 4; 225 do { 226 ddi_put32(ha->db_dev_handle, ha->nx_req_in, 227 w32); 228 } while (RD_REG_DWORD(ha, ha->db_read) != w32); 229 230 } else { 231 WRT16_IO_REG(ha, req_in, ha->req_ring_index); 232 } 233 234 /* Update outstanding command count statistic. */ 235 ha->adapter_stats->ncmds++; 236 237 /* if there is a pending command, try to start it. */ 238 if ((link = ha->pending_cmds.first) == NULL) { 239 break; 240 } 241 242 /* Remove command from pending command queue */ 243 sp = link->base_address; 244 ql_remove_link(&ha->pending_cmds, &sp->cmd); 245 } 246 247 /* Release ring specific lock */ 248 REQUEST_RING_UNLOCK(ha); 249 250 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 251 } 252 253 /* 254 * ql_req_pkt 255 * Function is responsible for locking ring and 256 * getting a zeroed out request packet. 257 * 258 * Input: 259 * ha: adapter state pointer. 260 * pkt: address for packet pointer. 261 * 262 * Returns: 263 * ql local function return status code. 264 * 265 * Context: 266 * Interrupt or Kernel context, no mailbox commands allowed. 267 */ 268 static int 269 ql_req_pkt(ql_adapter_state_t *vha, request_t **pktp) 270 { 271 uint16_t cnt; 272 uint32_t *long_ptr; 273 uint32_t timer; 274 int rval = QL_FUNCTION_TIMEOUT; 275 ql_adapter_state_t *ha = vha->pha; 276 277 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 278 279 /* Wait for 30 seconds for slot. */ 280 for (timer = 30000; timer != 0; timer--) { 281 /* Acquire ring lock. */ 282 REQUEST_RING_LOCK(ha); 283 284 if (ha->req_q_cnt == 0) { 285 /* Calculate number of free request entries. */ 286 cnt = RD16_IO_REG(ha, req_out); 287 if (ha->req_ring_index < cnt) { 288 ha->req_q_cnt = (uint16_t) 289 (cnt - ha->req_ring_index); 290 } else { 291 ha->req_q_cnt = (uint16_t) 292 (REQUEST_ENTRY_CNT - 293 (ha->req_ring_index - cnt)); 294 } 295 if (ha->req_q_cnt != 0) { 296 ha->req_q_cnt--; 297 } 298 } 299 300 /* Found empty request ring slot? */ 301 if (ha->req_q_cnt != 0) { 302 ha->req_q_cnt--; 303 *pktp = ha->request_ring_ptr; 304 305 /* Zero out packet. */ 306 long_ptr = (uint32_t *)ha->request_ring_ptr; 307 for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) { 308 *long_ptr++ = 0; 309 } 310 311 /* Setup IOCB common data. */ 312 ha->request_ring_ptr->entry_count = 1; 313 ha->request_ring_ptr->sys_define = 314 (uint8_t)ha->req_ring_index; 315 ddi_put32(ha->hba_buf.acc_handle, 316 &ha->request_ring_ptr->handle, 317 (uint32_t)QL_FCA_BRAND); 318 319 rval = QL_SUCCESS; 320 321 break; 322 } 323 324 /* Release request queue lock. */ 325 REQUEST_RING_UNLOCK(ha); 326 327 drv_usecwait(MILLISEC); 328 329 /* Check for pending interrupts. */ 330 /* 331 * XXX protect interrupt routine from calling itself. 332 * Need to revisit this routine. So far we never 333 * hit this case as req slot was available 334 */ 335 if ((!(curthread->t_flag & T_INTR_THREAD)) && 336 INTERRUPT_PENDING(ha)) { 337 (void) ql_isr((caddr_t)ha); 338 INTR_LOCK(ha); 339 ha->intr_claimed = TRUE; 340 INTR_UNLOCK(ha); 341 } 342 } 343 344 if (rval != QL_SUCCESS) { 345 ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0); 346 EL(ha, "failed, rval = %xh, isp_abort_needed\n", rval); 347 } else { 348 /*EMPTY*/ 349 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 350 } 351 return (rval); 352 } 353 354 /* 355 * ql_isp_cmd 356 * Function is responsible for modifying ISP input pointer. 357 * This action notifies the isp that a new request has been 358 * added to the request ring. 359 * 360 * Releases ring lock. 361 * 362 * Input: 363 * ha: adapter state pointer. 364 * 365 * Context: 366 * Interrupt or Kernel context, no mailbox commands allowed. 367 */ 368 void 369 ql_isp_cmd(ql_adapter_state_t *vha) 370 { 371 ql_adapter_state_t *ha = vha->pha; 372 373 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 374 375 QL_PRINT_5(CE_CONT, "(%d): req packet:\n", ha->instance); 376 QL_DUMP_5((uint8_t *)ha->request_ring_ptr, 8, REQUEST_ENTRY_SIZE); 377 378 /* Sync DMA buffer. */ 379 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 380 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + 381 REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE, 382 DDI_DMA_SYNC_FORDEV); 383 384 /* Adjust ring index. */ 385 ha->req_ring_index++; 386 if (ha->req_ring_index == REQUEST_ENTRY_CNT) { 387 ha->req_ring_index = 0; 388 ha->request_ring_ptr = ha->request_ring_bp; 389 } else { 390 ha->request_ring_ptr++; 391 } 392 393 /* Set chip new ring index. */ 394 if (CFG_IST(ha, CFG_CTRL_8021)) { 395 uint32_t w32; 396 397 w32 = ha->req_ring_index << 16 | 398 ha->function_number << 5 | 4; 399 do { 400 ddi_put32(ha->db_dev_handle, ha->nx_req_in, w32); 401 } while (RD_REG_DWORD(ha, ha->db_read) != w32); 402 403 } else { 404 WRT16_IO_REG(ha, req_in, ha->req_ring_index); 405 } 406 407 /* Release ring lock. */ 408 REQUEST_RING_UNLOCK(ha); 409 410 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 411 } 412 413 /* 414 * ql_command_iocb 415 * Setup of command IOCB. 416 * 417 * Input: 418 * ha: adapter state pointer. 419 * sp: srb structure pointer. 420 * 421 * arg: request queue packet. 422 * 423 * Context: 424 * Interrupt or Kernel context, no mailbox commands allowed. 425 */ 426 void 427 ql_command_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 428 { 429 ddi_dma_cookie_t *cp; 430 uint32_t *ptr32, cnt; 431 uint16_t seg_cnt; 432 fcp_cmd_t *fcp = sp->fcp; 433 ql_tgt_t *tq = sp->lun_queue->target_queue; 434 cmd_entry_t *pkt = arg; 435 436 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 437 438 /* Set LUN number */ 439 pkt->lun_l = LSB(sp->lun_queue->lun_no); 440 pkt->lun_h = MSB(sp->lun_queue->lun_no); 441 442 /* Set target ID */ 443 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 444 pkt->target_l = LSB(tq->loop_id); 445 pkt->target_h = MSB(tq->loop_id); 446 } else { 447 pkt->target_h = LSB(tq->loop_id); 448 } 449 450 /* Set tag queue control flags */ 451 if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_HEAD_OF_Q) { 452 pkt->control_flags_l = (uint8_t) 453 (pkt->control_flags_l | CF_HTAG); 454 } else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_ORDERED) { 455 pkt->control_flags_l = (uint8_t) 456 (pkt->control_flags_l | CF_OTAG); 457 /* else if (fcp->fcp_cntl.cntl_qtype == FCP_QTYPE_SIMPLE) */ 458 } else { 459 pkt->control_flags_l = (uint8_t) 460 (pkt->control_flags_l | CF_STAG); 461 } 462 463 /* Set ISP command timeout. */ 464 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); 465 466 /* Load SCSI CDB */ 467 ddi_rep_put8(ha->hba_buf.acc_handle, fcp->fcp_cdb, 468 pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR); 469 470 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 471 pkt->entry_type = IOCB_CMD_TYPE_3; 472 cnt = CMD_TYPE_3_DATA_SEGMENTS; 473 } else { 474 pkt->entry_type = IOCB_CMD_TYPE_2; 475 cnt = CMD_TYPE_2_DATA_SEGMENTS; 476 } 477 478 if (fcp->fcp_data_len == 0) { 479 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 480 ha->xioctl->IOControlRequests++; 481 return; 482 } 483 484 /* 485 * Set transfer direction. Load Data segments. 486 */ 487 if (fcp->fcp_cntl.cntl_write_data) { 488 pkt->control_flags_l = (uint8_t) 489 (pkt->control_flags_l | CF_DATA_OUT); 490 ha->xioctl->IOOutputRequests++; 491 ha->xioctl->IOOutputByteCnt += fcp->fcp_data_len; 492 } else if (fcp->fcp_cntl.cntl_read_data) { 493 pkt->control_flags_l = (uint8_t) 494 (pkt->control_flags_l | CF_DATA_IN); 495 ha->xioctl->IOInputRequests++; 496 ha->xioctl->IOInputByteCnt += fcp->fcp_data_len; 497 } 498 499 /* Set data segment count. */ 500 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; 501 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); 502 503 /* Load total byte count. */ 504 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, fcp->fcp_data_len); 505 506 /* Load command data segment. */ 507 ptr32 = (uint32_t *)&pkt->dseg_0_address; 508 cp = sp->pkt->pkt_data_cookie; 509 while (cnt && seg_cnt) { 510 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 511 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 512 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 513 cp->dmac_notused); 514 } 515 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 516 (uint32_t)cp->dmac_size); 517 seg_cnt--; 518 cnt--; 519 cp++; 520 } 521 522 /* 523 * Build continuation packets. 524 */ 525 if (seg_cnt) { 526 ql_continuation_iocb(ha, cp, seg_cnt, 527 (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); 528 } 529 530 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 531 } 532 533 /* 534 * ql_continuation_iocb 535 * Setup of continuation IOCB. 536 * 537 * Input: 538 * ha: adapter state pointer. 539 * cp: cookie list pointer. 540 * seg_cnt: number of segments. 541 * addr64: 64 bit addresses. 542 * 543 * Context: 544 * Interrupt or Kernel context, no mailbox commands allowed. 545 */ 546 static void 547 ql_continuation_iocb(ql_adapter_state_t *ha, ddi_dma_cookie_t *cp, 548 uint16_t seg_cnt, boolean_t addr64) 549 { 550 cont_entry_t *pkt; 551 uint64_t *ptr64; 552 uint32_t *ptr32, cnt; 553 554 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 555 556 /* 557 * Build continuation packets. 558 */ 559 while (seg_cnt) { 560 /* Sync DMA buffer. */ 561 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 562 (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + 563 REQUEST_Q_BUFFER_OFFSET), REQUEST_ENTRY_SIZE, 564 DDI_DMA_SYNC_FORDEV); 565 566 /* Adjust ring pointer, and deal with wrap. */ 567 ha->req_ring_index++; 568 if (ha->req_ring_index == REQUEST_ENTRY_CNT) { 569 ha->req_ring_index = 0; 570 ha->request_ring_ptr = ha->request_ring_bp; 571 } else { 572 ha->request_ring_ptr++; 573 } 574 pkt = (cont_entry_t *)ha->request_ring_ptr; 575 576 /* Zero out packet. */ 577 ptr64 = (uint64_t *)pkt; 578 *ptr64++ = 0; *ptr64++ = 0; 579 *ptr64++ = 0; *ptr64++ = 0; 580 *ptr64++ = 0; *ptr64++ = 0; 581 *ptr64++ = 0; *ptr64 = 0; 582 583 /* 584 * Build continuation packet. 585 */ 586 pkt->entry_count = 1; 587 pkt->sys_define = (uint8_t)ha->req_ring_index; 588 if (addr64) { 589 pkt->entry_type = CONTINUATION_TYPE_1; 590 cnt = CONT_TYPE_1_DATA_SEGMENTS; 591 ptr32 = (uint32_t *) 592 &((cont_type_1_entry_t *)pkt)->dseg_0_address; 593 while (cnt && seg_cnt) { 594 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 595 cp->dmac_address); 596 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 597 cp->dmac_notused); 598 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 599 (uint32_t)cp->dmac_size); 600 seg_cnt--; 601 cnt--; 602 cp++; 603 } 604 } else { 605 pkt->entry_type = CONTINUATION_TYPE_0; 606 cnt = CONT_TYPE_0_DATA_SEGMENTS; 607 ptr32 = (uint32_t *)&pkt->dseg_0_address; 608 while (cnt && seg_cnt) { 609 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 610 cp->dmac_address); 611 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 612 (uint32_t)cp->dmac_size); 613 seg_cnt--; 614 cnt--; 615 cp++; 616 } 617 } 618 619 QL_PRINT_5(CE_CONT, "(%d): packet:\n", ha->instance); 620 QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); 621 } 622 623 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 624 } 625 626 /* 627 * ql_command_24xx_iocb 628 * Setup of ISP24xx command IOCB. 629 * 630 * Input: 631 * ha: adapter state pointer. 632 * sp: srb structure pointer. 633 * arg: request queue packet. 634 * 635 * Context: 636 * Interrupt or Kernel context, no mailbox commands allowed. 637 */ 638 void 639 ql_command_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 640 { 641 ddi_dma_cookie_t *cp; 642 uint32_t *ptr32, cnt; 643 uint16_t seg_cnt; 644 fcp_cmd_t *fcp = sp->fcp; 645 ql_tgt_t *tq = sp->lun_queue->target_queue; 646 cmd7_24xx_entry_t *pkt = arg; 647 ql_adapter_state_t *pha = ha->pha; 648 649 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 650 651 if (fcp->fcp_data_len != 0 && sp->sg_dma.dma_handle != NULL && 652 sp->pkt->pkt_data_cookie_cnt > 1) { 653 ql_cmd_24xx_type_6_iocb(ha, sp, arg); 654 QL_PRINT_3(CE_CONT, "(%d): cmd6 exit\n", ha->instance); 655 return; 656 } 657 658 pkt->entry_type = IOCB_CMD_TYPE_7; 659 660 /* Set LUN number */ 661 pkt->fcp_lun[2] = LSB(sp->lun_queue->lun_no); 662 pkt->fcp_lun[3] = MSB(sp->lun_queue->lun_no); 663 664 /* Set N_port handle */ 665 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); 666 667 /* Set target ID */ 668 pkt->target_id[0] = tq->d_id.b.al_pa; 669 pkt->target_id[1] = tq->d_id.b.area; 670 pkt->target_id[2] = tq->d_id.b.domain; 671 672 pkt->vp_index = ha->vp_index; 673 674 /* Set ISP command timeout. */ 675 if (sp->isp_timeout < 0x1999) { 676 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, 677 sp->isp_timeout); 678 } 679 680 /* Load SCSI CDB */ 681 ddi_rep_put8(pha->hba_buf.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb, 682 MAX_CMDSZ, DDI_DEV_AUTOINCR); 683 for (cnt = 0; cnt < MAX_CMDSZ; cnt += 4) { 684 ql_chg_endian((uint8_t *)&pkt->scsi_cdb + cnt, 4); 685 } 686 687 /* 688 * Set tag queue control flags 689 * Note: 690 * Cannot copy fcp->fcp_cntl.cntl_qtype directly, 691 * problem with x86 in 32bit kernel mode 692 */ 693 switch (fcp->fcp_cntl.cntl_qtype) { 694 case FCP_QTYPE_SIMPLE: 695 pkt->task = TA_STAG; 696 break; 697 case FCP_QTYPE_HEAD_OF_Q: 698 pkt->task = TA_HTAG; 699 break; 700 case FCP_QTYPE_ORDERED: 701 pkt->task = TA_OTAG; 702 break; 703 case FCP_QTYPE_ACA_Q_TAG: 704 pkt->task = TA_ACA; 705 break; 706 case FCP_QTYPE_UNTAGGED: 707 pkt->task = TA_UNTAGGED; 708 break; 709 default: 710 break; 711 } 712 713 if (fcp->fcp_data_len == 0) { 714 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 715 pha->xioctl->IOControlRequests++; 716 return; 717 } 718 719 /* Set transfer direction. */ 720 if (fcp->fcp_cntl.cntl_write_data) { 721 pkt->control_flags = CF_WR; 722 pha->xioctl->IOOutputRequests++; 723 pha->xioctl->IOOutputByteCnt += fcp->fcp_data_len; 724 } else if (fcp->fcp_cntl.cntl_read_data) { 725 pkt->control_flags = CF_RD; 726 pha->xioctl->IOInputRequests++; 727 pha->xioctl->IOInputByteCnt += fcp->fcp_data_len; 728 } 729 730 /* Set data segment count. */ 731 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; 732 ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); 733 734 /* Load total byte count. */ 735 ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count, 736 fcp->fcp_data_len); 737 738 /* Load command data segment. */ 739 ptr32 = (uint32_t *)&pkt->dseg_0_address; 740 cp = sp->pkt->pkt_data_cookie; 741 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 742 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 743 ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); 744 seg_cnt--; 745 cp++; 746 747 /* 748 * Build continuation packets. 749 */ 750 if (seg_cnt) { 751 ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE); 752 } 753 754 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 755 } 756 757 /* 758 * ql_cmd_24xx_type_6_iocb 759 * Setup of ISP24xx command type 6 IOCB. 760 * 761 * Input: 762 * ha: adapter state pointer. 763 * sp: srb structure pointer. 764 * arg: request queue packet. 765 * 766 * Context: 767 * Interrupt or Kernel context, no mailbox commands allowed. 768 */ 769 static void 770 ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 771 { 772 uint64_t addr; 773 ddi_dma_cookie_t *cp; 774 uint32_t *ptr32; 775 uint16_t seg_cnt; 776 fcp_cmd_t *fcp = sp->fcp; 777 ql_tgt_t *tq = sp->lun_queue->target_queue; 778 cmd6_24xx_entry_t *pkt = arg; 779 ql_adapter_state_t *pha = ha->pha; 780 dma_mem_t *cmem = &sp->sg_dma; 781 cmd6_2400_dma_t *cdma = cmem->bp; 782 783 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 784 785 pkt->entry_type = IOCB_CMD_TYPE_6; 786 787 bzero(cdma, sizeof (cmd6_2400_dma_t)); 788 789 /* Set LUN number */ 790 pkt->fcp_lun[2] = cdma->cmd.fcp_lun[1] = LSB(sp->lun_queue->lun_no); 791 pkt->fcp_lun[3] = cdma->cmd.fcp_lun[0] = MSB(sp->lun_queue->lun_no); 792 793 /* Set N_port handle */ 794 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); 795 796 /* Set target ID */ 797 pkt->target_id[0] = tq->d_id.b.al_pa; 798 pkt->target_id[1] = tq->d_id.b.area; 799 pkt->target_id[2] = tq->d_id.b.domain; 800 801 pkt->vp_index = ha->vp_index; 802 803 /* Set ISP command timeout. */ 804 if (sp->isp_timeout < 0x1999) { 805 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, 806 sp->isp_timeout); 807 } 808 809 /* Load SCSI CDB */ 810 ddi_rep_put8(cmem->acc_handle, fcp->fcp_cdb, cdma->cmd.scsi_cdb, 811 MAX_CMDSZ, DDI_DEV_AUTOINCR); 812 813 /* 814 * Set tag queue control flags 815 * Note: 816 * Cannot copy fcp->fcp_cntl.cntl_qtype directly, 817 * problem with x86 in 32bit kernel mode 818 */ 819 switch (fcp->fcp_cntl.cntl_qtype) { 820 case FCP_QTYPE_SIMPLE: 821 cdma->cmd.task = TA_STAG; 822 break; 823 case FCP_QTYPE_HEAD_OF_Q: 824 cdma->cmd.task = TA_HTAG; 825 break; 826 case FCP_QTYPE_ORDERED: 827 cdma->cmd.task = TA_OTAG; 828 break; 829 case FCP_QTYPE_ACA_Q_TAG: 830 cdma->cmd.task = TA_ACA; 831 break; 832 case FCP_QTYPE_UNTAGGED: 833 cdma->cmd.task = TA_UNTAGGED; 834 break; 835 default: 836 break; 837 } 838 839 /* 840 * FCP_CMND Payload Data Segment 841 */ 842 cp = cmem->cookies; 843 ddi_put16(pha->hba_buf.acc_handle, &pkt->cmnd_length, 844 sizeof (fcp_cmnd_t)); 845 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[0], 846 cp->dmac_address); 847 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[1], 848 cp->dmac_notused); 849 850 /* Set transfer direction. */ 851 if (fcp->fcp_cntl.cntl_write_data) { 852 pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_WR); 853 cdma->cmd.control_flags = CF_WR; 854 pha->xioctl->IOOutputRequests++; 855 pha->xioctl->IOOutputByteCnt += fcp->fcp_data_len; 856 } else if (fcp->fcp_cntl.cntl_read_data) { 857 pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_RD); 858 cdma->cmd.control_flags = CF_RD; 859 pha->xioctl->IOInputRequests++; 860 pha->xioctl->IOInputByteCnt += fcp->fcp_data_len; 861 } 862 863 /* 864 * FCP_DATA Data Segment Descriptor. 865 */ 866 addr = cp->dmac_laddress + sizeof (fcp_cmnd_t); 867 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[0], LSD(addr)); 868 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[1], MSD(addr)); 869 870 /* Set data segment count. */ 871 seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; 872 ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); 873 ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_length, 874 seg_cnt * 12 + 12); 875 876 /* Load total byte count. */ 877 ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count, 878 fcp->fcp_data_len); 879 ddi_put32(cmem->acc_handle, &cdma->cmd.dl, (uint32_t)fcp->fcp_data_len); 880 ql_chg_endian((uint8_t *)&cdma->cmd.dl, 4); 881 882 /* Load command data segments. */ 883 ptr32 = (uint32_t *)cdma->cookie_list; 884 cp = sp->pkt->pkt_data_cookie; 885 while (seg_cnt--) { 886 ddi_put32(cmem->acc_handle, ptr32++, cp->dmac_address); 887 ddi_put32(cmem->acc_handle, ptr32++, cp->dmac_notused); 888 ddi_put32(cmem->acc_handle, ptr32++, (uint32_t)cp->dmac_size); 889 cp++; 890 } 891 892 /* Sync DMA buffer. */ 893 (void) ddi_dma_sync(cmem->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); 894 895 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 896 } 897 898 /* 899 * ql_marker 900 * Function issues marker IOCB. 901 * 902 * Input: 903 * ha: adapter state pointer. 904 * loop_id: device loop ID 905 * lun: device LUN 906 * type: marker modifier 907 * 908 * Returns: 909 * ql local function return status code. 910 * 911 * Context: 912 * Interrupt or Kernel context, no mailbox commands allowed. 913 */ 914 int 915 ql_marker(ql_adapter_state_t *ha, uint16_t loop_id, uint16_t lun, 916 uint8_t type) 917 { 918 mrk_entry_t *pkt; 919 int rval; 920 921 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 922 923 rval = ql_req_pkt(ha, (request_t **)&pkt); 924 if (rval == QL_SUCCESS) { 925 pkt->entry_type = MARKER_TYPE; 926 927 if (CFG_IST(ha, CFG_CTRL_24258081)) { 928 marker_24xx_entry_t *pkt24 = 929 (marker_24xx_entry_t *)pkt; 930 931 pkt24->modifier = type; 932 933 /* Set LUN number */ 934 pkt24->fcp_lun[2] = LSB(lun); 935 pkt24->fcp_lun[3] = MSB(lun); 936 937 pkt24->vp_index = ha->vp_index; 938 939 /* Set N_port handle */ 940 ddi_put16(ha->pha->hba_buf.acc_handle, 941 &pkt24->n_port_hdl, loop_id); 942 943 } else { 944 pkt->modifier = type; 945 946 pkt->lun_l = LSB(lun); 947 pkt->lun_h = MSB(lun); 948 949 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 950 pkt->target_l = LSB(loop_id); 951 pkt->target_h = MSB(loop_id); 952 } else { 953 pkt->target_h = LSB(loop_id); 954 } 955 } 956 957 /* Issue command to ISP */ 958 ql_isp_cmd(ha); 959 } 960 961 if (rval != QL_SUCCESS) { 962 EL(ha, "failed, rval = %xh\n", rval); 963 } else { 964 /*EMPTY*/ 965 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 966 } 967 return (rval); 968 } 969 970 /* 971 * ql_ms_iocb 972 * Setup of name/management server IOCB. 973 * 974 * Input: 975 * ha = adapter state pointer. 976 * sp = srb structure pointer. 977 * arg = request queue packet. 978 * 979 * Context: 980 * Interrupt or Kernel context, no mailbox commands allowed. 981 */ 982 void 983 ql_ms_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 984 { 985 ddi_dma_cookie_t *cp; 986 uint32_t *ptr32; 987 uint16_t seg_cnt; 988 ql_tgt_t *tq = sp->lun_queue->target_queue; 989 ms_entry_t *pkt = arg; 990 991 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 992 QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); 993 /* 994 * Build command packet. 995 */ 996 pkt->entry_type = MS_TYPE; 997 998 /* Set loop ID */ 999 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1000 pkt->loop_id_l = LSB(tq->loop_id); 1001 pkt->loop_id_h = MSB(tq->loop_id); 1002 } else { 1003 pkt->loop_id_h = LSB(tq->loop_id); 1004 } 1005 1006 /* Set ISP command timeout. */ 1007 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); 1008 1009 /* Set cmd data segment count. */ 1010 pkt->cmd_dseg_count_l = 1; 1011 1012 /* Set total data segment count */ 1013 seg_cnt = (uint16_t)(sp->pkt->pkt_resp_cookie_cnt + 1); 1014 ddi_put16(ha->hba_buf.acc_handle, &pkt->total_dseg_count, seg_cnt); 1015 1016 /* Load ct cmd byte count. */ 1017 ddi_put32(ha->hba_buf.acc_handle, &pkt->cmd_byte_count, 1018 (uint32_t)sp->pkt->pkt_cmdlen); 1019 1020 /* Load ct rsp byte count. */ 1021 ddi_put32(ha->hba_buf.acc_handle, &pkt->resp_byte_count, 1022 (uint32_t)sp->pkt->pkt_rsplen); 1023 1024 /* Load MS command data segments. */ 1025 ptr32 = (uint32_t *)&pkt->dseg_0_address; 1026 cp = sp->pkt->pkt_cmd_cookie; 1027 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1028 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 1029 ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); 1030 seg_cnt--; 1031 1032 /* Load MS response entry data segments. */ 1033 cp = sp->pkt->pkt_resp_cookie; 1034 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1035 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 1036 ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); 1037 seg_cnt--; 1038 cp++; 1039 1040 /* 1041 * Build continuation packets. 1042 */ 1043 if (seg_cnt) { 1044 ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE); 1045 } 1046 1047 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1048 } 1049 1050 /* 1051 * ql_ms_24xx_iocb 1052 * Setup of name/management server IOCB. 1053 * 1054 * Input: 1055 * ha: adapter state pointer. 1056 * sp: srb structure pointer. 1057 * arg: request queue packet. 1058 * 1059 * Context: 1060 * Interrupt or Kernel context, no mailbox commands allowed. 1061 */ 1062 void 1063 ql_ms_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 1064 { 1065 ddi_dma_cookie_t *cp; 1066 uint32_t *ptr32; 1067 uint16_t seg_cnt; 1068 ql_tgt_t *tq = sp->lun_queue->target_queue; 1069 ct_passthru_entry_t *pkt = arg; 1070 ql_adapter_state_t *pha = ha->pha; 1071 1072 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1073 QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); 1074 /* 1075 * Build command packet. 1076 */ 1077 pkt->entry_type = CT_PASSTHRU_TYPE; 1078 1079 /* Set loop ID */ 1080 ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); 1081 1082 pkt->vp_index = ha->vp_index; 1083 1084 /* Set ISP command timeout. */ 1085 if (sp->isp_timeout < 0x1999) { 1086 ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, 1087 sp->isp_timeout); 1088 } 1089 1090 /* Set cmd/response data segment counts. */ 1091 ddi_put16(pha->hba_buf.acc_handle, &pkt->cmd_dseg_count, 1); 1092 seg_cnt = (uint16_t)sp->pkt->pkt_resp_cookie_cnt; 1093 ddi_put16(pha->hba_buf.acc_handle, &pkt->resp_dseg_count, seg_cnt); 1094 1095 /* Load ct cmd byte count. */ 1096 ddi_put32(pha->hba_buf.acc_handle, &pkt->cmd_byte_count, 1097 (uint32_t)sp->pkt->pkt_cmdlen); 1098 1099 /* Load ct rsp byte count. */ 1100 ddi_put32(pha->hba_buf.acc_handle, &pkt->resp_byte_count, 1101 (uint32_t)sp->pkt->pkt_rsplen); 1102 1103 /* Load MS command entry data segments. */ 1104 ptr32 = (uint32_t *)&pkt->dseg_0_address; 1105 cp = sp->pkt->pkt_cmd_cookie; 1106 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1107 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 1108 ddi_put32(pha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); 1109 1110 /* Load MS response entry data segments. */ 1111 cp = sp->pkt->pkt_resp_cookie; 1112 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1113 ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 1114 ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); 1115 seg_cnt--; 1116 cp++; 1117 1118 /* 1119 * Build continuation packets. 1120 */ 1121 if (seg_cnt) { 1122 ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE); 1123 } 1124 1125 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1126 } 1127 1128 /* 1129 * ql_ip_iocb 1130 * Setup of IP IOCB. 1131 * 1132 * Input: 1133 * ha: adapter state pointer. 1134 * sp: srb structure pointer. 1135 * arg: request queue packet. 1136 * 1137 * Context: 1138 * Interrupt or Kernel context, no mailbox commands allowed. 1139 */ 1140 void 1141 ql_ip_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 1142 { 1143 ddi_dma_cookie_t *cp; 1144 uint32_t *ptr32, cnt; 1145 uint16_t seg_cnt; 1146 ql_tgt_t *tq = sp->lun_queue->target_queue; 1147 ip_entry_t *pkt = arg; 1148 1149 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1150 1151 /* Set loop ID */ 1152 if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { 1153 pkt->loop_id_l = LSB(tq->loop_id); 1154 pkt->loop_id_h = MSB(tq->loop_id); 1155 } else { 1156 pkt->loop_id_h = LSB(tq->loop_id); 1157 } 1158 1159 /* Set control flags */ 1160 pkt->control_flags_l = BIT_6; 1161 if (sp->pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) { 1162 pkt->control_flags_h = BIT_7; 1163 } 1164 1165 /* Set ISP command timeout. */ 1166 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); 1167 1168 /* Set data segment count. */ 1169 seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; 1170 /* Load total byte count. */ 1171 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, 1172 (uint32_t)sp->pkt->pkt_cmdlen); 1173 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); 1174 1175 /* 1176 * Build command packet. 1177 */ 1178 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 1179 pkt->entry_type = IP_A64_TYPE; 1180 cnt = IP_A64_DATA_SEGMENTS; 1181 } else { 1182 pkt->entry_type = IP_TYPE; 1183 cnt = IP_DATA_SEGMENTS; 1184 } 1185 1186 /* Load command entry data segments. */ 1187 ptr32 = (uint32_t *)&pkt->dseg_0_address; 1188 cp = sp->pkt->pkt_cmd_cookie; 1189 while (cnt && seg_cnt) { 1190 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1191 if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { 1192 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 1193 cp->dmac_notused); 1194 } 1195 ddi_put32(ha->hba_buf.acc_handle, ptr32++, 1196 (uint32_t)cp->dmac_size); 1197 seg_cnt--; 1198 cnt--; 1199 cp++; 1200 } 1201 1202 /* 1203 * Build continuation packets. 1204 */ 1205 if (seg_cnt) { 1206 ql_continuation_iocb(ha, cp, seg_cnt, 1207 (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); 1208 } 1209 1210 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1211 } 1212 1213 /* 1214 * ql_ip_24xx_iocb 1215 * Setup of IP IOCB for ISP24xx. 1216 * 1217 * Input: 1218 * ha: adapter state pointer. 1219 * sp: srb structure pointer. 1220 * arg: request queue packet. 1221 * 1222 * Context: 1223 * Interrupt or Kernel context, no mailbox commands allowed. 1224 */ 1225 void 1226 ql_ip_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) 1227 { 1228 ddi_dma_cookie_t *cp; 1229 uint32_t *ptr32; 1230 uint16_t seg_cnt; 1231 ql_tgt_t *tq = sp->lun_queue->target_queue; 1232 ip_cmd_entry_t *pkt = arg; 1233 1234 pkt->entry_type = IP_CMD_TYPE; 1235 1236 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1237 1238 /* Set N_port handle */ 1239 ddi_put16(ha->hba_buf.acc_handle, &pkt->hdl_status, tq->loop_id); 1240 1241 /* Set ISP command timeout. */ 1242 if (sp->isp_timeout < 0x1999) { 1243 ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout_hdl, 1244 sp->isp_timeout); 1245 } 1246 1247 /* Set data segment count. */ 1248 seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; 1249 /* Load total byte count. */ 1250 ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, 1251 (uint32_t)sp->pkt->pkt_cmdlen); 1252 ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); 1253 1254 /* Set control flags */ 1255 ddi_put16(ha->hba_buf.acc_handle, &pkt->control_flags, 1256 (uint16_t)(BIT_0)); 1257 1258 /* Set frame header control flags */ 1259 ddi_put16(ha->hba_buf.acc_handle, &pkt->frame_hdr_cntrl_flgs, 1260 (uint16_t)(IPCF_LAST_SEQ | IPCF_FIRST_SEQ)); 1261 1262 /* Load command data segment. */ 1263 ptr32 = (uint32_t *)&pkt->dseg_0_address; 1264 cp = sp->pkt->pkt_cmd_cookie; 1265 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); 1266 ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); 1267 ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); 1268 seg_cnt--; 1269 cp++; 1270 1271 /* 1272 * Build continuation packets. 1273 */ 1274 if (seg_cnt) { 1275 ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE); 1276 } 1277 1278 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1279 } 1280 1281 /* 1282 * ql_isp_rcvbuf 1283 * Locates free buffers and places it on the receive buffer queue. 1284 * 1285 * Input: 1286 * ha = adapter state pointer. 1287 * 1288 * Context: 1289 * Interrupt or Kernel context, no mailbox commands allowed. 1290 */ 1291 void 1292 ql_isp_rcvbuf(ql_adapter_state_t *ha) 1293 { 1294 rcvbuf_t *container; 1295 uint16_t rcv_q_cnt; 1296 uint16_t index = 0; 1297 uint16_t index1 = 1; 1298 int debounce_count = QL_MAX_DEBOUNCE; 1299 ql_srb_t *sp; 1300 fc_unsol_buf_t *ubp; 1301 int ring_updated = FALSE; 1302 1303 if (CFG_IST(ha, CFG_CTRL_24258081)) { 1304 ql_isp24xx_rcvbuf(ha); 1305 return; 1306 } 1307 1308 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1309 1310 /* Acquire adapter state lock. */ 1311 ADAPTER_STATE_LOCK(ha); 1312 1313 /* Calculate number of free receive buffer entries. */ 1314 index = RD16_IO_REG(ha, mailbox_out[8]); 1315 do { 1316 index1 = RD16_IO_REG(ha, mailbox_out[8]); 1317 if (index1 == index) { 1318 break; 1319 } else { 1320 index = index1; 1321 } 1322 } while (debounce_count --); 1323 1324 if (debounce_count < 0) { 1325 /* This should never happen */ 1326 EL(ha, "max mb8 debounce retries exceeded\n"); 1327 } 1328 1329 rcv_q_cnt = (uint16_t)(ha->rcvbuf_ring_index < index ? 1330 index - ha->rcvbuf_ring_index : RCVBUF_CONTAINER_CNT - 1331 (ha->rcvbuf_ring_index - index)); 1332 1333 if (rcv_q_cnt == RCVBUF_CONTAINER_CNT) { 1334 rcv_q_cnt--; 1335 } 1336 1337 /* Load all free buffers in ISP receive buffer ring. */ 1338 index = 0; 1339 while (rcv_q_cnt > (uint16_t)0 && index < QL_UB_LIMIT) { 1340 /* Locate a buffer to give. */ 1341 QL_UB_LOCK(ha); 1342 while (index < QL_UB_LIMIT) { 1343 ubp = ha->ub_array[index]; 1344 if (ubp != NULL) { 1345 sp = ubp->ub_fca_private; 1346 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) && 1347 (ha->flags & IP_INITIALIZED) && 1348 (sp->flags & SRB_UB_IN_FCA) && 1349 (!(sp->flags & (SRB_UB_IN_ISP | 1350 SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK | 1351 SRB_UB_ACQUIRED)))) { 1352 sp->flags |= SRB_UB_IN_ISP; 1353 break; 1354 } 1355 } 1356 index++; 1357 } 1358 1359 if (index < QL_UB_LIMIT) { 1360 rcv_q_cnt--; 1361 index++; 1362 container = ha->rcvbuf_ring_ptr; 1363 1364 /* 1365 * Build container. 1366 */ 1367 ddi_put32(ha->hba_buf.acc_handle, 1368 (uint32_t *)(void *)&container->bufp[0], 1369 sp->ub_buffer.cookie.dmac_address); 1370 1371 ddi_put32(ha->hba_buf.acc_handle, 1372 (uint32_t *)(void *)&container->bufp[1], 1373 sp->ub_buffer.cookie.dmac_notused); 1374 1375 ddi_put16(ha->hba_buf.acc_handle, &container->handle, 1376 LSW(sp->handle)); 1377 1378 ha->ub_outcnt++; 1379 1380 /* Adjust ring index. */ 1381 ha->rcvbuf_ring_index++; 1382 if (ha->rcvbuf_ring_index == RCVBUF_CONTAINER_CNT) { 1383 ha->rcvbuf_ring_index = 0; 1384 ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp; 1385 } else { 1386 ha->rcvbuf_ring_ptr++; 1387 } 1388 1389 ring_updated = TRUE; 1390 } 1391 QL_UB_UNLOCK(ha); 1392 } 1393 1394 if (ring_updated) { 1395 /* Sync queue. */ 1396 (void) ddi_dma_sync(ha->hba_buf.dma_handle, 1397 (off_t)RCVBUF_Q_BUFFER_OFFSET, (size_t)RCVBUF_QUEUE_SIZE, 1398 DDI_DMA_SYNC_FORDEV); 1399 1400 /* Set chip new ring index. */ 1401 WRT16_IO_REG(ha, mailbox_in[8], ha->rcvbuf_ring_index); 1402 } 1403 1404 /* Release adapter state lock. */ 1405 ADAPTER_STATE_UNLOCK(ha); 1406 1407 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1408 } 1409 1410 /* 1411 * ql_isp24xx_rcvbuf 1412 * Locates free buffers and send it to adapter. 1413 * 1414 * Input: 1415 * ha = adapter state pointer. 1416 * 1417 * Context: 1418 * Interrupt or Kernel context, no mailbox commands allowed. 1419 */ 1420 static void 1421 ql_isp24xx_rcvbuf(ql_adapter_state_t *ha) 1422 { 1423 rcvbuf_t *container; 1424 uint16_t index; 1425 ql_srb_t *sp; 1426 fc_unsol_buf_t *ubp; 1427 int rval; 1428 ip_buf_pool_entry_t *pkt = NULL; 1429 1430 QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); 1431 1432 for (;;) { 1433 /* Locate a buffer to give. */ 1434 QL_UB_LOCK(ha); 1435 for (index = 0; index < QL_UB_LIMIT; index++) { 1436 ubp = ha->ub_array[index]; 1437 if (ubp != NULL) { 1438 sp = ubp->ub_fca_private; 1439 if ((sp->ub_type == FC_TYPE_IS8802_SNAP) && 1440 (ha->flags & IP_INITIALIZED) && 1441 (sp->flags & SRB_UB_IN_FCA) && 1442 (!(sp->flags & (SRB_UB_IN_ISP | 1443 SRB_UB_FREE_REQUESTED | SRB_UB_CALLBACK | 1444 SRB_UB_ACQUIRED)))) { 1445 ha->ub_outcnt++; 1446 sp->flags |= SRB_UB_IN_ISP; 1447 break; 1448 } 1449 } 1450 } 1451 QL_UB_UNLOCK(ha); 1452 if (index == QL_UB_LIMIT) { 1453 break; 1454 } 1455 1456 /* Get IOCB packet for buffers. */ 1457 if (pkt == NULL) { 1458 rval = ql_req_pkt(ha, (request_t **)&pkt); 1459 if (rval != QL_SUCCESS) { 1460 EL(ha, "failed, ql_req_pkt=%x\n", rval); 1461 QL_UB_LOCK(ha); 1462 ha->ub_outcnt--; 1463 sp->flags &= ~SRB_UB_IN_ISP; 1464 QL_UB_UNLOCK(ha); 1465 break; 1466 } 1467 pkt->entry_type = IP_BUF_POOL_TYPE; 1468 container = &pkt->buffers[0]; 1469 } 1470 1471 /* 1472 * Build container. 1473 */ 1474 ddi_put32(ha->hba_buf.acc_handle, &container->bufp[0], 1475 sp->ub_buffer.cookie.dmac_address); 1476 ddi_put32(ha->hba_buf.acc_handle, &container->bufp[1], 1477 sp->ub_buffer.cookie.dmac_notused); 1478 ddi_put16(ha->hba_buf.acc_handle, &container->handle, 1479 LSW(sp->handle)); 1480 1481 pkt->buffer_count++; 1482 container++; 1483 1484 if (pkt->buffer_count == IP_POOL_BUFFERS) { 1485 ql_isp_cmd(ha); 1486 pkt = NULL; 1487 } 1488 } 1489 1490 if (pkt != NULL) { 1491 ql_isp_cmd(ha); 1492 } 1493 1494 QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); 1495 } 1496