1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
88f23e9faSHans Rosenfeld * You can obtain a copy of the license at
98f23e9faSHans Rosenfeld * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte
22fcf3ce44SJohn Forte /*
238f23e9faSHans Rosenfeld * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan * Use is subject to license terms.
25*a3170057SPaul Winder * Copyright 2020 RackTop Systems, Inc.
26fcf3ce44SJohn Forte */
27fcf3ce44SJohn Forte
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte
30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_FCP_C);
32fcf3ce44SJohn Forte
33fcf3ce44SJohn Forte #define EMLXS_GET_VADDR(hba, rp, icmd) emlxs_mem_get_vaddr(hba, rp, \
3482527734SSukumar Swaminathan PADDR(icmd->un.cont64[i].addrHigh, icmd->un.cont64[i].addrLow));
35fcf3ce44SJohn Forte
36291a2b48SSukumar Swaminathan static void emlxs_sbp_abort_add(emlxs_port_t *port, emlxs_buf_t *sbp,
37291a2b48SSukumar Swaminathan Q *abort, uint8_t *flag, emlxs_buf_t *fpkt);
38fcf3ce44SJohn Forte
39fcf3ce44SJohn Forte #define SCSI3_PERSISTENT_RESERVE_IN 0x5e
40291a2b48SSukumar Swaminathan #define SCSI_INQUIRY 0x12
41291a2b48SSukumar Swaminathan #define SCSI_RX_DIAG 0x1C
42fcf3ce44SJohn Forte
43fcf3ce44SJohn Forte
44fcf3ce44SJohn Forte /*
45fcf3ce44SJohn Forte * emlxs_handle_fcp_event
46fcf3ce44SJohn Forte *
47fcf3ce44SJohn Forte * Description: Process an FCP Rsp Ring completion
48fcf3ce44SJohn Forte *
49fcf3ce44SJohn Forte */
50fcf3ce44SJohn Forte /* ARGSUSED */
51fcf3ce44SJohn Forte extern void
emlxs_handle_fcp_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)5282527734SSukumar Swaminathan emlxs_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
53fcf3ce44SJohn Forte {
54fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
5582527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG;
56fcf3ce44SJohn Forte IOCB *cmd;
57fcf3ce44SJohn Forte emlxs_buf_t *sbp;
58fcf3ce44SJohn Forte fc_packet_t *pkt = NULL;
59291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
60291a2b48SSukumar Swaminathan NODELIST *ndlp;
61291a2b48SSukumar Swaminathan #endif
62fcf3ce44SJohn Forte uint32_t iostat;
63fcf3ce44SJohn Forte uint8_t localstat;
64fcf3ce44SJohn Forte fcp_rsp_t *rsp;
65fcf3ce44SJohn Forte uint32_t rsp_data_resid;
66fcf3ce44SJohn Forte uint32_t check_underrun;
67fcf3ce44SJohn Forte uint8_t asc;
68fcf3ce44SJohn Forte uint8_t ascq;
69fcf3ce44SJohn Forte uint8_t scsi_status;
70fcf3ce44SJohn Forte uint8_t sense;
71fcf3ce44SJohn Forte uint32_t did;
72fcf3ce44SJohn Forte uint32_t fix_it;
73fcf3ce44SJohn Forte uint8_t *scsi_cmd;
74fcf3ce44SJohn Forte uint8_t scsi_opcode;
75fcf3ce44SJohn Forte uint16_t scsi_dl;
76fcf3ce44SJohn Forte uint32_t data_rx;
778f23e9faSHans Rosenfeld uint32_t length;
78fcf3ce44SJohn Forte
79fcf3ce44SJohn Forte cmd = &iocbq->iocb;
80fcf3ce44SJohn Forte
81fcf3ce44SJohn Forte /* Initialize the status */
8282527734SSukumar Swaminathan iostat = cmd->ULPSTATUS;
83fcf3ce44SJohn Forte localstat = 0;
84fcf3ce44SJohn Forte scsi_status = 0;
85fcf3ce44SJohn Forte asc = 0;
86fcf3ce44SJohn Forte ascq = 0;
87fcf3ce44SJohn Forte sense = 0;
88fcf3ce44SJohn Forte check_underrun = 0;
89fcf3ce44SJohn Forte fix_it = 0;
90fcf3ce44SJohn Forte
91fcf3ce44SJohn Forte HBASTATS.FcpEvent++;
92fcf3ce44SJohn Forte
93fcf3ce44SJohn Forte sbp = (emlxs_buf_t *)iocbq->sbp;
94fcf3ce44SJohn Forte
95fcf3ce44SJohn Forte if (!sbp) {
96fcf3ce44SJohn Forte /* completion with missing xmit command */
97fcf3ce44SJohn Forte HBASTATS.FcpStray++;
98fcf3ce44SJohn Forte
99fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_fcp_completion_msg,
1008f23e9faSHans Rosenfeld "cmd=%x iotag=%d", cmd->ULPCOMMAND, cmd->ULPIOTAG);
101fcf3ce44SJohn Forte
102fcf3ce44SJohn Forte return;
103fcf3ce44SJohn Forte }
104291a2b48SSukumar Swaminathan
105fcf3ce44SJohn Forte HBASTATS.FcpCompleted++;
106fcf3ce44SJohn Forte
107291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
108291a2b48SSukumar Swaminathan emlxs_update_sd_bucket(sbp);
109291a2b48SSukumar Swaminathan #endif /* SAN_DIAG_SUPPORT */
110291a2b48SSukumar Swaminathan
111fcf3ce44SJohn Forte pkt = PRIV2PKT(sbp);
112fcf3ce44SJohn Forte
11382527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
114fcf3ce44SJohn Forte scsi_cmd = (uint8_t *)pkt->pkt_cmd;
115fcf3ce44SJohn Forte scsi_opcode = scsi_cmd[12];
116fcf3ce44SJohn Forte data_rx = 0;
117fcf3ce44SJohn Forte
118fcf3ce44SJohn Forte /* Sync data in data buffer only on FC_PKT_FCP_READ */
119fcf3ce44SJohn Forte if (pkt->pkt_datalen && (pkt->pkt_tran_type == FC_PKT_FCP_READ)) {
12082527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(pkt->pkt_data_dma, 0, pkt->pkt_datalen,
121fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
122fcf3ce44SJohn Forte
123fcf3ce44SJohn Forte #ifdef TEST_SUPPORT
124fcf3ce44SJohn Forte if (hba->underrun_counter && (iostat == IOSTAT_SUCCESS) &&
125fcf3ce44SJohn Forte (pkt->pkt_datalen >= 512)) {
126fcf3ce44SJohn Forte hba->underrun_counter--;
127fcf3ce44SJohn Forte iostat = IOSTAT_FCP_RSP_ERROR;
128fcf3ce44SJohn Forte
129fcf3ce44SJohn Forte /* Report 512 bytes missing by adapter */
130fcf3ce44SJohn Forte cmd->un.fcpi.fcpi_parm = pkt->pkt_datalen - 512;
131fcf3ce44SJohn Forte
132fcf3ce44SJohn Forte /* Corrupt 512 bytes of Data buffer */
133fcf3ce44SJohn Forte bzero((uint8_t *)pkt->pkt_data, 512);
134fcf3ce44SJohn Forte
135fcf3ce44SJohn Forte /* Set FCP response to STATUS_GOOD */
136fcf3ce44SJohn Forte bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen);
137fcf3ce44SJohn Forte }
138291a2b48SSukumar Swaminathan #endif /* TEST_SUPPORT */
139fcf3ce44SJohn Forte }
140291a2b48SSukumar Swaminathan
141fcf3ce44SJohn Forte /* Process the pkt */
142fcf3ce44SJohn Forte mutex_enter(&sbp->mtx);
143fcf3ce44SJohn Forte
144fcf3ce44SJohn Forte /* Check for immediate return */
145fcf3ce44SJohn Forte if ((iostat == IOSTAT_SUCCESS) &&
146fcf3ce44SJohn Forte (pkt->pkt_comp) &&
147291a2b48SSukumar Swaminathan !(sbp->pkt_flags &
14882527734SSukumar Swaminathan (PACKET_ULP_OWNED | PACKET_COMPLETED |
149fcf3ce44SJohn Forte PACKET_IN_COMPLETION | PACKET_IN_TXQ | PACKET_IN_CHIPQ |
150fcf3ce44SJohn Forte PACKET_IN_DONEQ | PACKET_IN_TIMEOUT | PACKET_IN_FLUSH |
151fcf3ce44SJohn Forte PACKET_IN_ABORT | PACKET_POLLED))) {
152fcf3ce44SJohn Forte HBASTATS.FcpGood++;
153fcf3ce44SJohn Forte
154291a2b48SSukumar Swaminathan sbp->pkt_flags |=
155291a2b48SSukumar Swaminathan (PACKET_STATE_VALID | PACKET_IN_COMPLETION |
15682527734SSukumar Swaminathan PACKET_COMPLETED | PACKET_ULP_OWNED);
157fcf3ce44SJohn Forte mutex_exit(&sbp->mtx);
158fcf3ce44SJohn Forte
159fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
160fcf3ce44SJohn Forte emlxs_unswap_pkt(sbp);
161291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
162b3660a96SSukumar Swaminathan
163b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT
164b3660a96SSukumar Swaminathan emlxs_check_dma(hba, sbp);
165b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */
166b3660a96SSukumar Swaminathan
16782527734SSukumar Swaminathan cp->ulpCmplCmd++;
168fcf3ce44SJohn Forte (*pkt->pkt_comp) (pkt);
169fcf3ce44SJohn Forte
170b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT
171b3660a96SSukumar Swaminathan if (hba->flag & FC_DMA_CHECK_ERROR) {
172b3660a96SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_restart_thread,
173b3660a96SSukumar Swaminathan NULL, NULL);
174b3660a96SSukumar Swaminathan }
175b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */
176b3660a96SSukumar Swaminathan
177fcf3ce44SJohn Forte return;
178fcf3ce44SJohn Forte }
179291a2b48SSukumar Swaminathan
180fcf3ce44SJohn Forte /*
181291a2b48SSukumar Swaminathan * A response is only placed in the resp buffer if IOSTAT_FCP_RSP_ERROR
182291a2b48SSukumar Swaminathan * is reported.
183fcf3ce44SJohn Forte */
184fcf3ce44SJohn Forte
1858f23e9faSHans Rosenfeld /* Check if a response buffer was not provided */
1868f23e9faSHans Rosenfeld if ((iostat != IOSTAT_FCP_RSP_ERROR) || (pkt->pkt_rsplen == 0)) {
1878f23e9faSHans Rosenfeld goto done;
1888f23e9faSHans Rosenfeld }
1898f23e9faSHans Rosenfeld
1908f23e9faSHans Rosenfeld EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
1918f23e9faSHans Rosenfeld DDI_DMA_SYNC_FORKERNEL);
1928f23e9faSHans Rosenfeld
1938f23e9faSHans Rosenfeld /* Get the response buffer pointer */
1948f23e9faSHans Rosenfeld rsp = (fcp_rsp_t *)pkt->pkt_resp;
1958f23e9faSHans Rosenfeld
1968f23e9faSHans Rosenfeld /* Validate the response payload */
1978f23e9faSHans Rosenfeld if (!rsp->fcp_u.fcp_status.resid_under &&
1988f23e9faSHans Rosenfeld !rsp->fcp_u.fcp_status.resid_over) {
1998f23e9faSHans Rosenfeld rsp->fcp_resid = 0;
2008f23e9faSHans Rosenfeld }
2018f23e9faSHans Rosenfeld
2028f23e9faSHans Rosenfeld if (!rsp->fcp_u.fcp_status.rsp_len_set) {
2038f23e9faSHans Rosenfeld rsp->fcp_response_len = 0;
2048f23e9faSHans Rosenfeld }
205fcf3ce44SJohn Forte
2068f23e9faSHans Rosenfeld if (!rsp->fcp_u.fcp_status.sense_len_set) {
2078f23e9faSHans Rosenfeld rsp->fcp_sense_len = 0;
2088f23e9faSHans Rosenfeld }
2098f23e9faSHans Rosenfeld
2108f23e9faSHans Rosenfeld length = sizeof (fcp_rsp_t) + LE_SWAP32(rsp->fcp_response_len) +
2118f23e9faSHans Rosenfeld LE_SWAP32(rsp->fcp_sense_len);
2128f23e9faSHans Rosenfeld
2138f23e9faSHans Rosenfeld if (length > pkt->pkt_rsplen) {
2148f23e9faSHans Rosenfeld iostat = IOSTAT_RSP_INVALID;
2158f23e9faSHans Rosenfeld pkt->pkt_data_resid = pkt->pkt_datalen;
2168f23e9faSHans Rosenfeld goto done;
2178f23e9faSHans Rosenfeld }
218fcf3ce44SJohn Forte
2198f23e9faSHans Rosenfeld /* Set the valid response flag */
2208f23e9faSHans Rosenfeld sbp->pkt_flags |= PACKET_FCP_RSP_VALID;
221fcf3ce44SJohn Forte
2228f23e9faSHans Rosenfeld scsi_status = rsp->fcp_u.fcp_status.scsi_status;
223fcf3ce44SJohn Forte
224291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
2258f23e9faSHans Rosenfeld ndlp = (NODELIST *)iocbq->node;
2268f23e9faSHans Rosenfeld if (scsi_status == SCSI_STAT_QUE_FULL) {
2278f23e9faSHans Rosenfeld emlxs_log_sd_scsi_event(port, SD_SCSI_SUBCATEGORY_QFULL,
2288f23e9faSHans Rosenfeld (HBA_WWN *)&ndlp->nlp_portname, sbp->lun);
2298f23e9faSHans Rosenfeld } else if (scsi_status == SCSI_STAT_BUSY) {
2308f23e9faSHans Rosenfeld emlxs_log_sd_scsi_event(port,
2318f23e9faSHans Rosenfeld SD_SCSI_SUBCATEGORY_DEVBSY,
2328f23e9faSHans Rosenfeld (HBA_WWN *)&ndlp->nlp_portname, sbp->lun);
2338f23e9faSHans Rosenfeld }
234291a2b48SSukumar Swaminathan #endif
235291a2b48SSukumar Swaminathan
2368f23e9faSHans Rosenfeld /*
2378f23e9faSHans Rosenfeld * Convert a task abort to a check condition with no data
2388f23e9faSHans Rosenfeld * transferred. We saw a data corruption when Solaris received
2398f23e9faSHans Rosenfeld * a Task Abort from a tape.
2408f23e9faSHans Rosenfeld */
241a9800bebSGarrett D'Amore
2428f23e9faSHans Rosenfeld if (scsi_status == SCSI_STAT_TASK_ABORT) {
2438f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT,
2448f23e9faSHans Rosenfeld &emlxs_fcp_completion_error_msg,
2458f23e9faSHans Rosenfeld "Task Abort. "
2468f23e9faSHans Rosenfeld "Fixed. did=0x%06x sbp=%p cmd=%02x dl=%d",
2478f23e9faSHans Rosenfeld did, sbp, scsi_opcode, pkt->pkt_datalen);
2488f23e9faSHans Rosenfeld
2498f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.scsi_status =
2508f23e9faSHans Rosenfeld SCSI_STAT_CHECK_COND;
2518f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.rsp_len_set = 0;
2528f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.sense_len_set = 0;
2538f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.resid_over = 0;
2548f23e9faSHans Rosenfeld
2558f23e9faSHans Rosenfeld if (pkt->pkt_datalen) {
2568f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.resid_under = 1;
2578f23e9faSHans Rosenfeld rsp->fcp_resid =
2588f23e9faSHans Rosenfeld LE_SWAP32(pkt->pkt_datalen);
2598f23e9faSHans Rosenfeld } else {
2608f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.resid_under = 0;
2618f23e9faSHans Rosenfeld rsp->fcp_resid = 0;
2628f23e9faSHans Rosenfeld }
263fcf3ce44SJohn Forte
2648f23e9faSHans Rosenfeld scsi_status = SCSI_STAT_CHECK_COND;
2658f23e9faSHans Rosenfeld }
266fcf3ce44SJohn Forte
2678f23e9faSHans Rosenfeld /*
2688f23e9faSHans Rosenfeld * We only need to check underrun if data could
2698f23e9faSHans Rosenfeld * have been sent
2708f23e9faSHans Rosenfeld */
271fcf3ce44SJohn Forte
2728f23e9faSHans Rosenfeld /* Always check underrun if status is good */
2738f23e9faSHans Rosenfeld if (scsi_status == SCSI_STAT_GOOD) {
2748f23e9faSHans Rosenfeld check_underrun = 1;
2758f23e9faSHans Rosenfeld }
2768f23e9faSHans Rosenfeld /* Check the sense codes if this is a check condition */
2778f23e9faSHans Rosenfeld else if (scsi_status == SCSI_STAT_CHECK_COND) {
2788f23e9faSHans Rosenfeld check_underrun = 1;
2798f23e9faSHans Rosenfeld
2808f23e9faSHans Rosenfeld /* Check if sense data was provided */
2818f23e9faSHans Rosenfeld if (LE_SWAP32(rsp->fcp_sense_len) >= 14) {
2828f23e9faSHans Rosenfeld sense = *((uint8_t *)rsp + 32 + 2);
2838f23e9faSHans Rosenfeld asc = *((uint8_t *)rsp + 32 + 12);
2848f23e9faSHans Rosenfeld ascq = *((uint8_t *)rsp + 32 + 13);
285fcf3ce44SJohn Forte }
286291a2b48SSukumar Swaminathan
2878f23e9faSHans Rosenfeld #ifdef SAN_DIAG_SUPPORT
2888f23e9faSHans Rosenfeld emlxs_log_sd_scsi_check_event(port,
2898f23e9faSHans Rosenfeld (HBA_WWN *)&ndlp->nlp_portname, sbp->lun,
2908f23e9faSHans Rosenfeld scsi_opcode, sense, asc, ascq);
2918f23e9faSHans Rosenfeld #endif
2928f23e9faSHans Rosenfeld }
2938f23e9faSHans Rosenfeld /* Status is not good and this is not a check condition */
2948f23e9faSHans Rosenfeld /* No data should have been sent */
2958f23e9faSHans Rosenfeld else {
2968f23e9faSHans Rosenfeld check_underrun = 0;
2978f23e9faSHans Rosenfeld }
2988f23e9faSHans Rosenfeld
2998f23e9faSHans Rosenfeld /* Initialize the resids */
3008f23e9faSHans Rosenfeld pkt->pkt_resp_resid = 0;
3018f23e9faSHans Rosenfeld pkt->pkt_data_resid = 0;
3028f23e9faSHans Rosenfeld
3038f23e9faSHans Rosenfeld /* Check if no data was to be transferred */
3048f23e9faSHans Rosenfeld if (pkt->pkt_datalen == 0) {
3058f23e9faSHans Rosenfeld goto done;
3068f23e9faSHans Rosenfeld }
3078f23e9faSHans Rosenfeld
3088f23e9faSHans Rosenfeld /* Get the residual underrun count reported by the SCSI reply */
3098f23e9faSHans Rosenfeld rsp_data_resid = (rsp->fcp_u.fcp_status.resid_under) ?
3108f23e9faSHans Rosenfeld LE_SWAP32(rsp->fcp_resid) : 0;
3118f23e9faSHans Rosenfeld
3128f23e9faSHans Rosenfeld /* Set the pkt_data_resid to what the scsi response resid */
3138f23e9faSHans Rosenfeld pkt->pkt_data_resid = rsp_data_resid;
3148f23e9faSHans Rosenfeld
3158f23e9faSHans Rosenfeld /* Adjust the pkt_data_resid field if needed */
3168f23e9faSHans Rosenfeld if (pkt->pkt_tran_type == FC_PKT_FCP_READ) {
317fcf3ce44SJohn Forte /*
3188f23e9faSHans Rosenfeld * Get the residual underrun count reported by
3198f23e9faSHans Rosenfeld * our adapter
320fcf3ce44SJohn Forte */
3218f23e9faSHans Rosenfeld pkt->pkt_data_resid = cmd->un.fcpi.fcpi_parm;
322291a2b48SSukumar Swaminathan
323291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
3248f23e9faSHans Rosenfeld if ((rsp_data_resid == 0) && (pkt->pkt_data_resid)) {
3258f23e9faSHans Rosenfeld emlxs_log_sd_fc_rdchk_event(port,
326291a2b48SSukumar Swaminathan (HBA_WWN *)&ndlp->nlp_portname, sbp->lun,
3278f23e9faSHans Rosenfeld scsi_opcode, pkt->pkt_data_resid);
328fcf3ce44SJohn Forte }
3298f23e9faSHans Rosenfeld #endif
3308f23e9faSHans Rosenfeld
3318f23e9faSHans Rosenfeld /* Get the actual amount of data transferred */
3328f23e9faSHans Rosenfeld data_rx = pkt->pkt_datalen - pkt->pkt_data_resid;
333fcf3ce44SJohn Forte
3348f23e9faSHans Rosenfeld /*
3358f23e9faSHans Rosenfeld * If the residual being reported by the adapter is
3368f23e9faSHans Rosenfeld * greater than the residual being reported in the
3378f23e9faSHans Rosenfeld * reply, then we have a true underrun.
3388f23e9faSHans Rosenfeld */
3398f23e9faSHans Rosenfeld if (check_underrun && (pkt->pkt_data_resid > rsp_data_resid)) {
3408f23e9faSHans Rosenfeld switch (scsi_opcode) {
3418f23e9faSHans Rosenfeld case SCSI_INQUIRY:
3428f23e9faSHans Rosenfeld scsi_dl = scsi_cmd[16];
3438f23e9faSHans Rosenfeld break;
3448f23e9faSHans Rosenfeld
3458f23e9faSHans Rosenfeld case SCSI_RX_DIAG:
3468f23e9faSHans Rosenfeld scsi_dl =
3478f23e9faSHans Rosenfeld (scsi_cmd[15] * 0x100) +
3488f23e9faSHans Rosenfeld scsi_cmd[16];
3498f23e9faSHans Rosenfeld break;
350fcf3ce44SJohn Forte
3518f23e9faSHans Rosenfeld default:
3528f23e9faSHans Rosenfeld scsi_dl = pkt->pkt_datalen;
3538f23e9faSHans Rosenfeld }
354fcf3ce44SJohn Forte
3558f23e9faSHans Rosenfeld #ifdef FCP_UNDERRUN_PATCH1
3568f23e9faSHans Rosenfeld if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH1) {
357fcf3ce44SJohn Forte /*
3588f23e9faSHans Rosenfeld * If status is not good and no data was
3598f23e9faSHans Rosenfeld * actually transferred, then we must fix
3608f23e9faSHans Rosenfeld * the issue
361fcf3ce44SJohn Forte */
3628f23e9faSHans Rosenfeld if ((scsi_status != SCSI_STAT_GOOD) && (data_rx == 0)) {
3638f23e9faSHans Rosenfeld fix_it = 1;
3648f23e9faSHans Rosenfeld
3658f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT,
3668f23e9faSHans Rosenfeld &emlxs_fcp_completion_error_msg,
3678f23e9faSHans Rosenfeld "Underrun(1). Fixed. "
3688f23e9faSHans Rosenfeld "did=0x%06x sbp=%p cmd=%02x "
3698f23e9faSHans Rosenfeld "dl=%d,%d rx=%d rsp=%d",
3708f23e9faSHans Rosenfeld did, sbp, scsi_opcode,
3718f23e9faSHans Rosenfeld pkt->pkt_datalen, scsi_dl,
3728f23e9faSHans Rosenfeld (pkt->pkt_datalen -
3738f23e9faSHans Rosenfeld pkt->pkt_data_resid),
3748f23e9faSHans Rosenfeld rsp_data_resid);
375fcf3ce44SJohn Forte
376291a2b48SSukumar Swaminathan }
3778f23e9faSHans Rosenfeld }
3788f23e9faSHans Rosenfeld #endif /* FCP_UNDERRUN_PATCH1 */
379291a2b48SSukumar Swaminathan
380fcf3ce44SJohn Forte
3818f23e9faSHans Rosenfeld #ifdef FCP_UNDERRUN_PATCH2
3828f23e9faSHans Rosenfeld if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH2) {
3838f23e9faSHans Rosenfeld if (scsi_status == SCSI_STAT_GOOD) {
3848f23e9faSHans Rosenfeld emlxs_msg_t *msg;
385fcf3ce44SJohn Forte
3868f23e9faSHans Rosenfeld msg = &emlxs_fcp_completion_error_msg;
3878f23e9faSHans Rosenfeld /*
3888f23e9faSHans Rosenfeld * If status is good and this is an
3898f23e9faSHans Rosenfeld * inquiry request and the amount of
3908f23e9faSHans Rosenfeld * data
3918f23e9faSHans Rosenfeld */
3928f23e9faSHans Rosenfeld /*
3938f23e9faSHans Rosenfeld * requested <= data received, then we
3948f23e9faSHans Rosenfeld * must fix the issue.
3958f23e9faSHans Rosenfeld */
3968f23e9faSHans Rosenfeld
3978f23e9faSHans Rosenfeld if ((scsi_opcode == SCSI_INQUIRY) &&
3988f23e9faSHans Rosenfeld (pkt->pkt_datalen >= data_rx) &&
3998f23e9faSHans Rosenfeld (scsi_dl <= data_rx)) {
4008f23e9faSHans Rosenfeld fix_it = 1;
4018f23e9faSHans Rosenfeld
4028f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, msg,
4038f23e9faSHans Rosenfeld "Underrun(2). Fixed. "
4048f23e9faSHans Rosenfeld "did=0x%06x sbp=%p "
4058f23e9faSHans Rosenfeld "cmd=%02x dl=%d,%d "
4068f23e9faSHans Rosenfeld "rx=%d rsp=%d",
4078f23e9faSHans Rosenfeld did, sbp, scsi_opcode,
4088f23e9faSHans Rosenfeld pkt->pkt_datalen, scsi_dl,
4098f23e9faSHans Rosenfeld data_rx, rsp_data_resid);
410fcf3ce44SJohn Forte
411fcf3ce44SJohn Forte }
412fcf3ce44SJohn Forte
413fcf3ce44SJohn Forte /*
4148f23e9faSHans Rosenfeld * If status is good and this is an
4158f23e9faSHans Rosenfeld * inquiry request and the amount of
4168f23e9faSHans Rosenfeld * data requested >= 128 bytes, but
4178f23e9faSHans Rosenfeld * only 128 bytes were received,
4188f23e9faSHans Rosenfeld * then we must fix the issue.
419fcf3ce44SJohn Forte */
4208f23e9faSHans Rosenfeld else if ((scsi_opcode == SCSI_INQUIRY) &&
4218f23e9faSHans Rosenfeld (pkt->pkt_datalen >= 128) &&
4228f23e9faSHans Rosenfeld (scsi_dl >= 128) && (data_rx == 128)) {
423fcf3ce44SJohn Forte fix_it = 1;
424fcf3ce44SJohn Forte
4258f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, msg,
4268f23e9faSHans Rosenfeld "Underrun(3). Fixed. "
4278f23e9faSHans Rosenfeld "did=0x%06x sbp=%p "
4288f23e9faSHans Rosenfeld "cmd=%02x dl=%d,%d "
4298f23e9faSHans Rosenfeld "rx=%d rsp=%d",
430fcf3ce44SJohn Forte did, sbp, scsi_opcode,
431fcf3ce44SJohn Forte pkt->pkt_datalen, scsi_dl,
4328f23e9faSHans Rosenfeld data_rx, rsp_data_resid);
433fcf3ce44SJohn Forte
434fcf3ce44SJohn Forte }
4358f23e9faSHans Rosenfeld }
43682527734SSukumar Swaminathan }
4378f23e9faSHans Rosenfeld #endif /* FCP_UNDERRUN_PATCH2 */
438fcf3ce44SJohn Forte
4398f23e9faSHans Rosenfeld /*
4408f23e9faSHans Rosenfeld * Check if SCSI response payload should be
4418f23e9faSHans Rosenfeld * fixed or if a DATA_UNDERRUN should be
4428f23e9faSHans Rosenfeld * reported
4438f23e9faSHans Rosenfeld */
4448f23e9faSHans Rosenfeld if (fix_it) {
4458f23e9faSHans Rosenfeld /*
4468f23e9faSHans Rosenfeld * Fix the SCSI response payload itself
4478f23e9faSHans Rosenfeld */
4488f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.resid_under = 1;
4498f23e9faSHans Rosenfeld rsp->fcp_resid =
4508f23e9faSHans Rosenfeld LE_SWAP32(pkt->pkt_data_resid);
4518f23e9faSHans Rosenfeld } else {
4528f23e9faSHans Rosenfeld /*
4538f23e9faSHans Rosenfeld * Change the status from
4548f23e9faSHans Rosenfeld * IOSTAT_FCP_RSP_ERROR to
4558f23e9faSHans Rosenfeld * IOSTAT_DATA_UNDERRUN
4568f23e9faSHans Rosenfeld */
4578f23e9faSHans Rosenfeld iostat = IOSTAT_DATA_UNDERRUN;
4588f23e9faSHans Rosenfeld pkt->pkt_data_resid =
4598f23e9faSHans Rosenfeld pkt->pkt_datalen;
4608f23e9faSHans Rosenfeld }
4618f23e9faSHans Rosenfeld }
462fcf3ce44SJohn Forte
4638f23e9faSHans Rosenfeld /*
4648f23e9faSHans Rosenfeld * If the residual being reported by the adapter is
4658f23e9faSHans Rosenfeld * less than the residual being reported in the reply,
4668f23e9faSHans Rosenfeld * then we have a true overrun. Since we don't know
4678f23e9faSHans Rosenfeld * where the extra data came from or went to then we
4688f23e9faSHans Rosenfeld * cannot trust anything we received
4698f23e9faSHans Rosenfeld */
4708f23e9faSHans Rosenfeld else if (rsp_data_resid > pkt->pkt_data_resid) {
4718f23e9faSHans Rosenfeld /*
4728f23e9faSHans Rosenfeld * Change the status from
4738f23e9faSHans Rosenfeld * IOSTAT_FCP_RSP_ERROR to
4748f23e9faSHans Rosenfeld * IOSTAT_DATA_OVERRUN
4758f23e9faSHans Rosenfeld */
4768f23e9faSHans Rosenfeld iostat = IOSTAT_DATA_OVERRUN;
4778f23e9faSHans Rosenfeld pkt->pkt_data_resid = pkt->pkt_datalen;
4788f23e9faSHans Rosenfeld }
479fcf3ce44SJohn Forte
4808f23e9faSHans Rosenfeld } else if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) &&
4818f23e9faSHans Rosenfeld (pkt->pkt_tran_type == FC_PKT_FCP_WRITE)) {
4828f23e9faSHans Rosenfeld /*
4838f23e9faSHans Rosenfeld * Get the residual underrun count reported by
4848f23e9faSHans Rosenfeld * our adapter
4858f23e9faSHans Rosenfeld */
4868f23e9faSHans Rosenfeld pkt->pkt_data_resid = cmd->un.fcpi.fcpi_parm;
487fcf3ce44SJohn Forte
4888f23e9faSHans Rosenfeld #ifdef SAN_DIAG_SUPPORT
4898f23e9faSHans Rosenfeld if ((rsp_data_resid == 0) && (pkt->pkt_data_resid)) {
4908f23e9faSHans Rosenfeld emlxs_log_sd_fc_rdchk_event(port,
4918f23e9faSHans Rosenfeld (HBA_WWN *)&ndlp->nlp_portname, sbp->lun,
4928f23e9faSHans Rosenfeld scsi_opcode, pkt->pkt_data_resid);
4938f23e9faSHans Rosenfeld }
4948f23e9faSHans Rosenfeld #endif /* SAN_DIAG_SUPPORT */
495fcf3ce44SJohn Forte
4968f23e9faSHans Rosenfeld /* Get the actual amount of data transferred */
4978f23e9faSHans Rosenfeld data_rx = pkt->pkt_datalen - pkt->pkt_data_resid;
498fcf3ce44SJohn Forte
4998f23e9faSHans Rosenfeld /*
5008f23e9faSHans Rosenfeld * If the residual being reported by the adapter is
5018f23e9faSHans Rosenfeld * greater than the residual being reported in the
5028f23e9faSHans Rosenfeld * reply, then we have a true underrun.
5038f23e9faSHans Rosenfeld */
5048f23e9faSHans Rosenfeld if (check_underrun && (pkt->pkt_data_resid > rsp_data_resid)) {
505291a2b48SSukumar Swaminathan
5068f23e9faSHans Rosenfeld scsi_dl = pkt->pkt_datalen;
507fcf3ce44SJohn Forte
5088f23e9faSHans Rosenfeld #ifdef FCP_UNDERRUN_PATCH1
5098f23e9faSHans Rosenfeld if (cfg[CFG_ENABLE_PATCH].current & FCP_UNDERRUN_PATCH1) {
5108f23e9faSHans Rosenfeld /*
5118f23e9faSHans Rosenfeld * If status is not good and no data was
5128f23e9faSHans Rosenfeld * actually transferred, then we must fix
5138f23e9faSHans Rosenfeld * the issue
5148f23e9faSHans Rosenfeld */
5158f23e9faSHans Rosenfeld if ((scsi_status != SCSI_STAT_GOOD) && (data_rx == 0)) {
5168f23e9faSHans Rosenfeld fix_it = 1;
517291a2b48SSukumar Swaminathan
5188f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT,
5198f23e9faSHans Rosenfeld &emlxs_fcp_completion_error_msg,
5208f23e9faSHans Rosenfeld "Underrun(1). Fixed. "
5218f23e9faSHans Rosenfeld "did=0x%06x sbp=%p cmd=%02x "
5228f23e9faSHans Rosenfeld "dl=%d,%d rx=%d rsp=%d",
5238f23e9faSHans Rosenfeld did, sbp, scsi_opcode,
5248f23e9faSHans Rosenfeld pkt->pkt_datalen, scsi_dl,
5258f23e9faSHans Rosenfeld (pkt->pkt_datalen -
5268f23e9faSHans Rosenfeld pkt->pkt_data_resid),
5278f23e9faSHans Rosenfeld rsp_data_resid);
528fcf3ce44SJohn Forte
529fcf3ce44SJohn Forte }
5308f23e9faSHans Rosenfeld }
5318f23e9faSHans Rosenfeld #endif /* FCP_UNDERRUN_PATCH1 */
532291a2b48SSukumar Swaminathan
533fcf3ce44SJohn Forte /*
5348f23e9faSHans Rosenfeld * Check if SCSI response payload should be
5358f23e9faSHans Rosenfeld * fixed or if a DATA_UNDERRUN should be
5368f23e9faSHans Rosenfeld * reported
537fcf3ce44SJohn Forte */
5388f23e9faSHans Rosenfeld if (fix_it) {
5398f23e9faSHans Rosenfeld /*
5408f23e9faSHans Rosenfeld * Fix the SCSI response payload itself
5418f23e9faSHans Rosenfeld */
5428f23e9faSHans Rosenfeld rsp->fcp_u.fcp_status.resid_under = 1;
5438f23e9faSHans Rosenfeld rsp->fcp_resid =
5448f23e9faSHans Rosenfeld LE_SWAP32(pkt->pkt_data_resid);
5458f23e9faSHans Rosenfeld } else {
546fcf3ce44SJohn Forte /*
547fcf3ce44SJohn Forte * Change the status from
548fcf3ce44SJohn Forte * IOSTAT_FCP_RSP_ERROR to
5498f23e9faSHans Rosenfeld * IOSTAT_DATA_UNDERRUN
550fcf3ce44SJohn Forte */
5518f23e9faSHans Rosenfeld iostat = IOSTAT_DATA_UNDERRUN;
5528f23e9faSHans Rosenfeld pkt->pkt_data_resid =
5538f23e9faSHans Rosenfeld pkt->pkt_datalen;
554fcf3ce44SJohn Forte }
5558f23e9faSHans Rosenfeld }
556291a2b48SSukumar Swaminathan
5578f23e9faSHans Rosenfeld /*
5588f23e9faSHans Rosenfeld * If the residual being reported by the adapter is
5598f23e9faSHans Rosenfeld * less than the residual being reported in the reply,
5608f23e9faSHans Rosenfeld * then we have a true overrun. Since we don't know
5618f23e9faSHans Rosenfeld * where the extra data came from or went to then we
5628f23e9faSHans Rosenfeld * cannot trust anything we received
5638f23e9faSHans Rosenfeld */
5648f23e9faSHans Rosenfeld else if (rsp_data_resid > pkt->pkt_data_resid) {
5658f23e9faSHans Rosenfeld /*
5668f23e9faSHans Rosenfeld * Change the status from
5678f23e9faSHans Rosenfeld * IOSTAT_FCP_RSP_ERROR to
5688f23e9faSHans Rosenfeld * IOSTAT_DATA_OVERRUN
5698f23e9faSHans Rosenfeld */
5708f23e9faSHans Rosenfeld iostat = IOSTAT_DATA_OVERRUN;
5718f23e9faSHans Rosenfeld pkt->pkt_data_resid = pkt->pkt_datalen;
572fcf3ce44SJohn Forte }
573fcf3ce44SJohn Forte }
574291a2b48SSukumar Swaminathan
5758f23e9faSHans Rosenfeld done:
5768f23e9faSHans Rosenfeld
577fcf3ce44SJohn Forte /* Print completion message */
578fcf3ce44SJohn Forte switch (iostat) {
579fcf3ce44SJohn Forte case IOSTAT_SUCCESS:
580fcf3ce44SJohn Forte /* Build SCSI GOOD status */
581fcf3ce44SJohn Forte if (pkt->pkt_rsplen) {
582fcf3ce44SJohn Forte bzero((uint8_t *)pkt->pkt_resp, pkt->pkt_rsplen);
583fcf3ce44SJohn Forte }
584fcf3ce44SJohn Forte break;
585fcf3ce44SJohn Forte
586fcf3ce44SJohn Forte case IOSTAT_FCP_RSP_ERROR:
587fcf3ce44SJohn Forte break;
588fcf3ce44SJohn Forte
589fcf3ce44SJohn Forte case IOSTAT_REMOTE_STOP:
590fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
591291a2b48SSukumar Swaminathan "Remote Stop. did=0x%06x sbp=%p cmd=%02x", did, sbp,
592291a2b48SSukumar Swaminathan scsi_opcode);
593fcf3ce44SJohn Forte break;
594fcf3ce44SJohn Forte
595fcf3ce44SJohn Forte case IOSTAT_LOCAL_REJECT:
596fcf3ce44SJohn Forte localstat = cmd->un.grsp.perr.statLocalError;
597fcf3ce44SJohn Forte
598fcf3ce44SJohn Forte switch (localstat) {
599fcf3ce44SJohn Forte case IOERR_SEQUENCE_TIMEOUT:
600fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT,
601fcf3ce44SJohn Forte &emlxs_fcp_completion_error_msg,
602291a2b48SSukumar Swaminathan "Local reject. "
603291a2b48SSukumar Swaminathan "%s did=0x%06x sbp=%p cmd=%02x tmo=%d ",
604fcf3ce44SJohn Forte emlxs_error_xlate(localstat), did, sbp,
605fcf3ce44SJohn Forte scsi_opcode, pkt->pkt_timeout);
606fcf3ce44SJohn Forte break;
607fcf3ce44SJohn Forte
608fcf3ce44SJohn Forte default:
609fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT,
610fcf3ce44SJohn Forte &emlxs_fcp_completion_error_msg,
611a9800bebSGarrett D'Amore "Local reject. %s 0x%06x %p %02x (%x)(%x)",
612291a2b48SSukumar Swaminathan emlxs_error_xlate(localstat), did, sbp,
613a9800bebSGarrett D'Amore scsi_opcode, (uint16_t)cmd->ULPIOTAG,
614a9800bebSGarrett D'Amore (uint16_t)cmd->ULPCONTEXT);
615fcf3ce44SJohn Forte }
616fcf3ce44SJohn Forte
617fcf3ce44SJohn Forte break;
618fcf3ce44SJohn Forte
619fcf3ce44SJohn Forte case IOSTAT_NPORT_RJT:
620fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
621291a2b48SSukumar Swaminathan "Nport reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
622291a2b48SSukumar Swaminathan scsi_opcode);
623fcf3ce44SJohn Forte break;
624fcf3ce44SJohn Forte
625fcf3ce44SJohn Forte case IOSTAT_FABRIC_RJT:
626fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
627291a2b48SSukumar Swaminathan "Fabric reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
628291a2b48SSukumar Swaminathan scsi_opcode);
629fcf3ce44SJohn Forte break;
630fcf3ce44SJohn Forte
631fcf3ce44SJohn Forte case IOSTAT_NPORT_BSY:
632291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
633291a2b48SSukumar Swaminathan ndlp = (NODELIST *)iocbq->node;
634291a2b48SSukumar Swaminathan emlxs_log_sd_fc_bsy_event(port, (HBA_WWN *)&ndlp->nlp_portname);
635291a2b48SSukumar Swaminathan #endif
636291a2b48SSukumar Swaminathan
637fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
638291a2b48SSukumar Swaminathan "Nport busy. did=0x%06x sbp=%p cmd=%02x", did, sbp,
639291a2b48SSukumar Swaminathan scsi_opcode);
640fcf3ce44SJohn Forte break;
641fcf3ce44SJohn Forte
642fcf3ce44SJohn Forte case IOSTAT_FABRIC_BSY:
643291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
644291a2b48SSukumar Swaminathan ndlp = (NODELIST *)iocbq->node;
645291a2b48SSukumar Swaminathan emlxs_log_sd_fc_bsy_event(port, NULL);
646291a2b48SSukumar Swaminathan #endif
647291a2b48SSukumar Swaminathan
648fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
649291a2b48SSukumar Swaminathan "Fabric busy. did=0x%06x sbp=%p cmd=%02x", did, sbp,
650291a2b48SSukumar Swaminathan scsi_opcode);
651fcf3ce44SJohn Forte break;
652fcf3ce44SJohn Forte
653fcf3ce44SJohn Forte case IOSTAT_INTERMED_RSP:
654fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
655291a2b48SSukumar Swaminathan "Intermediate response. did=0x%06x sbp=%p cmd=%02x", did,
656291a2b48SSukumar Swaminathan sbp, scsi_opcode);
657fcf3ce44SJohn Forte break;
658fcf3ce44SJohn Forte
659fcf3ce44SJohn Forte case IOSTAT_LS_RJT:
660fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
661291a2b48SSukumar Swaminathan "LS Reject. did=0x%06x sbp=%p cmd=%02x", did, sbp,
662291a2b48SSukumar Swaminathan scsi_opcode);
663fcf3ce44SJohn Forte break;
664fcf3ce44SJohn Forte
665fcf3ce44SJohn Forte case IOSTAT_DATA_UNDERRUN:
666fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
667291a2b48SSukumar Swaminathan "Underrun. did=0x%06x sbp=%p cmd=%02x "
668291a2b48SSukumar Swaminathan "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)",
669291a2b48SSukumar Swaminathan did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx,
670291a2b48SSukumar Swaminathan rsp_data_resid, scsi_status, sense, asc, ascq);
671fcf3ce44SJohn Forte break;
672fcf3ce44SJohn Forte
673fcf3ce44SJohn Forte case IOSTAT_DATA_OVERRUN:
674fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
675291a2b48SSukumar Swaminathan "Overrun. did=0x%06x sbp=%p cmd=%02x "
676291a2b48SSukumar Swaminathan "dl=%d,%d rx=%d rsp=%d (%02x,%02x,%02x,%02x)",
677291a2b48SSukumar Swaminathan did, sbp, scsi_opcode, pkt->pkt_datalen, scsi_dl, data_rx,
678291a2b48SSukumar Swaminathan rsp_data_resid, scsi_status, sense, asc, ascq);
679fcf3ce44SJohn Forte break;
680fcf3ce44SJohn Forte
6818f23e9faSHans Rosenfeld case IOSTAT_RSP_INVALID:
6828f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
6838f23e9faSHans Rosenfeld "Rsp Invalid. did=0x%06x sbp=%p cmd=%02x dl=%d rl=%d"
6848f23e9faSHans Rosenfeld "(%d, %d, %d)",
6858f23e9faSHans Rosenfeld did, sbp, scsi_opcode, pkt->pkt_datalen, pkt->pkt_rsplen,
6868f23e9faSHans Rosenfeld LE_SWAP32(rsp->fcp_resid),
6878f23e9faSHans Rosenfeld LE_SWAP32(rsp->fcp_sense_len),
6888f23e9faSHans Rosenfeld LE_SWAP32(rsp->fcp_response_len));
6898f23e9faSHans Rosenfeld break;
6908f23e9faSHans Rosenfeld
691fcf3ce44SJohn Forte default:
692fcf3ce44SJohn Forte EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcp_completion_error_msg,
693fcf3ce44SJohn Forte "Unknown status=%x reason=%x did=0x%06x sbp=%p cmd=%02x",
694291a2b48SSukumar Swaminathan iostat, cmd->un.grsp.perr.statLocalError, did, sbp,
695291a2b48SSukumar Swaminathan scsi_opcode);
696fcf3ce44SJohn Forte break;
697fcf3ce44SJohn Forte }
698fcf3ce44SJohn Forte
699fcf3ce44SJohn Forte if (iostat == IOSTAT_SUCCESS) {
700fcf3ce44SJohn Forte HBASTATS.FcpGood++;
701fcf3ce44SJohn Forte } else {
702fcf3ce44SJohn Forte HBASTATS.FcpError++;
703fcf3ce44SJohn Forte }
704fcf3ce44SJohn Forte
705fcf3ce44SJohn Forte mutex_exit(&sbp->mtx);
706fcf3ce44SJohn Forte
707fcf3ce44SJohn Forte emlxs_pkt_complete(sbp, iostat, localstat, 0);
708fcf3ce44SJohn Forte
709fcf3ce44SJohn Forte return;
710fcf3ce44SJohn Forte
71182527734SSukumar Swaminathan } /* emlxs_handle_fcp_event() */
712fcf3ce44SJohn Forte
713fcf3ce44SJohn Forte
714fcf3ce44SJohn Forte /*
715fcf3ce44SJohn Forte * emlxs_post_buffer
716fcf3ce44SJohn Forte *
717fcf3ce44SJohn Forte * This routine will post count buffers to the
718fcf3ce44SJohn Forte * ring with the QUE_RING_BUF_CN command. This
719fcf3ce44SJohn Forte * allows 2 buffers / command to be posted.
720fcf3ce44SJohn Forte * Returns the number of buffers NOT posted.
721fcf3ce44SJohn Forte */
72282527734SSukumar Swaminathan /* SLI3 */
723fcf3ce44SJohn Forte extern int
emlxs_post_buffer(emlxs_hba_t * hba,RING * rp,int16_t cnt)724fcf3ce44SJohn Forte emlxs_post_buffer(emlxs_hba_t *hba, RING *rp, int16_t cnt)
725fcf3ce44SJohn Forte {
726fcf3ce44SJohn Forte emlxs_port_t *port = &PPORT;
727fcf3ce44SJohn Forte IOCB *icmd;
728fcf3ce44SJohn Forte IOCBQ *iocbq;
729fcf3ce44SJohn Forte MATCHMAP *mp;
730fcf3ce44SJohn Forte uint16_t tag;
731fcf3ce44SJohn Forte uint32_t maxqbuf;
732fcf3ce44SJohn Forte int32_t i;
733fcf3ce44SJohn Forte int32_t j;
734fcf3ce44SJohn Forte uint32_t seg;
735fcf3ce44SJohn Forte uint32_t size;
736fcf3ce44SJohn Forte
737fcf3ce44SJohn Forte mp = 0;
738fcf3ce44SJohn Forte maxqbuf = 2;
739fcf3ce44SJohn Forte tag = (uint16_t)cnt;
740fcf3ce44SJohn Forte cnt += rp->fc_missbufcnt;
741fcf3ce44SJohn Forte
74282527734SSukumar Swaminathan if (rp->ringno == hba->channel_els) {
743fcf3ce44SJohn Forte seg = MEM_BUF;
744fcf3ce44