/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright 2010 QLogic Corporation */
/*
*/
#pragma ident "Copyright 2010 QLogic Corporation; ql_isr.c"
/*
* ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
*
* ***********************************************************************
* * **
* * NOTICE **
* * COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION **
* * ALL RIGHTS RESERVED **
* * **
* ***********************************************************************
*
*/
#include <ql_apps.h>
#include <ql_api.h>
#include <ql_debug.h>
#include <ql_iocb.h>
#include <ql_isr.h>
#include <ql_init.h>
#include <ql_mbx.h>
#include <ql_nx.h>
#include <ql_xioctl.h>
/*
* Local Function Prototypes.
*/
uint32_t *);
static void ql_spurious_intr(ql_adapter_state_t *, int);
uint32_t *, int);
static void ql_fast_fcp_post(ql_srb_t *);
uint32_t *, int);
static void ql_ip_rcv_cont_entry(ql_adapter_state_t *,
static void ql_els_passthru_entry(ql_adapter_state_t *,
/*
* Spurious interrupt counter
*/
/*
* ql_isr
* Process all INTX intr types.
*
* Input:
* arg1: adapter state pointer.
*
* Returns:
* DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
{
return (ql_isr_aif(arg1, 0));
}
/*
* ql_isr_default
* Process unknown/unvectored intr types
*
* Input:
* arg1: adapter state pointer.
* arg2: interrupt vector.
*
* Returns:
* DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
{
}
/*
* ql_isr_aif
* Process mailbox and I/O command completions.
*
* Input:
* arg: adapter state pointer.
* intvec: interrupt vector.
*
* Returns:
* DDI_INTR_CLAIMED or DDI_INTR_UNCLAIMED
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
{
int spurious_intr = 0;
QL_PM_LOCK(ha);
/*
* Looks like we are about to go down soon, exit early.
*/
return (DDI_INTR_UNCLAIMED);
}
/* Acquire interrupt lock. */
/* Reset idle timer. */
ha->idle_timer = 0;
if (intr_loop) {
intr_loop--;
}
/* Special Fast Post 2200. */
stat = 0;
/* Release mailbox registers. */
if (intr_loop) {
}
/* Get handle. */
mbx >>= 4;
/* Validate handle. */
== mbx) {
NULL;
/* Set completed status. */
/* Set completion status */
} else if (mbx !=
(QL_FCA_BRAND & 0xfff)) {
" handle=%xh\n",
mbx);
} else {
" handle pkt=%xh, "
"sp=%xh\n", mbx,
}
(void) ql_binary_fw_dump(ha,
FALSE);
if (!(ha->task_daemon_flags &
ABORT_ISP_ACTIVE))) {
"handle, "
"isp_abort_needed"
"\n");
set_flags |=
}
}
}
}
if (stat == 0) {
/* Check for mailbox interrupt. */
/* Release mailbox registers. */
/* Get mailbox data. */
&set_flags, &reset_flags,
} else if (mbx > 0x7fff &&
mbx < 0xc000) {
&isr_done_q, &set_flags,
&reset_flags, intr_loop);
} else {
"type\n");
}
} else {
resp_in);
if (ha->isp_rsp_index !=
ha->rsp_ring_index) {
&isr_done_q, &set_flags,
&reset_flags, intr_loop);
} else if (++spurious_intr ==
/*
* Process excessive
* spurious intrrupts
*/
"interrupts, "
"isp_abort_needed\n");
} else {
}
}
}
/* Clear RISC interrupt */
}
if (set_flags != 0 || reset_flags != 0) {
set_flags = 0;
reset_flags = 0;
}
}
} else {
intr_loop = 1;
}
(++ql_max_intr_loop_cnt < ql_max_intr_loop)) {
/* Capture FW defined interrupt info */
/* Reset idle timer. */
ha->idle_timer = 0;
intr_loop == 0)) {
break;
}
if (intr_loop) {
intr_loop--;
}
switch (stat & 0x1ff) {
case ROM_MBX_SUCCESS:
case ROM_MBX_ERR:
&reset_flags, intr_loop);
/* Release mailbox registers. */
}
break;
case MBX_SUCCESS:
case MBX_ERR:
/* Sun FW, Release mailbox registers. */
}
&reset_flags, intr_loop);
break;
case ASYNC_EVENT:
/* Sun FW, Release mailbox registers. */
}
break;
case RESP_UPDATE:
&set_flags, &reset_flags,
} else if (++spurious_intr ==
/* Process excessive spurious intr. */
"interrupts, isp_abort_needed\n");
} else {
"ring index same as before\n",
}
break;
case SCSI_FAST_POST_16:
break;
case SCSI_FAST_POST_32:
break;
case CTIO_FAST_POST:
break;
case IP_FAST_POST_XMT:
break;
case IP_FAST_POST_RCV:
break;
case IP_FAST_POST_BRD:
break;
case IP_FAST_POST_RCV_ALN:
break;
case ATIO_UPDATE:
" interrupt, status=%xh\n", stat);
break;
case ATIO_RESP_UPDATE:
"update interrupt, status=%xh\n", stat);
break;
default:
&set_flags);
break;
}
/* Clear RISC interrupt */
} else {
}
}
if (set_flags != 0 || reset_flags != 0) {
set_flags = 0;
reset_flags = 0;
}
break;
}
if (clear_spurious) {
spurious_intr = 0;
}
}
}
/* Process claimed interrupts during polls. */
}
/* Release interrupt lock. */
if (daemon) {
}
}
if (rval == DDI_INTR_CLAIMED) {
} else {
/*EMPTY*/
}
QL_PM_LOCK(ha);
return (rval);
}
/*
* ql_handle_uncommon_risc_intr
* Handle an uncommon RISC interrupt.
*
* Input:
* ha: adapter state pointer.
* stat: interrupt status
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
if (stat & RH_RISC_PAUSED ||
if (ha->parity_pause_errors == 0 ||
"Pause Error - hccr=%xh, stat=%xh, count=%d",
}
}
if (ha->parity_pause_errors == 0) {
}
}
/* Disable ISP interrupts. */
} else {
}
}
/*
* ql_spurious_intr
* Inform Solaris of spurious interrupts.
*
* Input:
* ha: adapter state pointer.
* intr_clr: early interrupt clear
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
/* Disable ISP interrupts. */
/* Clear RISC interrupt */
if (intr_clr) {
} else {
}
}
if (state == DDI_DEVSTATE_UP) {
/*EMPTY*/
DDI_DEVICE_FAULT, "spurious interrupts");
}
}
/*
* ql_mbx_completion
* Processes mailbox completions.
*
* Input:
* ha: adapter state pointer.
* mb0: Mailbox 0 contents.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
* intr_clr: early interrupt clear
*
* Context:
* Interrupt context.
*/
/* ARGSUSED */
static void
{
/* Load return mailbox registers. */
index >>= 1;
mailbox_out[cnt]);
}
}
} else {
}
if (intr_clr) {
/* Clear RISC interrupt. */
} else {
}
}
}
}
/*
* ql_async_event
* Processes asynchronous events.
*
* Input:
* ha: adapter state pointer.
* mbx: Mailbox 0 register.
* done_q: head pointer to done queue.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
* intr_clr: early interrupt clear
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
/* Setup to process fast completion. */
switch (mb[0]) {
case MBA_SCSI_COMPLETION:
break;
case MBA_CMPLT_1_16BIT:
mb[0] = MBA_SCSI_COMPLETION;
break;
case MBA_CMPLT_1_32BIT:
mb[0] = MBA_SCSI_COMPLETION;
break;
case MBA_CTIO_COMPLETION:
case MBA_IP_COMPLETION:
mb[0] = MBA_SCSI_COMPLETION;
break;
default:
break;
}
/* Handle asynchronous event */
switch (mb[0]) {
case MBA_SCSI_COMPLETION:
if (intr_clr) {
/* Clear RISC interrupt */
} else {
}
}
break;
}
/* Get handle. */
/* Validate handle. */
/* Set completed status. */
/* Set completion status */
/* Place block on done queue */
} else {
}
} else if (handle != QL_FCA_BRAND) {
} else {
}
"mbx6=%xh, mbx7=%xh\n", mb[0],
if (!(ha->task_daemon_flags &
(ISP_ABORT_NEEDED | ABORT_ISP_ACTIVE))) {
"isp_abort_needed\n", mb[0]);
}
}
break;
case MBA_RESET: /* Reset */
break;
case MBA_SYSTEM_ERR: /* System Error */
"mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh, mbx6=%xh,\n "
"mbx7=%xh, mbx8=%xh, mbx9=%xh, mbx10=%xh, mbx11=%xh, "
"mbx14=%xh, mbx15=%xh, mbx16=%xh, mbx17=%xh, mbx18=%xh,\n"
"mbx19=%xh, mbx20=%xh, mbx21=%xh, mbx22=%xh, mbx23=%xh\n",
"mbx26=%xh,\n mbx27=%xh, mbx28=%xh, mbx29=%xh, "
"mbx30=%xh, mbx31=%xh\n", mb[0],
}
}
break;
case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
"isp_abort_needed\n", mb[0]);
break;
case MBA_RSP_TRANSFER_ERR: /* Response Xfer Err */
" isp_abort_needed\n", mb[0]);
break;
case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
mb[0]);
break;
case MBA_MENLO_ALERT: /* Menlo Alert Notification */
switch (mb[1]) {
case MLA_LOGIN_OPERATIONAL_FW:
break;
case MLA_PANIC_RECOVERY:
case MLA_LOGIN_DIAGNOSTIC_FW:
case MLA_LOGIN_GOLDEN_FW:
case MLA_REJECT_RESPONSE:
default:
break;
}
break;
case MBA_LIP_F8: /* Received a LIP F8. */
case MBA_LIP_RESET: /* LIP reset occurred. */
case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
} else {
}
}
}
/* Update AEN queue. */
}
break;
case MBA_LOOP_UP:
CFG_CTRL_24258081))) {
index = 1;
index = 2;
index = 4;
index = 8;
index = 10;
} else {
index = 0;
}
} else {
index = 1;
}
}
/* Update AEN queue. */
}
break;
case MBA_LOOP_DOWN:
}
}
}
/* Update AEN queue. */
}
break;
case MBA_PORT_UPDATE:
/* Locate port state structure. */
break;
}
}
break;
}
/*
* received FLOGI reject
* received FLOGO
* FCF configuration changed
* FIP Clear Virtual Link received
* FKA timeout
*/
}
}
/*
* In N port 2 N port topology the FW provides a port
* database entry at loop_id 0x7fe which we use to
* acquire the Ports WWPN.
*/
"received, mbx1=%xh, mbx2=%xh, mbx3=%xh\n",
} else {
mb[3]);
*reset_flags |= LOOP_DOWN;
}
/* Update AEN queue. */
}
break;
case MBA_RSCN_UPDATE:
/* Locate port state structure. */
break;
}
}
break;
}
} else {
}
}
/* Update AEN queue. */
}
break;
case MBA_LIP_ERROR: /* Loop initialization errors. */
break;
case MBA_IP_RECEIVE:
case MBA_IP_BROADCAST:
/* Locate device queue. */
break;
}
tq->ub_total_seg_cnt++;
}
index++) {
}
tq->ub_seq_cnt = 0;
tq->ub_frame_ro = 0;
QL_SUCCESS) {
"isp_abort_needed\n");
break;
}
}
break;
case MBA_IP_LOW_WATER_MARK:
case MBA_IP_RCV_BUFFER_EMPTY:
mb[0]);
break;
case MBA_IP_HDR_DATA_SPLIT:
break;
break;
case MBA_POINT_TO_POINT:
/* case MBA_DCBX_COMPLETED: */
} else {
}
break;
case MBA_FCF_CONFIG_ERROR:
break;
case MBA_DCBX_PARAM_CHANGED:
break;
case MBA_CHG_IN_CONNECTION:
~QL_N_PORT);
}
} else {
}
break;
case MBA_ZIO_UPDATE:
break;
case MBA_PORT_BYPASS_CHANGED:
/*
* Event generated when there is a transition on
* port bypass of crystal+.
* Mailbox 1: Bit 0 - External.
* Bit 2 - Internal.
* When the bit is 0, the port is bypassed.
*
* For now we will generate a LIP for all cases.
*/
break;
case MBA_RECEIVE_ERROR:
break;
case MBA_LS_RJT_SENT:
break;
case MBA_FW_RESTART_COMP:
break;
/*
* MBA_IDC_COMPLETE & MBA_IDC_NOTIFICATION: We won't get another
* IDC async event until we ACK the current one.
*/
case MBA_IDC_COMPLETE:
" mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, mbx5=%xh,"
break;
case MBA_IDC_NOTIFICATION:
"received, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh, "
break;
case MBA_IDC_TIME_EXTENDED:
" mbx1=%xh, mbx2=%xh\n", mb[0],
break;
default:
break;
}
/* Clear RISC interrupt */
} else {
}
}
}
/*
* ql_fast_fcp_post
* Fast path for good SCSI I/O completion.
*
* Input:
* sp: SRB pointer.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
/* Acquire device queue lock. */
/* Decrement outstanding commands on device. */
}
/*
* Clear the flag for this LUN so that
* untagged commands can be submitted
* for it.
*/
}
if (lq->lun_outcnt != 0) {
lq->lun_outcnt--;
}
}
/* Reset port down retry count on good completion. */
/* Remove command from watchdog queue. */
}
} else {
/* Release LU queue specific lock. */
}
}
/* Sync buffers if required. */
}
/* Map ISP completion codes. */
/* Now call the pkt completion callback */
}
}
/*
* ql_response_pkt
* Processes response entry.
*
* Input:
* ha: adapter state pointer.
* done_q: head pointer to done queue.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
* intr_clr: early interrupt clear
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
int status = 0;
/* Clear RISC interrupt */
if (intr_clr) {
} else {
}
}
ha->isp_rsp_index);
return;
}
return;
}
/* Calculate size of response queue entries to sync. */
} else if (ha->isp_rsp_index == 0) {
} else {
/* Responses wrap around the Q */
}
/* Sync DMA buffer. */
if (dma_sync_size_2) {
}
/* Adjust ring index. */
ha->rsp_ring_index++;
ha->rsp_ring_index = 0;
} else {
ha->response_ring_ptr++;
}
/* Process packet. */
}
if (pkt->entry_status != 0) {
} else {
switch (pkt->entry_type) {
case STATUS_TYPE:
reset_flags) :
break;
case STATUS_CONT_TYPE:
break;
case IP_TYPE:
case IP_A64_TYPE:
case IP_CMD_TYPE:
break;
case IP_RECEIVE_TYPE:
break;
case IP_RECEIVE_CONT_TYPE:
break;
case IP_24XX_RECEIVE_TYPE:
break;
case MS_TYPE:
break;
case REPORT_ID_TYPE:
break;
case ELS_PASSTHRU_TYPE:
break;
case IP_BUF_POOL_TYPE:
case MARKER_TYPE:
case VP_MODIFY_TYPE:
case VP_CONTROL_TYPE:
break;
default:
pkt->entry_type);
break;
}
}
}
/* Inform RISC of processed responses. */
/* RESET packet received delay for possible async event. */
drv_usecwait(500000);
}
}
/*
* ql_error_entry
* Processes error entry.
*
* Input:
* ha = adapter state pointer.
* pkt = entry pointer.
* done_q = head pointer to done queue.
* set_flags = task daemon flags to set.
* reset_flags = task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
return;
}
} else {
}
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
/* Bad payload or header */
/* Bad payload or header, set error status. */
} else {
/* Set error status. */
}
/* Set completed status. */
/* Place command on done queue. */
}
}
/*
* ql_status_entry
* Processes received ISP2200-2300 status entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Returns:
* BIT_0 = CS_RESET status received.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static int
{
int rval = 0;
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
&pkt->comp_status);
/*
* We dont care about SCSI QFULLs.
*/
if (comp_status == CS_QUEUE_FULL) {
}
/*
* 2300 firmware marks completion status as data underrun
* for scsi qfulls. Make it transport complete.
*/
(comp_status == CS_DATA_UNDERRUN) &&
(pkt->scsi_status_l != 0)) {
}
/*
* Workaround T3 issue where we do not get any data xferred
* but get back a good status.
*/
comp_status == CS_COMPLETE &&
pkt->scsi_status_l == 0 &&
pkt->residual_length == 0 &&
SF_DATA_OUT) {
}
/*
* Ideally it should never be true. But there
* is a bug in FW which upon receiving invalid
* parameters in MS IOCB returns it as
* status entry and not as ms entry type.
*/
return (0);
}
/*
* Fast path to good SCSI I/O completion
*/
if ((comp_status == CS_COMPLETE) &
(!pkt->scsi_status_l) &
/* Set completed status. */
return (0);
}
}
return (rval);
}
/*
* ql_24xx_status_entry
* Processes received ISP24xx status entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Returns:
* BIT_0 = CS_RESET status received.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static int
{
int rval = 0;
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
&pkt->comp_status);
/* We dont care about SCSI QFULLs. */
if (comp_status == CS_QUEUE_FULL) {
}
/*
* 2300 firmware marks completion status as data underrun
* for scsi qfulls. Make it transport complete.
*/
if ((comp_status == CS_DATA_UNDERRUN) &&
(pkt->scsi_status_l != 0)) {
}
/*
* Workaround T3 issue where we do not get any data xferred
* but get back a good status.
*/
if (comp_status == CS_COMPLETE &&
pkt->scsi_status_l == 0 &&
pkt->residual_length != 0 &&
}
/*
* Fast path to good SCSI I/O completion
*/
if ((comp_status == CS_COMPLETE) &
(!pkt->scsi_status_l) &
/* Set completed status. */
return (0);
}
}
return (rval);
}
/*
* ql_verify_preprocessed_cmd
* Handles preprocessed cmds..
*
* Input:
* ha: adapter state pointer.
* pkt_handle: handle pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Returns:
* srb pointer or NULL
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
ql_srb_t *
{
while (get_handle) {
/* Get handle. */
/* Validate handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
}
break;
} else {
get_handle -= 1;
drv_usecwait(10000);
if (get_handle == 1) {
/* Last chance, Sync whole DMA buffer. */
index);
}
}
}
return (sp);
}
/*
* ql_status_error
* Processes received ISP status entry error.
*
* Input:
* ha: adapter state pointer.
* sp: SRB pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Returns:
* BIT_0 = CS_RESET status received.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static int
{
int rval = 0;
struct {
} sts;
/* Setup status. */
&pkt24->comp_status);
/* Setup firmware residuals. */
/* Setup FCP residuals. */
}
/* Setup state flags. */
} else {
}
}
}
/* Setup FCP response info. */
if (sts.rsp_info_length >
sizeof (struct fcp_rsp_info)) {
sizeof (struct fcp_rsp_info);
}
}
} else {
sts.rsp_info_length = 0;
}
/* Setup sense data. */
}
} else {
sts.req_sense_length = 0;
}
} else {
/* Setup status. */
/* Setup firmware residuals. */
/* Setup FCP residuals. */
sts.residual_length : 0;
/* Setup state flags. */
/* Setup FCP response info. */
if (sts.rsp_info_length >
sizeof (struct fcp_rsp_info)) {
sizeof (struct fcp_rsp_info);
}
} else {
sts.rsp_info_length = 0;
}
/* Setup sense data. */
}
sizeof (fcp_rsp_t));
}
}
}
}
/* Set ISP completion status */
/* Update statistics. */
}
/* copy response information data. */
if (sense_sz) {
}
case FCP_NO_FAILURE:
break;
case FCP_DL_LEN_MISMATCH:
break;
case FCP_CMND_INVALID:
break;
case FCP_DATA_RO_MISMATCH:
break;
case FCP_TASK_MGMT_NOT_SUPPTD:
break;
case FCP_TASK_MGMT_FAILED:
break;
default:
break;
}
} else {
/*
* EL(sp->ha, "scsi_h=%xh, pkt_rsplen=%xh\n",
* sts.scsi_status_h, sp->pkt->pkt_rsplen);
*/
fcpr->fcp_response_len = 0;
}
/* Set reset status received. */
}
/* Set retry status. */
tq->port_down_retry_count != 0 &&
/* Set retry status. */
/* Acquire device queue lock. */
/* Decrement port down count. */
}
== 0 &&
}
if (ha->port_retry_timer == 0) {
if ((ha->port_retry_timer =
ha->port_down_retry_delay) == 0) {
*set_flags |=
}
}
}
tq->qfull_retry_count--;
if (ha->port_retry_timer == 0) {
if ((ha->port_retry_timer =
ha->qfull_retry_delay) ==
0) {
*set_flags |=
}
}
}
} else {
}
/* Set retry status. */
} else {
} else {
"underrun & invalid resid\n");
}
}
/* Ignore firmware underrun error. */
}
}
/* Set target request sense data. */
}
/* Insure data does not exceed buf. */
fcpr->fcp_response_len) {
sp->request_sense_length = 0;
} else {
sizeof (fcp_rsp_t) -
}
if (sense_sz <
}
sizeof (sts_entry_t)) -
if (sp->request_sense_length <
sense_sz) {
sense_sz =
}
/* Move sense data. */
if (sp->request_sense_length != 0 &&
}
}
if (sense_sz != 0) {
"d_id=%xh, lun=%xh\n%2xh%3xh%3xh%3xh"
"%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh%3xh"
sts.req_sense_data[0],
} else {
}
}
}
/* Set completed status. */
/* Place command on done queue. */
}
return (rval);
}
/*
* ql_status_cont_entry
* Processes status continuation entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
} else {
}
ql_chg_endian((uint8_t *)
}
}
/* Move sense data. */
/* Place command on done queue. */
if (sp->request_sense_length == 0) {
}
}
}
/*
* ql_ip_entry
* Processes received ISP IP entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
/* Set ISP completion status */
} else {
}
/* Set retry status. */
} else if (tq->port_down_retry_count &&
/* Set retry status. */
}
/* Acquire device queue lock. */
if (ha->port_retry_timer == 0) {
if ((ha->port_retry_timer =
ha->port_down_retry_delay) == 0) {
*set_flags |=
}
}
}
/* Release device queue specific lock. */
/* Set retry status. */
} else {
}
}
/* Set completed status. */
}
}
/*
* ql_ip_rcv_entry
* Processes received ISP IP buffers entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Locate device queue. */
return;
}
&pkt->seq_length);
tq->ub_seq_cnt = 0;
tq->ub_frame_ro = 0;
break;
}
}
}
/*
* ql_ip_rcv_cont_entry
* Processes received ISP IP buffers continuation entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
return;
}
break;
}
}
}
/*
* ip_rcv_24xx_entry_t
* Processes received ISP24xx IP buffers entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Locate device queue. */
return;
}
if (tq->ub_total_seg_cnt == 0) {
tq->ub_seq_cnt = 0;
tq->ub_frame_ro = 0;
}
break;
}
}
}
/*
* ql_ms_entry
* Processes received Name/Management/CT Pass-Through entry.
*
* Input:
* ha: adapter state pointer.
* pkt23: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
return;
}
/* Set ISP completion status */
} else {
}
sp->retry_count) {
sp->retry_count);
/* Set retry status. */
sp->retry_count--;
/* Acquire device queue lock. */
if (ha->port_retry_timer == 0) {
}
}
/* Release device queue specific lock. */
} else if (tq->port_down_retry_count &&
/* Set retry status. */
/* Acquire device queue lock. */
if (ha->port_retry_timer == 0) {
if ((ha->port_retry_timer =
ha->port_down_retry_delay) == 0) {
*set_flags |=
}
}
}
/* Release device queue specific lock. */
/* Set retry status. */
&pkt24->resp_byte_count);
if (cnt < sizeof (fc_ct_header_t)) {
} else {
}
}
/*EMPTY*/
}
/* For nameserver restore command, management change header. */
}
/* Set completed status. */
/* Place command on done queue. */
}
}
/*
* ql_report_id_entry
* Processes received Name/Management/CT Pass-Through entry.
*
* Input:
* ha: adapter state pointer.
* pkt: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Locate port state structure. */
break;
}
}
}
}
}
/*
* ql_els_entry
* Processes received ELS Pass-Through entry.
*
* Input:
* ha: adapter state pointer.
* pkt23: entry pointer.
* done_q: done queue pointer.
* set_flags: task daemon flags to set.
* reset_flags: task daemon flags to reset.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
/* ARGSUSED */
static void
{
/* Validate the response entry handle. */
if (index < MAX_OUTSTANDING_COMMANDS) {
/* the index seems reasonable */
/* Neo, you're the one... */
} else {
}
} else {
}
} else {
}
return;
}
/* Set ISP completion status */
}
/* Build RJT in the response. */
sizeof (rjt), DDI_DEV_AUTOINCR);
}
/* Indicate ISP completion */
&rsp->n_port_hdl);
/* create a target Q if there isn't one */
/* Acquire adapter state lock. */
}
/* on plogi success assume the chosen s_id */
&rsp->els_cmd_opcode);
if (opcode == LA_ELS_PLOGI) {
}
}
}
tq->logout_sent = 0;
}
}
}
/* invoke the callback */
}
}
/*
* ql_signal_abort
* Signal to the task daemon that a condition warranting an
* isp reset has been detected.
*
* Input:
* ha: adapter state pointer.
* set_flags: task daemon flags to set.
*
* Context:
* Interrupt or Kernel context, no mailbox commands allowed.
*/
static void
{
}
}