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");
}