Print this page
NEX-5717 import QLogic 16G FC drivers
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>

*** 17,41 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* Copyright 2010 QLogic Corporation */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ ! #pragma ident "Copyright 2010 QLogic Corporation; ql_iocb.c" /* * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. * * *********************************************************************** * * ** * * NOTICE ** ! * * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION ** * * ALL RIGHTS RESERVED ** * * ** * *********************************************************************** * */ --- 17,41 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* Copyright 2015 QLogic Corporation */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ ! #pragma ident "Copyright 2015 QLogic Corporation; ql_iocb.c" /* * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file. * * *********************************************************************** * * ** * * NOTICE ** ! * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION ** * * ALL RIGHTS RESERVED ** * * ** * *********************************************************************** * */
*** 43,62 **** #include <ql_apps.h> #include <ql_api.h> #include <ql_debug.h> #include <ql_iocb.h> #include <ql_isr.h> #include <ql_xioctl.h> /* * Local Function Prototypes. */ ! static int ql_req_pkt(ql_adapter_state_t *, request_t **); ! static void ql_continuation_iocb(ql_adapter_state_t *, ddi_dma_cookie_t *, ! uint16_t, boolean_t); static void ql_isp24xx_rcvbuf(ql_adapter_state_t *); ! static void ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *, ql_srb_t *, void *); /* * ql_start_iocb * The start IOCB is responsible for building request packets * on request ring and modifying ISP input pointer. --- 43,67 ---- #include <ql_apps.h> #include <ql_api.h> #include <ql_debug.h> #include <ql_iocb.h> #include <ql_isr.h> + #include <ql_nx.h> #include <ql_xioctl.h> + #include <ql_fm.h> + /* * Local Function Prototypes. */ ! static int ql_req_pkt(ql_adapter_state_t *, ql_request_q_t *, request_t **); ! static void ql_isp_cmd(ql_adapter_state_t *, ql_request_q_t *); ! static void ql_continuation_iocb(ql_adapter_state_t *, ql_request_q_t *, ! ddi_dma_cookie_t *, uint16_t, boolean_t); static void ql_isp24xx_rcvbuf(ql_adapter_state_t *); ! static void ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *, ql_request_q_t *, ! ql_srb_t *, void *); /* * ql_start_iocb * The start IOCB is responsible for building request packets * on request ring and modifying ISP input pointer.
*** 70,85 **** */ void ql_start_iocb(ql_adapter_state_t *vha, ql_srb_t *sp) { ql_link_t *link; request_t *pkt; uint64_t *ptr64; uint32_t cnt; ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Acquire ring lock. */ REQUEST_RING_LOCK(ha); if (sp != NULL) { --- 75,91 ---- */ void ql_start_iocb(ql_adapter_state_t *vha, ql_srb_t *sp) { ql_link_t *link; + ql_request_q_t *req_q; request_t *pkt; uint64_t *ptr64; uint32_t cnt; ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(ha, "started\n"); /* Acquire ring lock. */ REQUEST_RING_LOCK(ha); if (sp != NULL) {
*** 96,148 **** } else { /* Get command from pending command queue if not empty. */ if ((link = ha->pending_cmds.first) == NULL) { /* Release ring specific lock */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(CE_CONT, "(%d): empty done\n", ! ha->instance); return; } /* Remove command from pending command queue */ sp = link->base_address; ql_remove_link(&ha->pending_cmds, &sp->cmd); } /* start this request and as many others as possible */ for (;;) { ! if (ha->req_q_cnt < sp->req_cnt) { /* Calculate number of free request entries. */ cnt = RD16_IO_REG(ha, req_out); ! if (ha->req_ring_index < cnt) { ! ha->req_q_cnt = (uint16_t) ! (cnt - ha->req_ring_index); } else { ! ha->req_q_cnt = (uint16_t)(REQUEST_ENTRY_CNT - ! (ha->req_ring_index - cnt)); } ! if (ha->req_q_cnt != 0) { ! ha->req_q_cnt--; } /* * If no room in request ring put this srb at * the head of the pending queue and exit. */ ! if (ha->req_q_cnt < sp->req_cnt) { ! QL_PRINT_8(CE_CONT, "(%d): request ring full," " req_q_cnt=%d, req_ring_index=%d\n", ! ha->instance, ha->req_q_cnt, ! ha->req_ring_index); ql_add_link_t(&ha->pending_cmds, &sp->cmd); break; } } /* Check for room in outstanding command list. */ ! for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { ha->osc_index++; ! if (ha->osc_index == MAX_OUTSTANDING_COMMANDS) { ha->osc_index = 1; } if (ha->outstanding_cmds[ha->osc_index] == NULL) { break; } --- 102,169 ---- } else { /* Get command from pending command queue if not empty. */ if ((link = ha->pending_cmds.first) == NULL) { /* Release ring specific lock */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(ha, "empty done\n"); return; } /* Remove command from pending command queue */ sp = link->base_address; ql_remove_link(&ha->pending_cmds, &sp->cmd); } /* start this request and as many others as possible */ for (;;) { ! if (ha->req_q[1] != NULL && sp->rsp_q_number != 0) { ! req_q = ha->req_q[1]; ! } else { ! req_q = ha->req_q[0]; ! } ! ! if (req_q->req_q_cnt < sp->req_cnt) { /* Calculate number of free request entries. */ + if (ha->flags & QUEUE_SHADOW_PTRS) { + (void) ddi_dma_sync(req_q->req_ring.dma_handle, + (off_t)req_q->req_out_shadow_ofst, + SHADOW_ENTRY_SIZE, DDI_DMA_SYNC_FORCPU); + cnt = ddi_get32(req_q->req_ring.acc_handle, + req_q->req_out_shadow_ptr); + } else if (ha->flags & MULTI_QUEUE) { + cnt = RD16_MBAR_REG(ha, req_q->mbar_req_out); + } else { cnt = RD16_IO_REG(ha, req_out); ! } ! if (req_q->req_ring_index < cnt) { ! req_q->req_q_cnt = (uint16_t) ! (cnt - req_q->req_ring_index); } else { ! req_q->req_q_cnt = ! (uint16_t)(req_q->req_entry_cnt - ! (req_q->req_ring_index - cnt)); } ! if (req_q->req_q_cnt != 0) { ! req_q->req_q_cnt--; } /* * If no room in request ring put this srb at * the head of the pending queue and exit. */ ! if (req_q->req_q_cnt < sp->req_cnt) { ! QL_PRINT_8(ha, "request ring full," " req_q_cnt=%d, req_ring_index=%d\n", ! req_q->req_q_cnt, req_q->req_ring_index); ql_add_link_t(&ha->pending_cmds, &sp->cmd); break; } } /* Check for room in outstanding command list. */ ! for (cnt = 1; cnt < ha->osc_max_cnt; cnt++) { ha->osc_index++; ! if (ha->osc_index == ha->osc_max_cnt) { ha->osc_index = 1; } if (ha->outstanding_cmds[ha->osc_index] == NULL) { break; }
*** 149,175 **** } /* * If no room in outstanding array put this srb at * the head of the pending queue and exit. */ ! if (cnt == MAX_OUTSTANDING_COMMANDS) { ! QL_PRINT_8(CE_CONT, "(%d): no room in outstanding " ! "array\n", ha->instance); ql_add_link_t(&ha->pending_cmds, &sp->cmd); break; } /* nothing to stop us now. */ ha->outstanding_cmds[ha->osc_index] = sp; /* create and save a unique response identifier in the srb */ sp->handle = ha->adapter_stats->ncmds << OSC_INDEX_SHIFT | ha->osc_index; ! ha->req_q_cnt -= sp->req_cnt; /* build the iocb in the request ring */ ! pkt = ha->request_ring_ptr; sp->request_ring_ptr = pkt; sp->flags |= SRB_IN_TOKEN_ARRAY; /* Zero out packet. */ ptr64 = (uint64_t *)pkt; *ptr64++ = 0; *ptr64++ = 0; --- 170,196 ---- } /* * If no room in outstanding array put this srb at * the head of the pending queue and exit. */ ! if (cnt == ha->osc_max_cnt) { ! QL_PRINT_8(ha, "no room in outstanding array\n"); ql_add_link_t(&ha->pending_cmds, &sp->cmd); break; } /* nothing to stop us now. */ ha->outstanding_cmds[ha->osc_index] = sp; /* create and save a unique response identifier in the srb */ sp->handle = ha->adapter_stats->ncmds << OSC_INDEX_SHIFT | ha->osc_index; ! req_q->req_q_cnt = (uint16_t)(req_q->req_q_cnt - sp->req_cnt); /* build the iocb in the request ring */ ! pkt = req_q->req_ring_ptr; sp->request_ring_ptr = pkt; + sp->req_q_number = req_q->req_q_number; sp->flags |= SRB_IN_TOKEN_ARRAY; /* Zero out packet. */ ptr64 = (uint64_t *)pkt; *ptr64++ = 0; *ptr64++ = 0;
*** 177,213 **** *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0; *ptr64 = 0; /* Setup IOCB common data. */ pkt->entry_count = (uint8_t)sp->req_cnt; ! pkt->sys_define = (uint8_t)ha->req_ring_index; /* mark the iocb with the response identifier */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->handle, (uint32_t)sp->handle); /* Setup IOCB unique data. */ ! (sp->iocb)(vha, sp, pkt); sp->flags |= SRB_ISP_STARTED; ! QL_PRINT_5(CE_CONT, "(%d,%d): req packet, sp=%p\n", ! ha->instance, vha->vp_index, (void *)sp); QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); /* Sync DMA buffer. */ ! (void) ddi_dma_sync(ha->hba_buf.dma_handle, ! (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + ! REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE, ! DDI_DMA_SYNC_FORDEV); /* Adjust ring index. */ ! ha->req_ring_index++; ! if (ha->req_ring_index == REQUEST_ENTRY_CNT) { ! ha->req_ring_index = 0; ! ha->request_ring_ptr = ha->request_ring_bp; } else { ! ha->request_ring_ptr++; } /* Reset watchdog timer */ sp->wdg_q_time = sp->init_wdg_q_time; --- 198,236 ---- *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0; *ptr64 = 0; /* Setup IOCB common data. */ pkt->entry_count = (uint8_t)sp->req_cnt; ! if (ha->req_q[1] != NULL && sp->rsp_q_number != 0) { ! pkt->entry_status = sp->rsp_q_number; ! } ! pkt->sys_define = (uint8_t)req_q->req_ring_index; ! /* mark the iocb with the response identifier */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->handle, (uint32_t)sp->handle); /* Setup IOCB unique data. */ ! (sp->iocb)(vha, req_q, sp, pkt); sp->flags |= SRB_ISP_STARTED; ! QL_PRINT_5(ha, "req packet, sp=%p\n", (void *)sp); QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); /* Sync DMA buffer. */ ! (void) ddi_dma_sync(req_q->req_ring.dma_handle, ! (off_t)(req_q->req_ring_index * REQUEST_ENTRY_SIZE), ! (size_t)REQUEST_ENTRY_SIZE, DDI_DMA_SYNC_FORDEV); /* Adjust ring index. */ ! req_q->req_ring_index++; ! if (req_q->req_ring_index == REQUEST_ENTRY_CNT) { ! req_q->req_ring_index = 0; ! req_q->req_ring_ptr = req_q->req_ring.bp; } else { ! req_q->req_ring_ptr++; } /* Reset watchdog timer */ sp->wdg_q_time = sp->init_wdg_q_time;
*** 215,236 **** * Send it by setting the new ring index in the ISP Request * Ring In Pointer register. This is the mechanism * used to notify the isp that a new iocb has been * placed on the request ring. */ ! if (CFG_IST(ha, CFG_CTRL_8021)) { ! uint32_t w32; ! ! w32 = ha->req_ring_index << 16 | ! ha->function_number << 5 | 4; ! do { ! ddi_put32(ha->db_dev_handle, ha->nx_req_in, ! w32); ! } while (RD_REG_DWORD(ha, ha->db_read) != w32); ! } else { ! WRT16_IO_REG(ha, req_in, ha->req_ring_index); } /* Update outstanding command count statistic. */ ha->adapter_stats->ncmds++; --- 238,254 ---- * Send it by setting the new ring index in the ISP Request * Ring In Pointer register. This is the mechanism * used to notify the isp that a new iocb has been * placed on the request ring. */ ! if (ha->flags & MULTI_QUEUE) { ! WR16_MBAR_REG(ha, req_q->mbar_req_in, ! req_q->req_ring_index); ! } else if (CFG_IST(ha, CFG_CTRL_82XX)) { ! ql_8021_wr_req_in(ha, req_q->req_ring_index); } else { ! WRT16_IO_REG(ha, req_in, req_q->req_ring_index); } /* Update outstanding command count statistic. */ ha->adapter_stats->ncmds++;
*** 242,321 **** /* Remove command from pending command queue */ sp = link->base_address; ql_remove_link(&ha->pending_cmds, &sp->cmd); } /* Release ring specific lock */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_req_pkt * Function is responsible for locking ring and * getting a zeroed out request packet. * * Input: * ha: adapter state pointer. * pkt: address for packet pointer. * * Returns: * ql local function return status code. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ static int ! ql_req_pkt(ql_adapter_state_t *vha, request_t **pktp) { uint16_t cnt; ! uint32_t *long_ptr; uint32_t timer; int rval = QL_FUNCTION_TIMEOUT; ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Wait for 30 seconds for slot. */ for (timer = 30000; timer != 0; timer--) { /* Acquire ring lock. */ REQUEST_RING_LOCK(ha); ! if (ha->req_q_cnt == 0) { /* Calculate number of free request entries. */ cnt = RD16_IO_REG(ha, req_out); ! if (ha->req_ring_index < cnt) { ! ha->req_q_cnt = (uint16_t) ! (cnt - ha->req_ring_index); } else { ! ha->req_q_cnt = (uint16_t) (REQUEST_ENTRY_CNT - ! (ha->req_ring_index - cnt)); } ! if (ha->req_q_cnt != 0) { ! ha->req_q_cnt--; } } /* Found empty request ring slot? */ ! if (ha->req_q_cnt != 0) { ! ha->req_q_cnt--; ! *pktp = ha->request_ring_ptr; /* Zero out packet. */ ! long_ptr = (uint32_t *)ha->request_ring_ptr; ! for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++) { ! *long_ptr++ = 0; ! } /* Setup IOCB common data. */ ! ha->request_ring_ptr->entry_count = 1; ! ha->request_ring_ptr->sys_define = ! (uint8_t)ha->req_ring_index; ! ddi_put32(ha->hba_buf.acc_handle, ! &ha->request_ring_ptr->handle, (uint32_t)QL_FCA_BRAND); rval = QL_SUCCESS; break; --- 260,357 ---- /* Remove command from pending command queue */ sp = link->base_address; ql_remove_link(&ha->pending_cmds, &sp->cmd); } + if (qlc_fm_check_acc_handle(ha, ha->dev_handle) + != DDI_FM_OK) { + qlc_fm_report_err_impact(ha, + QL_FM_EREPORT_ACC_HANDLE_CHECK); + } + /* Release ring specific lock */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(ha, "done\n"); } /* * ql_req_pkt * Function is responsible for locking ring and * getting a zeroed out request packet. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * pkt: address for packet pointer. * * Returns: * ql local function return status code. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ static int ! ql_req_pkt(ql_adapter_state_t *vha, ql_request_q_t *req_q, request_t **pktp) { uint16_t cnt; ! uint64_t *ptr64; uint32_t timer; int rval = QL_FUNCTION_TIMEOUT; ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(ha, "started\n"); /* Wait for 30 seconds for slot. */ for (timer = 30000; timer != 0; timer--) { /* Acquire ring lock. */ REQUEST_RING_LOCK(ha); ! if (req_q->req_q_cnt == 0) { /* Calculate number of free request entries. */ + if (ha->flags & QUEUE_SHADOW_PTRS) { + (void) ddi_dma_sync(req_q->req_ring.dma_handle, + (off_t)req_q->req_out_shadow_ofst, + SHADOW_ENTRY_SIZE, DDI_DMA_SYNC_FORCPU); + cnt = ddi_get32(req_q->req_ring.acc_handle, + req_q->req_out_shadow_ptr); + } else if (ha->flags & MULTI_QUEUE) { + cnt = RD16_MBAR_REG(ha, req_q->mbar_req_out); + } else { cnt = RD16_IO_REG(ha, req_out); ! } ! if (req_q->req_ring_index < cnt) { ! req_q->req_q_cnt = (uint16_t) ! (cnt - req_q->req_ring_index); } else { ! req_q->req_q_cnt = (uint16_t) (REQUEST_ENTRY_CNT - ! (req_q->req_ring_index - cnt)); } ! if (req_q->req_q_cnt != 0) { ! req_q->req_q_cnt--; } } /* Found empty request ring slot? */ ! if (req_q->req_q_cnt != 0) { ! req_q->req_q_cnt--; ! *pktp = req_q->req_ring_ptr; /* Zero out packet. */ ! ptr64 = (uint64_t *)req_q->req_ring_ptr; ! *ptr64++ = 0; *ptr64++ = 0; ! *ptr64++ = 0; *ptr64++ = 0; ! *ptr64++ = 0; *ptr64++ = 0; ! *ptr64++ = 0; *ptr64 = 0; /* Setup IOCB common data. */ ! req_q->req_ring_ptr->entry_count = 1; ! req_q->req_ring_ptr->sys_define = ! (uint8_t)req_q->req_ring_index; ! ddi_put32(req_q->req_ring.acc_handle, ! &req_q->req_ring_ptr->handle, (uint32_t)QL_FCA_BRAND); rval = QL_SUCCESS; break;
*** 344,354 **** if (rval != QL_SUCCESS) { ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0); EL(ha, "failed, rval = %xh, isp_abort_needed\n", rval); } else { /*EMPTY*/ ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } return (rval); } /* --- 380,390 ---- if (rval != QL_SUCCESS) { ql_awaken_task_daemon(ha, NULL, ISP_ABORT_NEEDED, 0); EL(ha, "failed, rval = %xh, isp_abort_needed\n", rval); } else { /*EMPTY*/ ! QL_PRINT_3(ha, "done\n"); } return (rval); } /*
*** 358,441 **** * added to the request ring. * * Releases ring lock. * * Input: ! * ha: adapter state pointer. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ ! void ! ql_isp_cmd(ql_adapter_state_t *vha) { ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); ! QL_PRINT_5(CE_CONT, "(%d): req packet:\n", ha->instance); ! QL_DUMP_5((uint8_t *)ha->request_ring_ptr, 8, REQUEST_ENTRY_SIZE); /* Sync DMA buffer. */ ! (void) ddi_dma_sync(ha->hba_buf.dma_handle, ! (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + ! REQUEST_Q_BUFFER_OFFSET), (size_t)REQUEST_ENTRY_SIZE, ! DDI_DMA_SYNC_FORDEV); /* Adjust ring index. */ ! ha->req_ring_index++; ! if (ha->req_ring_index == REQUEST_ENTRY_CNT) { ! ha->req_ring_index = 0; ! ha->request_ring_ptr = ha->request_ring_bp; } else { ! ha->request_ring_ptr++; } /* Set chip new ring index. */ ! if (CFG_IST(ha, CFG_CTRL_8021)) { ! uint32_t w32; ! ! w32 = ha->req_ring_index << 16 | ! ha->function_number << 5 | 4; ! do { ! ddi_put32(ha->db_dev_handle, ha->nx_req_in, w32); ! } while (RD_REG_DWORD(ha, ha->db_read) != w32); ! } else { ! WRT16_IO_REG(ha, req_in, ha->req_ring_index); } /* Release ring lock. */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_command_iocb * Setup of command IOCB. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. - * * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_command_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; fcp_cmd_t *fcp = sp->fcp; ql_tgt_t *tq = sp->lun_queue->target_queue; cmd_entry_t *pkt = arg; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Set LUN number */ pkt->lun_l = LSB(sp->lun_queue->lun_no); pkt->lun_h = MSB(sp->lun_queue->lun_no); --- 394,475 ---- * added to the request ring. * * Releases ring lock. * * Input: ! * vha: adapter state pointer. ! * req_q: request queue structure pointer. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ ! static void ! ql_isp_cmd(ql_adapter_state_t *vha, ql_request_q_t *req_q) { ql_adapter_state_t *ha = vha->pha; ! QL_PRINT_3(ha, "started\n"); ! QL_PRINT_5(ha, "req packet:\n"); ! QL_DUMP_5((uint8_t *)req_q->req_ring_ptr, 8, REQUEST_ENTRY_SIZE); /* Sync DMA buffer. */ ! (void) ddi_dma_sync(req_q->req_ring.dma_handle, ! (off_t)(req_q->req_ring_index * REQUEST_ENTRY_SIZE), ! (size_t)REQUEST_ENTRY_SIZE, DDI_DMA_SYNC_FORDEV); /* Adjust ring index. */ ! req_q->req_ring_index++; ! if (req_q->req_ring_index == REQUEST_ENTRY_CNT) { ! req_q->req_ring_index = 0; ! req_q->req_ring_ptr = req_q->req_ring.bp; } else { ! req_q->req_ring_ptr++; } /* Set chip new ring index. */ ! if (ha->flags & MULTI_QUEUE) { ! WR16_MBAR_REG(ha, req_q->mbar_req_in, ! req_q->req_ring_index); ! } else if (CFG_IST(ha, CFG_CTRL_82XX)) { ! ql_8021_wr_req_in(ha, req_q->req_ring_index); } else { ! WRT16_IO_REG(ha, req_in, req_q->req_ring_index); } /* Release ring lock. */ REQUEST_RING_UNLOCK(ha); ! QL_PRINT_3(ha, "done\n"); } /* * ql_command_iocb * Setup of command IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_command_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *sp, ! void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; fcp_cmd_t *fcp = sp->fcp; ql_tgt_t *tq = sp->lun_queue->target_queue; cmd_entry_t *pkt = arg; + cmd_3_entry_t *pkt3 = arg; ! QL_PRINT_3(ha, "started\n"); /* Set LUN number */ pkt->lun_l = LSB(sp->lun_queue->lun_no); pkt->lun_h = MSB(sp->lun_queue->lun_no);
*** 459,484 **** pkt->control_flags_l = (uint8_t) (pkt->control_flags_l | CF_STAG); } /* Set ISP command timeout. */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); /* Load SCSI CDB */ ! ddi_rep_put8(ha->hba_buf.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR); - if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { - pkt->entry_type = IOCB_CMD_TYPE_3; - cnt = CMD_TYPE_3_DATA_SEGMENTS; - } else { - pkt->entry_type = IOCB_CMD_TYPE_2; - cnt = CMD_TYPE_2_DATA_SEGMENTS; - } - if (fcp->fcp_data_len == 0) { ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); ha->xioctl->IOControlRequests++; return; } /* --- 493,511 ---- pkt->control_flags_l = (uint8_t) (pkt->control_flags_l | CF_STAG); } /* Set ISP command timeout. */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); /* Load SCSI CDB */ ! ddi_rep_put8(req_q->req_ring.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR); if (fcp->fcp_data_len == 0) { ! QL_PRINT_3(ha, "done\n"); ! pkt->entry_type = IOCB_CMD_TYPE_2; ha->xioctl->IOControlRequests++; return; } /*
*** 496,579 **** ha->xioctl->IOInputByteCnt += fcp->fcp_data_len; } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); /* Load total byte count. */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, fcp->fcp_data_len); /* Load command data segment. */ - ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_data_cookie; ! while (cnt && seg_cnt) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); } ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, cp, seg_cnt, (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_continuation_iocb * Setup of continuation IOCB. * * Input: * ha: adapter state pointer. * cp: cookie list pointer. * seg_cnt: number of segments. * addr64: 64 bit addresses. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ static void ! ql_continuation_iocb(ql_adapter_state_t *ha, ddi_dma_cookie_t *cp, ! uint16_t seg_cnt, boolean_t addr64) { cont_entry_t *pkt; uint64_t *ptr64; uint32_t *ptr32, cnt; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* * Build continuation packets. */ while (seg_cnt) { /* Sync DMA buffer. */ ! (void) ddi_dma_sync(ha->hba_buf.dma_handle, ! (off_t)(ha->req_ring_index * REQUEST_ENTRY_SIZE + ! REQUEST_Q_BUFFER_OFFSET), REQUEST_ENTRY_SIZE, ! DDI_DMA_SYNC_FORDEV); /* Adjust ring pointer, and deal with wrap. */ ! ha->req_ring_index++; ! if (ha->req_ring_index == REQUEST_ENTRY_CNT) { ! ha->req_ring_index = 0; ! ha->request_ring_ptr = ha->request_ring_bp; } else { ! ha->request_ring_ptr++; } ! pkt = (cont_entry_t *)ha->request_ring_ptr; /* Zero out packet. */ ptr64 = (uint64_t *)pkt; *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0; --- 523,629 ---- ha->xioctl->IOInputByteCnt += fcp->fcp_data_len; } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(req_q->req_ring.acc_handle, &pkt->dseg_count, seg_cnt); /* Load total byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->byte_count, ! fcp->fcp_data_len); /* Load command data segment. */ cp = sp->pkt->pkt_data_cookie; ! if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { ! pkt3->entry_type = IOCB_CMD_TYPE_3; ! cnt = CMD_TYPE_3_DATA_SEGMENTS; ! ! ptr32 = (uint32_t *)&pkt3->dseg; ! while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, ! cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); + ddi_put32(req_q->req_ring.acc_handle, ptr32++, + (uint32_t)cp->dmac_size); + seg_cnt--; + cnt--; + cp++; } ! } else { ! pkt->entry_type = IOCB_CMD_TYPE_2; ! cnt = CMD_TYPE_2_DATA_SEGMENTS; ! ! ptr32 = (uint32_t *)&pkt->dseg; ! while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, ! cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } + } /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, req_q, cp, seg_cnt, (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_continuation_iocb * Setup of continuation IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * cp: cookie list pointer. * seg_cnt: number of segments. * addr64: 64 bit addresses. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ + /* ARGSUSED */ static void ! ql_continuation_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ! ddi_dma_cookie_t *cp, uint16_t seg_cnt, boolean_t addr64) { cont_entry_t *pkt; + cont_type_1_entry_t *pkt1; uint64_t *ptr64; uint32_t *ptr32, cnt; ! QL_PRINT_3(ha, "started\n"); /* * Build continuation packets. */ while (seg_cnt) { /* Sync DMA buffer. */ ! (void) ddi_dma_sync(req_q->req_ring.dma_handle, ! (off_t)(req_q->req_ring_index * REQUEST_ENTRY_SIZE), ! REQUEST_ENTRY_SIZE, DDI_DMA_SYNC_FORDEV); /* Adjust ring pointer, and deal with wrap. */ ! req_q->req_ring_index++; ! if (req_q->req_ring_index == REQUEST_ENTRY_CNT) { ! req_q->req_ring_index = 0; ! req_q->req_ring_ptr = req_q->req_ring.bp; } else { ! req_q->req_ring_ptr++; } ! pkt = (cont_entry_t *)req_q->req_ring_ptr; ! pkt1 = (cont_type_1_entry_t *)req_q->req_ring_ptr; /* Zero out packet. */ ptr64 = (uint64_t *)pkt; *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0; *ptr64++ = 0;
*** 582,670 **** /* * Build continuation packet. */ pkt->entry_count = 1; ! pkt->sys_define = (uint8_t)ha->req_ring_index; if (addr64) { ! pkt->entry_type = CONTINUATION_TYPE_1; cnt = CONT_TYPE_1_DATA_SEGMENTS; ! ptr32 = (uint32_t *) ! &((cont_type_1_entry_t *)pkt)->dseg_0_address; while (cnt && seg_cnt) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } } else { pkt->entry_type = CONTINUATION_TYPE_0; cnt = CONT_TYPE_0_DATA_SEGMENTS; ! ptr32 = (uint32_t *)&pkt->dseg_0_address; while (cnt && seg_cnt) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } } ! QL_PRINT_5(CE_CONT, "(%d): packet:\n", ha->instance); QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_command_24xx_iocb * Setup of ISP24xx command IOCB. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_command_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; fcp_cmd_t *fcp = sp->fcp; ql_tgt_t *tq = sp->lun_queue->target_queue; cmd7_24xx_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); if (fcp->fcp_data_len != 0 && sp->sg_dma.dma_handle != NULL && sp->pkt->pkt_data_cookie_cnt > 1) { ! ql_cmd_24xx_type_6_iocb(ha, sp, arg); ! QL_PRINT_3(CE_CONT, "(%d): cmd6 exit\n", ha->instance); return; } pkt->entry_type = IOCB_CMD_TYPE_7; /* Set LUN number */ ! pkt->fcp_lun[2] = LSB(sp->lun_queue->lun_no); ! pkt->fcp_lun[3] = MSB(sp->lun_queue->lun_no); /* Set N_port handle */ ! ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); /* Set target ID */ pkt->target_id[0] = tq->d_id.b.al_pa; pkt->target_id[1] = tq->d_id.b.area; pkt->target_id[2] = tq->d_id.b.domain; --- 632,729 ---- /* * Build continuation packet. */ pkt->entry_count = 1; ! pkt->sys_define = (uint8_t)req_q->req_ring_index; if (addr64) { ! pkt1->entry_type = CONTINUATION_TYPE_1; cnt = CONT_TYPE_1_DATA_SEGMENTS; ! ptr32 = (uint32_t *)&pkt1->dseg; while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } } else { pkt->entry_type = CONTINUATION_TYPE_0; cnt = CONT_TYPE_0_DATA_SEGMENTS; ! ptr32 = (uint32_t *)&pkt->dseg; while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } } ! QL_PRINT_5(ha, "packet:\n"); QL_DUMP_5((uint8_t *)pkt, 8, REQUEST_ENTRY_SIZE); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_command_24xx_iocb * Setup of ISP24xx command IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_command_24xx_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ! ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; fcp_cmd_t *fcp = sp->fcp; ql_tgt_t *tq = sp->lun_queue->target_queue; cmd7_24xx_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; + fcp_ent_addr_t *fcp_ent_addr; ! QL_PRINT_3(ha, "started\n"); if (fcp->fcp_data_len != 0 && sp->sg_dma.dma_handle != NULL && sp->pkt->pkt_data_cookie_cnt > 1) { ! ql_cmd_24xx_type_6_iocb(ha, req_q, sp, arg); ! QL_PRINT_3(ha, "cmd6 exit\n"); return; } pkt->entry_type = IOCB_CMD_TYPE_7; /* Set LUN number */ ! fcp_ent_addr = (fcp_ent_addr_t *)&sp->lun_queue->lun_addr; ! pkt->fcp_lun[2] = lobyte(fcp_ent_addr->ent_addr_0); ! pkt->fcp_lun[3] = hibyte(fcp_ent_addr->ent_addr_0); ! pkt->fcp_lun[0] = lobyte(fcp_ent_addr->ent_addr_1); ! pkt->fcp_lun[1] = hibyte(fcp_ent_addr->ent_addr_1); ! pkt->fcp_lun[6] = lobyte(fcp_ent_addr->ent_addr_2); ! pkt->fcp_lun[7] = hibyte(fcp_ent_addr->ent_addr_2); ! pkt->fcp_lun[4] = lobyte(fcp_ent_addr->ent_addr_3); ! pkt->fcp_lun[5] = hibyte(fcp_ent_addr->ent_addr_3); /* Set N_port handle */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->n_port_hdl, tq->loop_id); /* Set target ID */ pkt->target_id[0] = tq->d_id.b.al_pa; pkt->target_id[1] = tq->d_id.b.area; pkt->target_id[2] = tq->d_id.b.domain;
*** 671,686 **** pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Load SCSI CDB */ ! ddi_rep_put8(pha->hba_buf.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR); for (cnt = 0; cnt < MAX_CMDSZ; cnt += 4) { ql_chg_endian((uint8_t *)&pkt->scsi_cdb + cnt, 4); } --- 730,745 ---- pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Load SCSI CDB */ ! ddi_rep_put8(req_q->req_ring.acc_handle, fcp->fcp_cdb, pkt->scsi_cdb, MAX_CMDSZ, DDI_DEV_AUTOINCR); for (cnt = 0; cnt < MAX_CMDSZ; cnt += 4) { ql_chg_endian((uint8_t *)&pkt->scsi_cdb + cnt, 4); }
*** 709,719 **** default: break; } if (fcp->fcp_data_len == 0) { ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); pha->xioctl->IOControlRequests++; return; } /* Set transfer direction. */ --- 768,778 ---- default: break; } if (fcp->fcp_data_len == 0) { ! QL_PRINT_3(ha, "done\n"); pha->xioctl->IOControlRequests++; return; } /* Set transfer direction. */
*** 727,775 **** pha->xioctl->IOInputByteCnt += fcp->fcp_data_len; } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); /* Load total byte count. */ ! ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count, fcp->fcp_data_len); /* Load command data segment. */ ! ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_data_cookie; ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_cmd_24xx_type_6_iocb * Setup of ISP24xx command type 6 IOCB. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ static void ! ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { uint64_t addr; ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; --- 786,836 ---- pha->xioctl->IOInputByteCnt += fcp->fcp_data_len; } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(req_q->req_ring.acc_handle, &pkt->dseg_count, seg_cnt); /* Load total byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->total_byte_count, fcp->fcp_data_len); /* Load command data segment. */ ! ptr32 = (uint32_t *)&pkt->dseg; cp = sp->pkt->pkt_data_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(pha, req_q, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_cmd_24xx_type_6_iocb * Setup of ISP24xx command type 6 IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ static void ! ql_cmd_24xx_type_6_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ! ql_srb_t *sp, void *arg) { uint64_t addr; ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt;
*** 777,799 **** ql_tgt_t *tq = sp->lun_queue->target_queue; cmd6_24xx_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; dma_mem_t *cmem = &sp->sg_dma; cmd6_2400_dma_t *cdma = cmem->bp; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); pkt->entry_type = IOCB_CMD_TYPE_6; bzero(cdma, sizeof (cmd6_2400_dma_t)); /* Set LUN number */ ! pkt->fcp_lun[2] = cdma->cmd.fcp_lun[1] = LSB(sp->lun_queue->lun_no); ! pkt->fcp_lun[3] = cdma->cmd.fcp_lun[0] = MSB(sp->lun_queue->lun_no); /* Set N_port handle */ ! ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); /* Set target ID */ pkt->target_id[0] = tq->d_id.b.al_pa; pkt->target_id[1] = tq->d_id.b.area; pkt->target_id[2] = tq->d_id.b.domain; --- 838,876 ---- ql_tgt_t *tq = sp->lun_queue->target_queue; cmd6_24xx_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; dma_mem_t *cmem = &sp->sg_dma; cmd6_2400_dma_t *cdma = cmem->bp; + fcp_ent_addr_t *fcp_ent_addr; ! QL_PRINT_3(ha, "started\n"); pkt->entry_type = IOCB_CMD_TYPE_6; bzero(cdma, sizeof (cmd6_2400_dma_t)); /* Set LUN number */ ! fcp_ent_addr = (fcp_ent_addr_t *)&sp->lun_queue->lun_addr; ! pkt->fcp_lun[2] = cdma->cmd.fcp_lun[2] = ! lobyte(fcp_ent_addr->ent_addr_0); ! pkt->fcp_lun[3] = cdma->cmd.fcp_lun[3] = ! hibyte(fcp_ent_addr->ent_addr_0); ! pkt->fcp_lun[0] = cdma->cmd.fcp_lun[0] = ! lobyte(fcp_ent_addr->ent_addr_1); ! pkt->fcp_lun[1] = cdma->cmd.fcp_lun[1] = ! hibyte(fcp_ent_addr->ent_addr_1); ! pkt->fcp_lun[6] = cdma->cmd.fcp_lun[6] = ! lobyte(fcp_ent_addr->ent_addr_2); ! pkt->fcp_lun[7] = cdma->cmd.fcp_lun[7] = ! hibyte(fcp_ent_addr->ent_addr_2); ! pkt->fcp_lun[4] = cdma->cmd.fcp_lun[4] = ! lobyte(fcp_ent_addr->ent_addr_3); ! pkt->fcp_lun[5] = cdma->cmd.fcp_lun[5] = ! hibyte(fcp_ent_addr->ent_addr_3); /* Set N_port handle */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->n_port_hdl, tq->loop_id); /* Set target ID */ pkt->target_id[0] = tq->d_id.b.al_pa; pkt->target_id[1] = tq->d_id.b.area; pkt->target_id[2] = tq->d_id.b.domain;
*** 800,810 **** pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Load SCSI CDB */ ddi_rep_put8(cmem->acc_handle, fcp->fcp_cdb, cdma->cmd.scsi_cdb, --- 877,887 ---- pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Load SCSI CDB */ ddi_rep_put8(cmem->acc_handle, fcp->fcp_cdb, cdma->cmd.scsi_cdb,
*** 838,852 **** /* * FCP_CMND Payload Data Segment */ cp = cmem->cookies; ! ddi_put16(pha->hba_buf.acc_handle, &pkt->cmnd_length, sizeof (fcp_cmnd_t)); ! ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[0], cp->dmac_address); ! ddi_put32(pha->hba_buf.acc_handle, &pkt->cmnd_address[1], cp->dmac_notused); /* Set transfer direction. */ if (fcp->fcp_cntl.cntl_write_data) { pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_WR); --- 915,929 ---- /* * FCP_CMND Payload Data Segment */ cp = cmem->cookies; ! ddi_put16(req_q->req_ring.acc_handle, &pkt->cmnd_length, sizeof (fcp_cmnd_t)); ! ddi_put32(req_q->req_ring.acc_handle, &pkt->cmnd_address[0], cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, &pkt->cmnd_address[1], cp->dmac_notused); /* Set transfer direction. */ if (fcp->fcp_cntl.cntl_write_data) { pkt->control_flags = (uint8_t)(CF_DSD_PTR | CF_WR);
*** 862,882 **** /* * FCP_DATA Data Segment Descriptor. */ addr = cp->dmac_laddress + sizeof (fcp_cmnd_t); ! ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[0], LSD(addr)); ! ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_address[1], MSD(addr)); /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(pha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); ! ddi_put32(pha->hba_buf.acc_handle, &pkt->dseg_0_length, seg_cnt * 12 + 12); /* Load total byte count. */ ! ddi_put32(pha->hba_buf.acc_handle, &pkt->total_byte_count, fcp->fcp_data_len); ddi_put32(cmem->acc_handle, &cdma->cmd.dl, (uint32_t)fcp->fcp_data_len); ql_chg_endian((uint8_t *)&cdma->cmd.dl, 4); /* Load command data segments. */ --- 939,959 ---- /* * FCP_DATA Data Segment Descriptor. */ addr = cp->dmac_laddress + sizeof (fcp_cmnd_t); ! ddi_put32(req_q->req_ring.acc_handle, &pkt->dseg.address[0], LSD(addr)); ! ddi_put32(req_q->req_ring.acc_handle, &pkt->dseg.address[1], MSD(addr)); /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_data_cookie_cnt; ! ddi_put16(req_q->req_ring.acc_handle, &pkt->dseg_count, seg_cnt); ! ddi_put32(req_q->req_ring.acc_handle, &pkt->dseg.length, seg_cnt * 12 + 12); /* Load total byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->total_byte_count, fcp->fcp_data_len); ddi_put32(cmem->acc_handle, &cdma->cmd.dl, (uint32_t)fcp->fcp_data_len); ql_chg_endian((uint8_t *)&cdma->cmd.dl, 4); /* Load command data segments. */
*** 890,952 **** } /* Sync DMA buffer. */ (void) ddi_dma_sync(cmem->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_marker * Function issues marker IOCB. * * Input: * ha: adapter state pointer. * loop_id: device loop ID ! * lun: device LUN * type: marker modifier * * Returns: * ql local function return status code. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ int ! ql_marker(ql_adapter_state_t *ha, uint16_t loop_id, uint16_t lun, uint8_t type) { mrk_entry_t *pkt; int rval; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); ! rval = ql_req_pkt(ha, (request_t **)&pkt); if (rval == QL_SUCCESS) { pkt->entry_type = MARKER_TYPE; ! if (CFG_IST(ha, CFG_CTRL_24258081)) { marker_24xx_entry_t *pkt24 = (marker_24xx_entry_t *)pkt; pkt24->modifier = type; /* Set LUN number */ ! pkt24->fcp_lun[2] = LSB(lun); ! pkt24->fcp_lun[3] = MSB(lun); pkt24->vp_index = ha->vp_index; /* Set N_port handle */ ! ddi_put16(ha->pha->hba_buf.acc_handle, &pkt24->n_port_hdl, loop_id); } else { pkt->modifier = type; ! pkt->lun_l = LSB(lun); ! pkt->lun_h = MSB(lun); if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { pkt->target_l = LSB(loop_id); pkt->target_h = MSB(loop_id); } else { --- 967,1050 ---- } /* Sync DMA buffer. */ (void) ddi_dma_sync(cmem->dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); ! QL_PRINT_3(ha, "done\n"); } /* * ql_marker * Function issues marker IOCB. * * Input: * ha: adapter state pointer. * loop_id: device loop ID ! * lq: LUN queue pointer. * type: marker modifier * * Returns: * ql local function return status code. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ int ! ql_marker(ql_adapter_state_t *ha, uint16_t loop_id, ql_lun_t *lq, uint8_t type) { mrk_entry_t *pkt; int rval; + ql_request_q_t *req_q = ha->req_q[0]; + fcp_ent_addr_t *fcp_ent_addr; ! QL_PRINT_3(ha, "started\n"); ! rval = ql_req_pkt(ha, req_q, (request_t **)&pkt); if (rval == QL_SUCCESS) { pkt->entry_type = MARKER_TYPE; ! if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) { marker_24xx_entry_t *pkt24 = (marker_24xx_entry_t *)pkt; pkt24->modifier = type; /* Set LUN number */ ! if (lq) { ! fcp_ent_addr = (fcp_ent_addr_t *)&lq->lun_addr; ! pkt24->fcp_lun[2] = ! lobyte(fcp_ent_addr->ent_addr_0); ! pkt24->fcp_lun[3] = ! hibyte(fcp_ent_addr->ent_addr_0); ! pkt24->fcp_lun[0] = ! lobyte(fcp_ent_addr->ent_addr_1); ! pkt24->fcp_lun[1] = ! hibyte(fcp_ent_addr->ent_addr_1); ! pkt24->fcp_lun[6] = ! lobyte(fcp_ent_addr->ent_addr_2); ! pkt24->fcp_lun[7] = ! hibyte(fcp_ent_addr->ent_addr_2); ! pkt24->fcp_lun[4] = ! lobyte(fcp_ent_addr->ent_addr_3); ! pkt24->fcp_lun[5] = ! hibyte(fcp_ent_addr->ent_addr_3); ! } pkt24->vp_index = ha->vp_index; /* Set N_port handle */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt24->n_port_hdl, loop_id); } else { pkt->modifier = type; ! if (lq) { ! pkt->lun_l = LSB(lq->lun_no); ! pkt->lun_h = MSB(lq->lun_no); ! } if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { pkt->target_l = LSB(loop_id); pkt->target_h = MSB(loop_id); } else {
*** 953,996 **** pkt->target_h = LSB(loop_id); } } /* Issue command to ISP */ ! ql_isp_cmd(ha); } if (rval != QL_SUCCESS) { EL(ha, "failed, rval = %xh\n", rval); } else { /*EMPTY*/ ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } return (rval); } /* * ql_ms_iocb * Setup of name/management server IOCB. * * Input: ! * ha = adapter state pointer. ! * sp = srb structure pointer. ! * arg = request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ms_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ms_entry_t *pkt = arg; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); /* * Build command packet. */ pkt->entry_type = MS_TYPE; --- 1051,1096 ---- pkt->target_h = LSB(loop_id); } } /* Issue command to ISP */ ! ql_isp_cmd(ha, req_q); } if (rval != QL_SUCCESS) { EL(ha, "failed, rval = %xh\n", rval); } else { /*EMPTY*/ ! QL_PRINT_3(ha, "done\n"); } return (rval); } /* * ql_ms_iocb * Setup of name/management server IOCB. * * Input: ! * ha: adapter state pointer. ! * req_q: request queue structure pointer. ! * sp: srb structure pointer. ! * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ms_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *sp, ! void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ms_entry_t *pkt = arg; ! QL_PRINT_3(ha, "started\n"); QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); /* * Build command packet. */ pkt->entry_type = MS_TYPE;
*** 1002,1154 **** } else { pkt->loop_id_h = LSB(tq->loop_id); } /* Set ISP command timeout. */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); /* Set cmd data segment count. */ pkt->cmd_dseg_count_l = 1; /* Set total data segment count */ seg_cnt = (uint16_t)(sp->pkt->pkt_resp_cookie_cnt + 1); ! ddi_put16(ha->hba_buf.acc_handle, &pkt->total_dseg_count, seg_cnt); /* Load ct cmd byte count. */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->cmd_byte_count, (uint32_t)sp->pkt->pkt_cmdlen); /* Load ct rsp byte count. */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->resp_byte_count, (uint32_t)sp->pkt->pkt_rsplen); /* Load MS command data segments. */ ! ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; /* Load MS response entry data segments. */ cp = sp->pkt->pkt_resp_cookie; ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_ms_24xx_iocb * Setup of name/management server IOCB. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ms_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ct_passthru_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); /* * Build command packet. */ pkt->entry_type = CT_PASSTHRU_TYPE; /* Set loop ID */ ! ddi_put16(pha->hba_buf.acc_handle, &pkt->n_port_hdl, tq->loop_id); pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(pha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Set cmd/response data segment counts. */ ! ddi_put16(pha->hba_buf.acc_handle, &pkt->cmd_dseg_count, 1); seg_cnt = (uint16_t)sp->pkt->pkt_resp_cookie_cnt; ! ddi_put16(pha->hba_buf.acc_handle, &pkt->resp_dseg_count, seg_cnt); /* Load ct cmd byte count. */ ! ddi_put32(pha->hba_buf.acc_handle, &pkt->cmd_byte_count, (uint32_t)sp->pkt->pkt_cmdlen); /* Load ct rsp byte count. */ ! ddi_put32(pha->hba_buf.acc_handle, &pkt->resp_byte_count, (uint32_t)sp->pkt->pkt_rsplen); /* Load MS command entry data segments. */ ! ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); /* Load MS response entry data segments. */ cp = sp->pkt->pkt_resp_cookie; ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(pha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(pha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(pha, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_ip_iocb * Setup of IP IOCB. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ip_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ip_entry_t *pkt = arg; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Set loop ID */ if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { pkt->loop_id_l = LSB(tq->loop_id); pkt->loop_id_h = MSB(tq->loop_id); --- 1102,1259 ---- } else { pkt->loop_id_h = LSB(tq->loop_id); } /* Set ISP command timeout. */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); /* Set cmd data segment count. */ pkt->cmd_dseg_count_l = 1; /* Set total data segment count */ seg_cnt = (uint16_t)(sp->pkt->pkt_resp_cookie_cnt + 1); ! ddi_put16(req_q->req_ring.acc_handle, &pkt->total_dseg_count, seg_cnt); /* Load ct cmd byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->cmd_byte_count, (uint32_t)sp->pkt->pkt_cmdlen); /* Load ct rsp byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->resp_byte_count, (uint32_t)sp->pkt->pkt_rsplen); /* Load MS command data segments. */ ! ptr32 = (uint32_t *)&pkt->dseg; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; /* Load MS response entry data segments. */ cp = sp->pkt->pkt_resp_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, req_q, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_ms_24xx_iocb * Setup of name/management server IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ms_24xx_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *sp, ! void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ct_passthru_entry_t *pkt = arg; ql_adapter_state_t *pha = ha->pha; ! QL_PRINT_3(ha, "started\n"); QL_DUMP_3(sp->pkt->pkt_cmd, 8, sp->pkt->pkt_cmdlen); /* * Build command packet. */ pkt->entry_type = CT_PASSTHRU_TYPE; /* Set loop ID */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->n_port_hdl, tq->loop_id); pkt->vp_index = ha->vp_index; /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); } /* Set cmd/response data segment counts. */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->cmd_dseg_count, 1); seg_cnt = (uint16_t)sp->pkt->pkt_resp_cookie_cnt; ! ddi_put16(req_q->req_ring.acc_handle, &pkt->resp_dseg_count, seg_cnt); /* Load ct cmd byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->cmd_byte_count, (uint32_t)sp->pkt->pkt_cmdlen); /* Load ct rsp byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->resp_byte_count, (uint32_t)sp->pkt->pkt_rsplen); /* Load MS command entry data segments. */ ! ptr32 = (uint32_t *)&pkt->dseg; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); /* Load MS response entry data segments. */ cp = sp->pkt->pkt_resp_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(pha, req_q, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_ip_iocb * Setup of IP IOCB. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ip_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *sp, ! void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32, cnt; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ip_entry_t *pkt = arg; + ip_a64_entry_t *pkt64 = arg; ! QL_PRINT_3(ha, "started\n"); /* Set loop ID */ if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) { pkt->loop_id_l = LSB(tq->loop_id); pkt->loop_id_h = MSB(tq->loop_id);
*** 1161,1283 **** if (sp->pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) { pkt->control_flags_h = BIT_7; } /* Set ISP command timeout. */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout, sp->isp_timeout); /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; /* Load total byte count. */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, (uint32_t)sp->pkt->pkt_cmdlen); ! ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); /* * Build command packet. */ - if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { - pkt->entry_type = IP_A64_TYPE; - cnt = IP_A64_DATA_SEGMENTS; - } else { - pkt->entry_type = IP_TYPE; - cnt = IP_DATA_SEGMENTS; - } /* Load command entry data segments. */ - ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_cmd_cookie; ! while (cnt && seg_cnt) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); } ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, cp, seg_cnt, (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_ip_24xx_iocb * Setup of IP IOCB for ISP24xx. * * Input: * ha: adapter state pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ip_24xx_iocb(ql_adapter_state_t *ha, ql_srb_t *sp, void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ip_cmd_entry_t *pkt = arg; pkt->entry_type = IP_CMD_TYPE; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Set N_port handle */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->hdl_status, tq->loop_id); /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(ha->hba_buf.acc_handle, &pkt->timeout_hdl, sp->isp_timeout); } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; /* Load total byte count. */ ! ddi_put32(ha->hba_buf.acc_handle, &pkt->byte_count, (uint32_t)sp->pkt->pkt_cmdlen); ! ddi_put16(ha->hba_buf.acc_handle, &pkt->dseg_count, seg_cnt); /* Set control flags */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->control_flags, (uint16_t)(BIT_0)); /* Set frame header control flags */ ! ddi_put16(ha->hba_buf.acc_handle, &pkt->frame_hdr_cntrl_flgs, (uint16_t)(IPCF_LAST_SEQ | IPCF_FIRST_SEQ)); /* Load command data segment. */ ! ptr32 = (uint32_t *)&pkt->dseg_0_address; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(ha->hba_buf.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_isp_rcvbuf * Locates free buffers and places it on the receive buffer queue. --- 1266,1400 ---- if (sp->pkt->pkt_tran_flags & FC_TRAN_HI_PRIORITY) { pkt->control_flags_h = BIT_7; } /* Set ISP command timeout. */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout, sp->isp_timeout); /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; /* Load total byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->byte_count, (uint32_t)sp->pkt->pkt_cmdlen); ! ddi_put16(req_q->req_ring.acc_handle, &pkt->dseg_count, seg_cnt); /* * Build command packet. */ /* Load command entry data segments. */ cp = sp->pkt->pkt_cmd_cookie; ! if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) { ! pkt64->entry_type = IP_A64_TYPE; ! cnt = IP_A64_DATA_SEGMENTS; ! ptr32 = (uint32_t *)&pkt64->dseg; ! while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, ! cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); + ddi_put32(req_q->req_ring.acc_handle, ptr32++, + (uint32_t)cp->dmac_size); + seg_cnt--; + cnt--; + cp++; } ! } else { ! pkt->entry_type = IP_TYPE; ! cnt = IP_DATA_SEGMENTS; ! ptr32 = (uint32_t *)&pkt->dseg; ! while (cnt && seg_cnt) { ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, ! cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, (uint32_t)cp->dmac_size); seg_cnt--; cnt--; cp++; } + } /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, req_q, cp, seg_cnt, (boolean_t)(CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING))); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_ip_24xx_iocb * Setup of IP IOCB for ISP24xx. * * Input: * ha: adapter state pointer. + * req_q: request queue structure pointer. * sp: srb structure pointer. * arg: request queue packet. * * Context: * Interrupt or Kernel context, no mailbox commands allowed. */ void ! ql_ip_24xx_iocb(ql_adapter_state_t *ha, ql_request_q_t *req_q, ql_srb_t *sp, ! void *arg) { ddi_dma_cookie_t *cp; uint32_t *ptr32; uint16_t seg_cnt; ql_tgt_t *tq = sp->lun_queue->target_queue; ip_cmd_entry_t *pkt = arg; pkt->entry_type = IP_CMD_TYPE; ! QL_PRINT_3(ha, "started\n"); /* Set N_port handle */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->hdl_status, tq->loop_id); /* Set ISP command timeout. */ if (sp->isp_timeout < 0x1999) { ! ddi_put16(req_q->req_ring.acc_handle, &pkt->timeout_hdl, sp->isp_timeout); } /* Set data segment count. */ seg_cnt = (uint16_t)sp->pkt->pkt_cmd_cookie_cnt; /* Load total byte count. */ ! ddi_put32(req_q->req_ring.acc_handle, &pkt->byte_count, (uint32_t)sp->pkt->pkt_cmdlen); ! ddi_put16(req_q->req_ring.acc_handle, &pkt->dseg_count, seg_cnt); /* Set control flags */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->control_flags, (uint16_t)(BIT_0)); /* Set frame header control flags */ ! ddi_put16(req_q->req_ring.acc_handle, &pkt->frame_hdr_cntrl_flgs, (uint16_t)(IPCF_LAST_SEQ | IPCF_FIRST_SEQ)); /* Load command data segment. */ ! ptr32 = (uint32_t *)&pkt->dseg; cp = sp->pkt->pkt_cmd_cookie; ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, ptr32++, cp->dmac_notused); ! ddi_put32(req_q->req_ring.acc_handle, ptr32, (uint32_t)cp->dmac_size); seg_cnt--; cp++; /* * Build continuation packets. */ if (seg_cnt) { ! ql_continuation_iocb(ha, req_q, cp, seg_cnt, B_TRUE); } ! QL_PRINT_3(ha, "done\n"); } /* * ql_isp_rcvbuf * Locates free buffers and places it on the receive buffer queue.
*** 1298,1313 **** int debounce_count = QL_MAX_DEBOUNCE; ql_srb_t *sp; fc_unsol_buf_t *ubp; int ring_updated = FALSE; ! if (CFG_IST(ha, CFG_CTRL_24258081)) { ql_isp24xx_rcvbuf(ha); return; } ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); /* Acquire adapter state lock. */ ADAPTER_STATE_LOCK(ha); /* Calculate number of free receive buffer entries. */ --- 1415,1430 ---- int debounce_count = QL_MAX_DEBOUNCE; ql_srb_t *sp; fc_unsol_buf_t *ubp; int ring_updated = FALSE; ! if (CFG_IST(ha, CFG_CTRL_24XX)) { ql_isp24xx_rcvbuf(ha); return; } ! QL_PRINT_3(ha, "started\n"); /* Acquire adapter state lock. */ ADAPTER_STATE_LOCK(ha); /* Calculate number of free receive buffer entries. */
*** 1317,1327 **** if (index1 == index) { break; } else { index = index1; } ! } while (debounce_count --); if (debounce_count < 0) { /* This should never happen */ EL(ha, "max mb8 debounce retries exceeded\n"); } --- 1434,1444 ---- if (index1 == index) { break; } else { index = index1; } ! } while (debounce_count--); if (debounce_count < 0) { /* This should never happen */ EL(ha, "max mb8 debounce retries exceeded\n"); }
*** 1362,1389 **** container = ha->rcvbuf_ring_ptr; /* * Build container. */ ! ddi_put32(ha->hba_buf.acc_handle, (uint32_t *)(void *)&container->bufp[0], sp->ub_buffer.cookie.dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, (uint32_t *)(void *)&container->bufp[1], sp->ub_buffer.cookie.dmac_notused); ! ddi_put16(ha->hba_buf.acc_handle, &container->handle, LSW(sp->handle)); ha->ub_outcnt++; /* Adjust ring index. */ ha->rcvbuf_ring_index++; if (ha->rcvbuf_ring_index == RCVBUF_CONTAINER_CNT) { ha->rcvbuf_ring_index = 0; ! ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp; } else { ha->rcvbuf_ring_ptr++; } ring_updated = TRUE; --- 1479,1506 ---- container = ha->rcvbuf_ring_ptr; /* * Build container. */ ! ddi_put32(ha->rcv_ring.acc_handle, (uint32_t *)(void *)&container->bufp[0], sp->ub_buffer.cookie.dmac_address); ! ddi_put32(ha->rcv_ring.acc_handle, (uint32_t *)(void *)&container->bufp[1], sp->ub_buffer.cookie.dmac_notused); ! ddi_put16(ha->rcv_ring.acc_handle, &container->handle, LSW(sp->handle)); ha->ub_outcnt++; /* Adjust ring index. */ ha->rcvbuf_ring_index++; if (ha->rcvbuf_ring_index == RCVBUF_CONTAINER_CNT) { ha->rcvbuf_ring_index = 0; ! ha->rcvbuf_ring_ptr = ha->rcv_ring.bp; } else { ha->rcvbuf_ring_ptr++; } ring_updated = TRUE;
*** 1391,1412 **** QL_UB_UNLOCK(ha); } if (ring_updated) { /* Sync queue. */ ! (void) ddi_dma_sync(ha->hba_buf.dma_handle, ! (off_t)RCVBUF_Q_BUFFER_OFFSET, (size_t)RCVBUF_QUEUE_SIZE, ! DDI_DMA_SYNC_FORDEV); /* Set chip new ring index. */ WRT16_IO_REG(ha, mailbox_in[8], ha->rcvbuf_ring_index); } /* Release adapter state lock. */ ADAPTER_STATE_UNLOCK(ha); ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } /* * ql_isp24xx_rcvbuf * Locates free buffers and send it to adapter. --- 1508,1528 ---- QL_UB_UNLOCK(ha); } if (ring_updated) { /* Sync queue. */ ! (void) ddi_dma_sync(ha->rcv_ring.dma_handle, 0, ! (size_t)RCVBUF_QUEUE_SIZE, DDI_DMA_SYNC_FORDEV); /* Set chip new ring index. */ WRT16_IO_REG(ha, mailbox_in[8], ha->rcvbuf_ring_index); } /* Release adapter state lock. */ ADAPTER_STATE_UNLOCK(ha); ! QL_PRINT_3(ha, "done\n"); } /* * ql_isp24xx_rcvbuf * Locates free buffers and send it to adapter.
*** 1424,1435 **** uint16_t index; ql_srb_t *sp; fc_unsol_buf_t *ubp; int rval; ip_buf_pool_entry_t *pkt = NULL; ! QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance); for (;;) { /* Locate a buffer to give. */ QL_UB_LOCK(ha); for (index = 0; index < QL_UB_LIMIT; index++) { --- 1540,1552 ---- uint16_t index; ql_srb_t *sp; fc_unsol_buf_t *ubp; int rval; ip_buf_pool_entry_t *pkt = NULL; + ql_request_q_t *req_q = ha->req_q[0]; ! QL_PRINT_3(ha, "started\n"); for (;;) { /* Locate a buffer to give. */ QL_UB_LOCK(ha); for (index = 0; index < QL_UB_LIMIT; index++) {
*** 1453,1463 **** break; } /* Get IOCB packet for buffers. */ if (pkt == NULL) { ! rval = ql_req_pkt(ha, (request_t **)&pkt); if (rval != QL_SUCCESS) { EL(ha, "failed, ql_req_pkt=%x\n", rval); QL_UB_LOCK(ha); ha->ub_outcnt--; sp->flags &= ~SRB_UB_IN_ISP; --- 1570,1580 ---- break; } /* Get IOCB packet for buffers. */ if (pkt == NULL) { ! rval = ql_req_pkt(ha, req_q, (request_t **)&pkt); if (rval != QL_SUCCESS) { EL(ha, "failed, ql_req_pkt=%x\n", rval); QL_UB_LOCK(ha); ha->ub_outcnt--; sp->flags &= ~SRB_UB_IN_ISP;
*** 1469,1495 **** } /* * Build container. */ ! ddi_put32(ha->hba_buf.acc_handle, &container->bufp[0], sp->ub_buffer.cookie.dmac_address); ! ddi_put32(ha->hba_buf.acc_handle, &container->bufp[1], sp->ub_buffer.cookie.dmac_notused); ! ddi_put16(ha->hba_buf.acc_handle, &container->handle, LSW(sp->handle)); pkt->buffer_count++; container++; if (pkt->buffer_count == IP_POOL_BUFFERS) { ! ql_isp_cmd(ha); pkt = NULL; } } if (pkt != NULL) { ! ql_isp_cmd(ha); } ! QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance); } --- 1586,1612 ---- } /* * Build container. */ ! ddi_put32(req_q->req_ring.acc_handle, &container->bufp[0], sp->ub_buffer.cookie.dmac_address); ! ddi_put32(req_q->req_ring.acc_handle, &container->bufp[1], sp->ub_buffer.cookie.dmac_notused); ! ddi_put16(req_q->req_ring.acc_handle, &container->handle, LSW(sp->handle)); pkt->buffer_count++; container++; if (pkt->buffer_count == IP_POOL_BUFFERS) { ! ql_isp_cmd(ha, req_q); pkt = NULL; } } if (pkt != NULL) { ! ql_isp_cmd(ha, req_q); } ! QL_PRINT_3(ha, "done\n"); }