From 97abf4d1078b611795f79290ff9ec8de75419f7b Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Wed, 11 Feb 2009 18:55:43 +0000 Subject: [PATCH] Merge in work from Feral into this branch. The recovery from not being able to push a ctio fix is in. Various task management fixes are also in. Other work in progress. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@672 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla_isp/common/isp.c | 582 ++++++++----------- qla_isp/common/isp_library.c | 43 +- qla_isp/common/isp_library.h | 26 +- qla_isp/common/isp_stds.h | 26 +- qla_isp/common/isp_target.c | 710 ++++++++++++------------ qla_isp/common/isp_target.h | 1012 +++------------------------------- qla_isp/common/isp_tpublic.h | 87 +-- qla_isp/common/ispmbox.h | 951 +++++++++++++++++++++++++++++++- qla_isp/common/ispreg.h | 41 +- qla_isp/common/ispvar.h | 91 ++- qla_isp/linux/isp_cb_ops.c | 17 +- qla_isp/linux/isp_ioctl.h | 2 +- qla_isp/linux/isp_linux.c | 592 ++++++++++---------- qla_isp/linux/isp_linux.h | 78 ++- qla_isp/linux/isp_pci.c | 128 ++--- qla_isp/linux/isp_scst.c | 101 ++-- 16 files changed, 2217 insertions(+), 2270 deletions(-) diff --git a/qla_isp/common/isp.c b/qla_isp/common/isp.c index 55b7552a8..7949fe07d 100644 --- a/qla_isp/common/isp.c +++ b/qla_isp/common/isp.c @@ -1,4 +1,4 @@ -/* $Id: isp.c,v 1.209 2008/09/12 16:01:52 mjacob Exp $ */ +/* $Id: isp.c,v 1.213 2009/02/01 23:49:48 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -339,6 +339,23 @@ isp_reset(ispsoftc_t *isp) /* * XXX: Should probably do some bus sensing. */ + } else if (IS_ULTRA3(isp)) { + sdparam *sdp = isp->isp_param; + + isp->isp_clock = 100; + + if (IS_10160(isp)) + btype = "10160"; + else if (IS_12160(isp)) + btype = "12160"; + else + btype = ""; + sdp->isp_lvdmode = 1; + + if (IS_DUALBUS(isp)) { + sdp++; + sdp->isp_lvdmode = 1; + } } else if (IS_ULTRA2(isp)) { static const char m[] = "bus %d is in %s Mode"; uint16_t l; @@ -350,10 +367,6 @@ isp_reset(ispsoftc_t *isp) btype = "1280"; else if (IS_1080(isp)) btype = "1080"; - else if (IS_10160(isp)) - btype = "10160"; - else if (IS_12160(isp)) - btype = "12160"; else btype = ""; @@ -508,7 +521,7 @@ isp_reset(ispsoftc_t *isp) /* * A slight delay... */ - USEC_DELAY(100); + ISP_DELAY(100); /* * Clear data && control DMA engines. @@ -525,7 +538,7 @@ isp_reset(ispsoftc_t *isp) */ ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4)); for (val = loops = 0; loops < 30000; loops++) { - USEC_DELAY(10); + ISP_DELAY(10); val = ISP_READ(isp, BIU2400_CSR); if ((val & BIU2400_DMA_ACTIVE) == 0) { break; @@ -541,9 +554,9 @@ isp_reset(ispsoftc_t *isp) */ ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4)); - USEC_DELAY(100); + ISP_DELAY(100); for (loops = 0; loops < 10000; loops++) { - USEC_DELAY(5); + ISP_DELAY(5); val = ISP_READ(isp, OUTMAILBOX0); } for (val = loops = 0; loops < 500000; loops ++) { @@ -562,7 +575,7 @@ isp_reset(ispsoftc_t *isp) /* * A slight delay... */ - USEC_DELAY(100); + ISP_DELAY(100); /* * Clear data && control DMA engines. @@ -592,7 +605,7 @@ isp_reset(ispsoftc_t *isp) if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET)) break; } - USEC_DELAY(100); + ISP_DELAY(100); if (--loops < 0) { ISP_DUMPREGS(isp, "chip reset timed out"); ISP_RESET0(isp); @@ -620,7 +633,7 @@ isp_reset(ispsoftc_t *isp) ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET); } else { ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); - USEC_DELAY(100); + ISP_DELAY(100); ISP_WRITE(isp, BIU_SEMA, 0); } @@ -629,7 +642,7 @@ isp_reset(ispsoftc_t *isp) */ if (IS_24XX(isp)) { for (val = loops = 0; loops < 5000000; loops++) { - USEC_DELAY(5); + ISP_DELAY(5); val = ISP_READ(isp, OUTMAILBOX0); if (val == 0) { break; @@ -701,11 +714,11 @@ isp_reset(ispsoftc_t *isp) * parity error (chip breakage). */ if (IS_2312(isp) && isp->isp_revision < 2) { - USEC_DELAY(100); + ISP_DELAY(100); } else { loops = MBOX_DELAY_COUNT; while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) { - USEC_DELAY(100); + ISP_DELAY(100); if (--loops < 0) { ISP_RESET0(isp); isp_prt(isp, ISP_LOGERR, @@ -725,7 +738,7 @@ isp_reset(ispsoftc_t *isp) * Do some sanity checking by running a NOP command. * If it succeeds, the ROM firmware is now running. */ - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_NO_OP; mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); @@ -741,7 +754,7 @@ isp_reset(ispsoftc_t *isp) */ if (IS_SCSI(isp) || IS_24XX(isp)) { - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_MAILBOX_REG_TEST; mbs.param[1] = 0xdead; mbs.param[2] = 0xbeef; @@ -825,7 +838,7 @@ isp_reset(ispsoftc_t *isp) } MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_LOAD_RISC_RAM; mbs.param[1] = la; mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); @@ -888,7 +901,7 @@ isp_reset(ispsoftc_t *isp) } MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_LOAD_RISC_RAM; mbs.param[1] = la; mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); @@ -908,6 +921,10 @@ isp_reset(ispsoftc_t *isp) la += nw; } + if (!IS_2322(isp)) { + break; + } + if (++segno == 3) { break; } @@ -934,7 +951,7 @@ isp_reset(ispsoftc_t *isp) isp->isp_mbxworkp = &ucd.np[1]; isp->isp_mbxwrk0 = ucd.np[3] - 1; isp->isp_mbxwrk1 = code_org + 1; - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_WRITE_RAM_WORD; mbs.param[1] = code_org; mbs.param[2] = ucd.np[0]; @@ -956,7 +973,7 @@ isp_reset(ispsoftc_t *isp) * If we loaded firmware, verify its checksum */ if (isp->isp_loaded_fw) { - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_VERIFY_CHECKSUM; if (IS_24XX(isp)) { mbs.param[1] = code_org >> 16; @@ -980,9 +997,7 @@ isp_reset(ispsoftc_t *isp) */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.timeout = 1000000; - mbs.param[0] = MBOX_EXEC_FIRMWARE; + MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000); if (IS_24XX(isp)) { mbs.param[1] = code_org >> 16; mbs.param[2] = code_org; @@ -1001,8 +1016,6 @@ isp_reset(ispsoftc_t *isp) } else { mbs.param[1] = code_org; } - - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (IS_2322(isp) || IS_24XX(isp)) { if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -1016,7 +1029,7 @@ isp_reset(ispsoftc_t *isp) * Give the 24XX more time. */ if (IS_24XX(isp)) { - USEC_DELAY(500000); + ISP_DELAY(500000); /* * Check to see if the 24XX firmware really started. */ @@ -1026,7 +1039,7 @@ isp_reset(ispsoftc_t *isp) return; } } else { - USEC_DELAY(250000); + ISP_DELAY(250000); if (IS_SCSI(isp)) { /* * Set CLOCK RATE, but only if asked to. @@ -1045,9 +1058,7 @@ isp_reset(ispsoftc_t *isp) * Ask the chip for the current firmware version. * This should prove that the new firmware is working. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_ABOUT_FIRMWARE; - mbs.logval = MBLOGALL; + MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { ISP_RESET0(isp); @@ -1109,9 +1120,7 @@ isp_reset(ispsoftc_t *isp) } if (!IS_24XX(isp)) { - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_FIRMWARE_STATUS; - mbs.logval = MBLOGALL; + MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { ISP_RESET0(isp); @@ -1229,13 +1238,11 @@ isp_scsi_init(ispsoftc_t *isp) * Set Retry Delay and Count. * You set both channels at the same time. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_RETRY_COUNT; + MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0); mbs.param[1] = sdp_chan0->isp_retry_count; mbs.param[2] = sdp_chan0->isp_retry_delay; mbs.param[6] = sdp_chan1->isp_retry_count; mbs.param[7] = sdp_chan1->isp_retry_delay; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1244,11 +1251,9 @@ isp_scsi_init(ispsoftc_t *isp) /* * Set ASYNC DATA SETUP time. This is very important. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; + MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0); mbs.param[1] = sdp_chan0->isp_async_data_setup; mbs.param[2] = sdp_chan1->isp_async_data_setup; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1257,15 +1262,13 @@ isp_scsi_init(ispsoftc_t *isp) /* * Set ACTIVE Negation State. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_ACT_NEG_STATE; + MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0); mbs.param[1] = (sdp_chan0->isp_req_ack_active_neg << 4) | (sdp_chan0->isp_data_line_active_neg << 5); mbs.param[2] = (sdp_chan1->isp_req_ack_active_neg << 4) | (sdp_chan1->isp_data_line_active_neg << 5); - mbs.logval = MBLOGNONE; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGERR, @@ -1282,11 +1285,9 @@ isp_scsi_init(ispsoftc_t *isp) /* * Set the Tag Aging limit */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT; + MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0); mbs.param[1] = sdp_chan0->isp_tag_aging; mbs.param[2] = sdp_chan1->isp_tag_aging; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)", @@ -1297,11 +1298,9 @@ isp_scsi_init(ispsoftc_t *isp) /* * Set selection timeout. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_SELECT_TIMEOUT; + MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0); mbs.param[1] = sdp_chan0->isp_selection_timeout; mbs.param[2] = sdp_chan1->isp_selection_timeout; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1317,56 +1316,48 @@ isp_scsi_init(ispsoftc_t *isp) */ if (IS_ULTRA2(isp) || IS_1240(isp)) { - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_RES_QUEUE_A64; + MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0); mbs.param[1] = RESULT_QUEUE_LEN(isp); mbs.param[2] = DMA_WD1(isp->isp_result_dma); mbs.param[3] = DMA_WD0(isp->isp_result_dma); mbs.param[4] = 0; mbs.param[6] = DMA_WD3(isp->isp_result_dma); mbs.param[7] = DMA_WD2(isp->isp_result_dma); - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; } isp->isp_residx = mbs.param[5]; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64; + MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0); mbs.param[1] = RQUEST_QUEUE_LEN(isp); mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); mbs.param[5] = 0; mbs.param[6] = DMA_WD3(isp->isp_result_dma); mbs.param[7] = DMA_WD2(isp->isp_result_dma); - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; } isp->isp_reqidx = isp->isp_reqodx = mbs.param[4]; } else { - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_RES_QUEUE; + MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0); mbs.param[1] = RESULT_QUEUE_LEN(isp); mbs.param[2] = DMA_WD1(isp->isp_result_dma); mbs.param[3] = DMA_WD0(isp->isp_result_dma); mbs.param[4] = 0; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; } isp->isp_residx = mbs.param[5]; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_REQ_QUEUE; + MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0); mbs.param[1] = RQUEST_QUEUE_LEN(isp); mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); mbs.param[5] = 0; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1383,9 +1374,7 @@ isp_scsi_init(ispsoftc_t *isp) * to assume not for them. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_FW_FEATURES; - mbs.param[1] = 0; + MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0); if (IS_ULTRA2(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; #ifndef ISP_NO_RIO @@ -1397,7 +1386,6 @@ isp_scsi_init(ispsoftc_t *isp) #endif if (mbs.param[1] != 0) { uint16_t sfeat = mbs.param[1]; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGINFO, @@ -1420,10 +1408,8 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan) /* * Set (possibly new) Initiator ID. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_INIT_SCSI_ID; + MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0); mbs.param[1] = (chan << 7) | sdp->isp_initiator_id; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1465,8 +1451,7 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan) */ sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT; #endif - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_TARGET_PARAMS; + MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0); mbs.param[1] = (chan << 15) | (tgt << 8); mbs.param[2] = sdf; if ((sdf & DPARM_SYNC) == 0) { @@ -1480,16 +1465,13 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan) "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x", chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff); - mbs.logval = MBLOGNONE; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { sdf = DPARM_SAFE_DFLT; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_TARGET_PARAMS; + MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0); mbs.param[1] = (tgt << 8) | (chan << 15); mbs.param[2] = sdf; mbs.param[3] = 0; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { continue; @@ -1509,12 +1491,10 @@ isp_scsi_channel_init(ispsoftc_t *isp, int chan) */ sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING; for (lun = 0; lun < (int) isp->isp_maxluns; lun++) { - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; + MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0); mbs.param[1] = (chan << 15) | (tgt << 8) | lun; mbs.param[2] = sdp->isp_max_queue_depth; mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { break; @@ -1550,7 +1530,7 @@ isp_fibre_init(ispsoftc_t *isp) return; } - MEMZERO(icbp, sizeof (*icbp)); + ISP_MEMZERO(icbp, sizeof (*icbp)); icbp->icb_version = ICB_VERSION1; icbp->icb_fwoptions = fcp->isp_fwoptions; @@ -1718,12 +1698,10 @@ isp_fibre_init(ispsoftc_t *isp) * Turn on generate AE 8013 on all LIP Resets (2) * Disable LIP F7 switching (8) */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; + MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0); mbs.param[1] = 0xb; mbs.param[2] = 0; mbs.param[3] = 0; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1783,14 +1761,12 @@ isp_fibre_init(ispsoftc_t *isp) /* * Init the firmware */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_FIRMWARE; + MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000); mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); mbs.logval = MBLOGALL; - mbs.timeout = 30 * 1000000; isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)", fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32), (uint32_t) fcp->isp_scdma); @@ -1851,16 +1827,14 @@ isp_fibre_init_2400(ispsoftc_t *isp) /* * Turn on LIP F8 async event (1) */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS; + MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0); mbs.param[1] = 1; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; } - MEMZERO(icbp, sizeof (*icbp)); + ISP_MEMZERO(icbp, sizeof (*icbp)); icbp->icb_fwoptions1 = fcp->isp_fwoptions; if (fcp->role & ISP_ROLE_TARGET) { icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE; @@ -1896,10 +1870,8 @@ isp_fibre_init_2400(ispsoftc_t *isp) /* * Get current resource count */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_RESOURCE_COUNT; + MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0); mbs.obits = 0x4cf; - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -2065,7 +2037,7 @@ isp_fibre_init_2400(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, sacq); return; } - MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN); + ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN); isp_put_icb_2400(isp, icbp, fcp->isp_scratch); /* @@ -2087,7 +2059,7 @@ isp_fibre_init_2400(ispsoftc_t *isp) for (chan = 1; chan < isp->isp_nchan; chan++) { fcparam *fcp2; - MEMZERO(&pi, sizeof (pi)); + ISP_MEMZERO(&pi, sizeof (pi)); fcp2 = FCPARAM(isp, chan); if (fcp2->role != ISP_ROLE_NONE) { pi.vp_port_options = ICB2400_VPOPT_ENABLED; @@ -2115,7 +2087,7 @@ isp_fibre_init_2400(ispsoftc_t *isp) /* * Init the firmware */ - MEMZERO(&mbs, sizeof (mbs)); + MBSINIT(&mbs, 0, MBLOGALL, 30000000); if (nchan > 1) { mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID; } else { @@ -2125,8 +2097,6 @@ isp_fibre_init_2400(ispsoftc_t *isp) mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.logval = MBLOGALL; - mbs.timeout = 30 * 1000000; isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma)); @@ -2154,38 +2124,33 @@ isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition) int i; if (chan < 0 || chan >= isp->isp_nchan) { - isp_prt(isp, ISP_LOGWARN, - "isp_mark_portdb: bad channel %d", chan); + isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan); return; } for (i = 0; i < MAX_FC_TARG; i++) { if (fcp->portdb[i].target_mode) { if (disposition < 0) { - isp_prt(isp, ISP_LOGTINFO, - "isp_mark_portdb: Chan %d zeroing handle 0x" - "%02x port 0x%06x", chan, - fcp->portdb[i].handle, - fcp->portdb[i].portid); - MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); + isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%02x port 0x%06x", chan, + fcp->portdb[i].handle, fcp->portdb[i].portid); + ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); } continue; } if (disposition == 0) { - MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); + ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); } else { switch (fcp->portdb[i].state) { case FC_PORTDB_STATE_CHANGED: case FC_PORTDB_STATE_PENDING_VALID: case FC_PORTDB_STATE_VALID: case FC_PORTDB_STATE_PROBATIONAL: - fcp->portdb[i].state = - FC_PORTDB_STATE_PROBATIONAL; + fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL; break; case FC_PORTDB_STATE_ZOMBIE: break; case FC_PORTDB_STATE_NIL: default: - MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); + ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); fcp->portdb[i].state = FC_PORTDB_STATE_NIL; break; } @@ -2222,7 +2187,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, } } - MEMZERO(q, QENTRY_LEN); + ISP_MEMZERO(q, QENTRY_LEN); plp = (isp_plogx_t *) q; plp->plogx_header.rqs_entry_count = 1; plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN; @@ -2247,16 +2212,12 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, scp = fcp->isp_scratch; isp_put_plogx(isp, plp, (isp_plogx_t *) scp); - - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000); mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.timeout = 500000; - mbs.logval = MBLOGALL; MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -2299,7 +2260,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, msg = "no Exchange Control Block"; break; case PLOGX_IOCBERR_FAILED: - SNPRINTF(buf, sizeof (buf), + ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff); msg = buf; @@ -2311,33 +2272,33 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, msg = "firmware not ready"; break; case PLOGX_IOCBERR_NOLOGIN: - SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", + ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1); msg = buf; rval = MBOX_NOT_LOGGED_IN; break; case PLOGX_IOCBERR_REJECT: - SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1); + ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1); msg = buf; break; case PLOGX_IOCBERR_NOPCB: msg = "no PCB allocated"; break; case PLOGX_IOCBERR_EINVAL: - SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", + ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1); msg = buf; break; case PLOGX_IOCBERR_PORTUSED: lev = ISP_LOGSANCFG|ISP_LOGDEBUG0; - SNPRINTF(buf, sizeof (buf), + ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1); msg = buf; rval = MBOX_PORT_ID_USED | (parm1 << 16); break; case PLOGX_IOCBERR_HNDLUSED: lev = ISP_LOGSANCFG|ISP_LOGDEBUG0; - SNPRINTF(buf, sizeof (buf), + ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1); msg = buf; rval = MBOX_LOOP_ID_USED; @@ -2349,7 +2310,7 @@ isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, msg = "no FLOGI_ACC"; break; default: - SNPRINTF(buf, sizeof (buf), "status %x from %x", + ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags); msg = buf; break; @@ -2371,8 +2332,7 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid) { mbreg_t mbs; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_FABRIC_LOGIN; + MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000); if (ISP_CAP_2KLOGIN(isp)) { mbs.param[1] = handle; mbs.ibits = (1 << 10); @@ -2425,16 +2385,13 @@ isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid) { mbreg_t mbs; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_FABRIC_LOGOUT; + MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000); if (ISP_CAP_2KLOGIN(isp)) { mbs.param[1] = handle; mbs.ibits = (1 << 10); } else { mbs.param[1] = handle << 8; } - mbs.logval = MBLOGNONE; - mbs.timeout = 100000; isp_mboxcmd(isp, &mbs); return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]); } @@ -2449,8 +2406,7 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock) isp_pdb_24xx_t bill; } un; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_PORT_DB; + MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000); if (IS_24XX(isp)) { mbs.ibits = (1 << 9)|(1 << 10); mbs.param[1] = id; @@ -2464,8 +2420,6 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock) mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.timeout = 250000; - mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR; if (dolock) { if (FC_SCRATCH_ACQUIRE(isp, chan)) { isp_prt(isp, ISP_LOGERR, sacq); @@ -2485,13 +2439,13 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock) pdb->handle = un.bill.pdb_handle; pdb->s3_role = un.bill.pdb_prli_svc3; pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits); - MEMCPY(pdb->portname, un.bill.pdb_portname, 8); - MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8); + ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8); + ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8); isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Port 0x%06x flags 0x%x curstate %x", chan, pdb->portid, un.bill.pdb_flags, un.bill.pdb_curstate); - if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE && + if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) { mbs.param[0] = MBOX_NOT_LOGGED_IN; if (dolock) { @@ -2504,8 +2458,8 @@ isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock) pdb->handle = un.fred.pdb_loopid; pdb->s3_role = un.fred.pdb_prli_svc3; pdb->portid = BITS2WORD(un.fred.pdb_portid_bits); - MEMCPY(pdb->portname, un.fred.pdb_portname, 8); - MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8); + ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8); + ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8); } if (dolock) { FC_SCRATCH_RELEASE(isp, chan); @@ -2547,8 +2501,7 @@ isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename) fcp->isp_loopstate < LOOP_PDB_RCVD) { return (wwn); } - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_PORT_NAME; + MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000); if (ISP_CAP_2KLOGIN(isp)) { mbs.param[1] = loopid; mbs.ibits = (1 << 10); @@ -2565,7 +2518,6 @@ isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename) mbs.param[1] |= 1; } } - mbs.logval = MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return (wwn); @@ -2670,12 +2622,12 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) count += 1000; enano = (1000 * 1000) - enano; while (enano > (uint64_t) 4000000000U) { - USEC_SLEEP(isp, 4000000); + ISP_SLEEP(isp, 4000000); enano -= (uint64_t) 4000000000U; } wrk = enano; wrk /= 1000; - USEC_SLEEP(isp, wrk); + ISP_SLEEP(isp, wrk); } else { while (enano > (uint64_t) 4000000000U) { count += 4000000; @@ -2700,14 +2652,12 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) /* * Get our Loop ID and Port ID. */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_LOOP_ID; + MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0); if (ISP_CAP_MULTI_ID(isp)) { mbs.param[9] = chan; mbs.ibits = (1 << 9); mbs.obits = (1 << 7); } - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return (-1); @@ -2740,8 +2690,7 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) } else { check_for_fabric = 0; } - } else if (fcp->isp_topo == TOPO_FL_PORT || - fcp->isp_topo == TOPO_F_PORT) { + } else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) { check_for_fabric = 1; } else { check_for_fabric = 0; @@ -2749,17 +2698,14 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) /* * Check to make sure we got a valid loopid - * The 24XX seems to mess this up for multiple - * channels. + * The 24XX seems to mess this up for multiple channels. */ - if (fcp->isp_topo == TOPO_FL_PORT || - fcp->isp_topo == TOPO_NL_PORT) { + if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) { uint8_t alpa = fcp->isp_portid; if (alpa == 0) { /* "Cannot Happen" */ - isp_prt(isp, ISP_LOGWARN, - "Zero AL_PA for Loop Topology?"); + isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?"); } else { int i; for (i = 0; alpa_map[i]; i++) { @@ -2786,10 +2732,8 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) } if (check_for_fabric) { r = isp_getpdb(isp, chan, loopid, &pdb, 1); - if (r && (fcp->isp_topo == TOPO_F_PORT || - fcp->isp_topo == TOPO_FL_PORT)) { - isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot " - "get info about fabric controller (0x%x)", r); + if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) { + isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r); fcp->isp_topo = TOPO_PTP_STUB; } } else { @@ -2850,7 +2794,7 @@ isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay) r = isp_register_fc4_type(isp, chan); } if (r) { - isp_prt(isp, ISP_LOGSANCFG, + isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "isp_fclink_test: register fc4 type failed"); return (-1); } @@ -2861,12 +2805,9 @@ not_on_fabric: fcp->isp_gbspeed = 1; if (IS_23XX(isp) || IS_24XX(isp)) { - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_SET_DATA_RATE; + MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000); mbs.param[1] = MBGSD_GET_RATE; /* mbs.param[2] undefined if we're just getting rate */ - mbs.logval = MBLOGALL; - mbs.timeout = 3000000; isp_mboxcmd(isp, &mbs); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { if (mbs.param[1] == MBGSD_FOURGB) { @@ -3001,7 +2942,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) case FC_PORTDB_STATE_PROBATIONAL: case FC_PORTDB_STATE_DEAD: /* - * It's up to the outer layers to clear isp_ini_map. + * It's up to the outer layers to clear isp_dev_map. */ lp->state = FC_PORTDB_STATE_NIL; isp_async(isp, ISPASYNC_DEV_GONE, chan, lp); @@ -3024,7 +2965,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) case FC_PORTDB_STATE_NEW: /* * It's up to the outer layers to assign a virtual - * target id in isp_ini_map (if any). + * target id in isp_dev_map (if any). */ lp->portid = lp->new_portid; lp->roles = lp->new_roles; @@ -3049,9 +2990,9 @@ isp_pdb_sync(ispsoftc_t *isp, int chan) case FC_PORTDB_STATE_PENDING_VALID: lp->portid = lp->new_portid; lp->roles = lp->new_roles; - if (lp->ini_map_idx) { - int t = lp->ini_map_idx - 1; - fcp->isp_ini_map[t] = dbidx + 1; + if (lp->dev_map_idx) { + int t = lp->dev_map_idx - 1; + fcp->isp_dev_map[t] = dbidx + 1; } lp->state = FC_PORTDB_STATE_VALID; isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp); @@ -3350,7 +3291,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan) } lp = &fcp->portdb[i]; - MEMZERO(lp, sizeof (fcportdb_t)); + ISP_MEMZERO(lp, sizeof (fcportdb_t)); lp->autologin = 1; lp->state = FC_PORTDB_STATE_NEW; lp->new_portid = tmp.portid; @@ -3410,7 +3351,7 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan) isp_prt(isp, ISP_LOGDEBUG0, "Chan %d scanning fabric (GID_FT) via SNS", chan); - MEMZERO(rq, SNS_GID_FT_REQ_SIZE); + ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE); rq->snscb_rblen = GIDLEN >> 1; rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF); rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF); @@ -3424,15 +3365,13 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan) isp_put_gid_ft_request(isp, rq, fcp->isp_scratch); MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE); - MEMZERO(&mbs, sizeof (mbs)); + MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000); mbs.param[0] = MBOX_SEND_SNS; mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.logval = MBLOGALL; - mbs.timeout = 10000000; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { if (mbs.param[0] == MBOX_INVALID_COMMAND) { @@ -3470,7 +3409,7 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan) * Build a Passthrough IOCB in memory. */ pt = &un.plocal; - MEMZERO(un.q, QENTRY_LEN); + ISP_MEMZERO(un.q, QENTRY_LEN); pt->ctp_header.rqs_entry_count = 1; pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; pt->ctp_handle = 0xffffffff; @@ -3498,7 +3437,7 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan) * Note that the CT header has to end up as Big Endian format in memory. */ ct = &un.clocal; - MEMZERO(ct, sizeof (*ct)); + ISP_MEMZERO(ct, sizeof (*ct)); ct->ct_revision = CT_REVISION; ct->ct_fcs_type = CT_FC_TYPE_FC; ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS; @@ -3512,16 +3451,13 @@ isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan) isp_print_bytes(isp, "CT HDR + payload after put", sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]); } - MEMZERO(&scp[ZTXOFF], QENTRY_LEN); - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN); + MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000); mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); - mbs.timeout = 500000; - mbs.logval = MBLOGALL; MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -4025,7 +3961,7 @@ isp_scan_fabric(ispsoftc_t *isp, int chan) } if (dbidx == MAX_FC_TARG) { - MEMZERO(lp, sizeof (fcportdb_t)); + ISP_MEMZERO(lp, sizeof (fcportdb_t)); lp->handle = handle; lp->node_wwn = wwnn; lp->port_wwn = wwpn; @@ -4182,7 +4118,7 @@ isp_register_fc4_type(ispsoftc_t *isp, int chan) sns_screq_t *reqp = (sns_screq_t *) local; mbreg_t mbs; - MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); + ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE); reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1; reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); @@ -4198,15 +4134,12 @@ isp_register_fc4_type(ispsoftc_t *isp, int chan) return (-1); } isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch); - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_SEND_SNS; + MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000); mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.logval = MBLOGALL; - mbs.timeout = 10000000; MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE); isp_mboxcmd(isp, &mbs); FC_SCRATCH_RELEASE(isp, chan); @@ -4240,7 +4173,7 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) /* * Build a Passthrough IOCB in memory. */ - MEMZERO(un.q, QENTRY_LEN); + ISP_MEMZERO(un.q, QENTRY_LEN); pt = &un.plocal; pt->ctp_header.rqs_entry_count = 1; pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; @@ -4268,7 +4201,7 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) * * Note that the CT header has to end up as Big Endian format in memory. */ - MEMZERO(&un.clocal, sizeof (un.clocal)); + ISP_MEMZERO(&un.clocal, sizeof (un.clocal)); ct = &un.clocal.rftid_hdr; ct->ct_revision = CT_REVISION; ct->ct_fcs_type = CT_FC_TYPE_FC; @@ -4285,17 +4218,14 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]); } - MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t)); + ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t)); - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000); mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); - mbs.timeout = 500000; - mbs.logval = MBLOGALL; MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -4447,7 +4377,7 @@ isp_start(XS_T *xs) return (CMD_COMPLETE); } - hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1; + hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1; isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx); if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) { @@ -4490,14 +4420,14 @@ isp_start(XS_T *xs) if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) { if (IS_24XX(isp)) { isp_marker_24xx_t *m = (isp_marker_24xx_t *) qep; - MEMZERO(m, QENTRY_LEN); + ISP_MEMZERO(m, QENTRY_LEN); m->mrk_header.rqs_entry_count = 1; m->mrk_header.rqs_entry_type = RQSTYPE_MARKER; m->mrk_modifier = SYNC_ALL; isp_put_marker_24xx(isp, m, (isp_marker_24xx_t *)qep); } else { isp_marker_t *m = (isp_marker_t *) qep; - MEMZERO(m, QENTRY_LEN); + ISP_MEMZERO(m, QENTRY_LEN); m->mrk_header.rqs_entry_count = 1; m->mrk_header.rqs_entry_type = RQSTYPE_MARKER; m->mrk_target = (XS_CHANNEL(xs) << 7); /* bus # */ @@ -4509,7 +4439,7 @@ isp_start(XS_T *xs) goto start_again; } - MEMZERO((void *)reqp, QENTRY_LEN); + ISP_MEMZERO((void *)reqp, QENTRY_LEN); reqp->req_header.rqs_entry_count = 1; if (IS_24XX(isp)) { reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS; @@ -4604,7 +4534,7 @@ isp_start(XS_T *xs) ((ispreqt2_t *)reqp)->req_target = target; ((ispreqt2_t *)reqp)->req_lun_trn = XS_LUN(xs); } - MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs)); + ISP_MEMCPY(cdbp, XS_CDBP(xs), XS_CDBLEN(xs)); *tptr = XS_TIME(xs) / 1000; if (*tptr == 0 && XS_TIME(xs)) { @@ -4659,8 +4589,6 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) uint32_t handle; va_list ap; - MEMZERO(&mbs, sizeof (mbs)); - switch (ctl) { case ISPCTL_RESET_BUS: /* @@ -4682,9 +4610,8 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) } mbs.param[2] = chan; } - mbs.param[0] = MBOX_BUS_RESET; + MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0); ISP_SET_SENDMARKER(isp, chan, 1); - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { break; @@ -4706,7 +4633,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) fcportdb_t *lp; int hdlidx; - hdlidx = fcp->isp_ini_map[tgt] - 1; + hdlidx = fcp->isp_dev_map[tgt] - 1; if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) { isp_prt(isp, ISP_LOGWARN, "Chan %d bad handle %d trying to reset" @@ -4723,7 +4650,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) } tmf = (isp24xx_tmf_t *) local; - MEMZERO(tmf, QENTRY_LEN); + ISP_MEMZERO(tmf, QENTRY_LEN); tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT; tmf->tmf_header.rqs_entry_count = 1; tmf->tmf_nphdl = lp->handle; @@ -4736,15 +4663,12 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid); - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000); mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.timeout = 5000000; - mbs.logval = MBLOGALL; if (FC_SCRATCH_ACQUIRE(isp, chan)) { isp_prt(isp, ISP_LOGERR, sacq); @@ -4781,9 +4705,8 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) } else { mbs.param[1] = (chan << 15) | (tgt << 8); } - mbs.param[0] = MBOX_ABORT_TARGET; + MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0); mbs.param[2] = 3; /* 'delay', in seconds */ - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { break; @@ -4814,7 +4737,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) int hdlidx; fcp = FCPARAM(isp, chan); - hdlidx = fcp->isp_ini_map[tgt] - 1; + hdlidx = fcp->isp_dev_map[tgt] - 1; if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) { isp_prt(isp, ISP_LOGWARN, "Chan %d bad handle %d trying to abort" @@ -4831,7 +4754,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port " "0x%06x %p", chan, lp->handle, lp->portid, xs); - MEMZERO(ab, QENTRY_LEN); + ISP_MEMZERO(ab, QENTRY_LEN); ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO; ab->abrt_header.rqs_entry_count = 1; ab->abrt_handle = lp->handle; @@ -4840,15 +4763,13 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) ab->abrt_tidhi = lp->portid >> 16; ab->abrt_vpidx = chan; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; + ISP_MEMZERO(&mbs, sizeof (mbs)); + MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000); mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma); mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[6] = DMA_WD3(fcp->isp_scdma); mbs.param[7] = DMA_WD2(fcp->isp_scdma); - mbs.timeout = 5000000; - mbs.logval = MBLOGALL; if (FC_SCRATCH_ACQUIRE(isp, chan)) { isp_prt(isp, ISP_LOGERR, sacq); @@ -4889,9 +4810,8 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) } else { mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs); } - mbs.param[0] = MBOX_ABORT; + MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0); mbs.param[2] = handle; - mbs.logval = MBLOGALL & ~MBOX_COMMAND_ERROR; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { break; @@ -4954,11 +4874,10 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) case ISPCTL_SEND_LIP: if (IS_FC(isp) && !IS_24XX(isp)) { - mbs.param[0] = MBOX_INIT_LIP; + MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0); if (ISP_CAP_2KLOGIN(isp)) { mbs.ibits = (1 << 10); } - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { return (0); @@ -5085,8 +5004,7 @@ again: if ((obits & (1 << i)) == 0) { continue; } - isp->isp_mboxtmp[i] = - ISP_READ(isp, MBOX_OFF(i)); + isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i)); } if (isp->isp_mbxwrk0) { if (isp_mbox_continue(isp) == 0) { @@ -5095,14 +5013,12 @@ again: } MBOX_NOTIFY_COMPLETE(isp); } else { - isp_prt(isp, ISP_LOGWARN, - "mailbox cmd (0x%x) with no waiters", mbox); + isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox); } } else if (isp_parse_async(isp, mbox) < 0) { return; } - if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || - isp->isp_state != ISP_RUNSTATE) { + if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || isp->isp_state != ISP_RUNSTATE) { goto out; } } @@ -5114,17 +5030,14 @@ again: /* * This seems to happen to 23XX and 24XX cards- don't know why. */ - if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == - MBOX_ABOUT_FIRMWARE) { + if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) { goto fmbox; } - isp_prt(isp, ISP_LOGINFO, - "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema); + isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema); /* * Thank you very much! *Burrrp*! */ - ISP_WRITE(isp, isp->isp_respoutrp, - ISP_READ(isp, isp->isp_respinrp)); + ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp)); if (IS_24XX(isp)) { ISP_DISABLE_INTS(isp); } @@ -5156,8 +5069,7 @@ again: (void) isp_target_notify(isp, addr, &oop); break; default: - isp_print_qentry(isp, "?ATIOQ entry?", - oop, addr); + isp_print_qentry(isp, "?ATIOQ entry?", oop, addr); break; } optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp)); @@ -5178,9 +5090,7 @@ again: * Debug: to be taken out eventually */ if (isp->isp_residx != optr) { - isp_prt(isp, ISP_LOGINFO, - "isp_intr: hard optr=%x, soft optr %x", - optr, isp->isp_residx); + isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx); isp->isp_residx = optr; } } else { @@ -5201,9 +5111,7 @@ again: } while (junk != iptr && ++i < 1000); if (iptr != junk) { - isp_prt(isp, ISP_LOGWARN, - "Response Queue Out Pointer Unstable (%x, %x)", - iptr, junk); + isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk); goto out; } } else { @@ -5224,7 +5132,7 @@ again: if (IS_24XX(isp)) { junk = 0; } else if (IS_23XX(isp)) { - USEC_DELAY(100); + ISP_DELAY(100); iptr = ISP_READ(isp, isp->isp_respinrp); junk = ISP_READ(isp, BIU_R2HSTSLO); } else { @@ -5241,9 +5149,7 @@ again: } } isp->isp_intbogus++; - isp_prt(isp, ISP_LOGDEBUG1, - "bogus intr- isr %x (%x) iptr %x optr %x", - isr, junk, iptr, optr); + isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr); } } isp->isp_resodx = iptr; @@ -5276,11 +5182,9 @@ again: if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) { isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe; - isp_get_24xx_response(isp, - (isp24xx_statusreq_t *)hp, sp2); + isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2); if (isp->isp_dblev & ISP_LOGDEBUG1) { - isp_print_bytes(isp, - "Response Queue Entry", QENTRY_LEN, sp2); + isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2); } scsi_status = sp2->req_scsi_status; completion_status = sp2->req_completion_status; @@ -5289,8 +5193,7 @@ again: } else if (etype == RQSTYPE_RESPONSE) { isp_get_response(isp, (ispstatusreq_t *) hp, sp); if (isp->isp_dblev & ISP_LOGDEBUG1) { - isp_print_bytes(isp, - "Response Queue Entry", QENTRY_LEN, sp); + isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp); } scsi_status = sp->req_scsi_status; completion_status = sp->req_completion_status; @@ -5301,17 +5204,15 @@ again: isp_rio2_t *rio = (isp_rio2_t *)qe; isp_get_rio2(isp, (isp_rio2_t *) hp, rio); if (isp->isp_dblev & ISP_LOGDEBUG1) { - isp_print_bytes(isp, - "Response Queue Entry", QENTRY_LEN, rio); + isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio); } for (i = 0; i < rio->req_header.rqs_seqno; i++) { isp_fastpost_complete(isp, rio->req_handles[i]); } if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) { - isp->isp_fpcchiwater = - rio->req_header.rqs_seqno; + isp->isp_fpcchiwater = rio->req_header.rqs_seqno; } - MEMZERO(hp, QENTRY_LEN); /* PERF */ + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; } else { /* @@ -5335,7 +5236,7 @@ again: } if (r > 0) { ISP_WRITE(isp, isp->isp_respoutrp, optr); - MEMZERO(hp, QENTRY_LEN); /* PERF */ + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; } @@ -5355,7 +5256,7 @@ again: etype, oop, optr, nlooked); isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, sp); - MEMZERO(hp, QENTRY_LEN); /* PERF */ + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ continue; } buddaboom = 1; @@ -5368,36 +5269,38 @@ again: if (sp->req_header.rqs_flags & RQSFLAG_MASK) { if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) { - isp_prt(isp, ISP_LOGWARN, - "continuation segment"); + isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp); ISP_WRITE(isp, isp->isp_respoutrp, optr); continue; } if (sp->req_header.rqs_flags & RQSFLAG_FULL) { - isp_prt(isp, ISP_LOGDEBUG1, - "internal queues full"); + isp_prt(isp, ISP_LOGDEBUG0, "internal queues full"); /* * We'll synthesize a QUEUE FULL message below. */ } if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) { - isp_print_bytes(isp, "bad header flag", - QENTRY_LEN, sp); + isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp); buddaboom++; } if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) { - isp_print_bytes(isp, "bad request packet", - QENTRY_LEN, sp); + isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp); buddaboom++; } + if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) { + isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp); + buddaboom++; + } + if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) { + isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp); + ISP_WRITE(isp, isp->isp_respoutrp, optr); + continue; + } } - if ((sp->req_handle != ISP_SPCL_HANDLE) && - (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) { - isp_prt(isp, ISP_LOGERR, - "bad request handle %d (type 0x%x)", - sp->req_handle, etype); - MEMZERO(hp, QENTRY_LEN); /* PERF */ + if ((sp->req_handle != ISP_SPCL_HANDLE) && (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) { + isp_prt(isp, ISP_LOGERR, "bad request handle %d (type 0x%x)", sp->req_handle, etype); + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ ISP_WRITE(isp, isp->isp_respoutrp, optr); continue; } @@ -5409,17 +5312,11 @@ again: * aborting the command or resetting the target. */ if (etype != RQSTYPE_RESPONSE) { - isp_prt(isp, ISP_LOGERR, - "cannot find handle 0x%x (type 0x%x)", - sp->req_handle, etype); - } else if (ts != RQCS_ABORTED && - ts != RQCS_RESET_OCCURRED && - sp->req_handle != ISP_SPCL_HANDLE) { - isp_prt(isp, ISP_LOGERR, - "cannot find handle 0x%x (status 0x%x)", - sp->req_handle, ts); + isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype); + } else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED && sp->req_handle != ISP_SPCL_HANDLE) { + isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts); } - MEMZERO(hp, QENTRY_LEN); /* PERF */ + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ ISP_WRITE(isp, isp->isp_respoutrp, optr); continue; } @@ -5451,11 +5348,9 @@ again: */ req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE; if (IS_24XX(isp)) { - snsp = - ((isp24xx_statusreq_t *)sp)->req_rsp_sense; + snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense; snsp += rlen; - slen = - ((isp24xx_statusreq_t *)sp)->req_sense_len; + slen = ((isp24xx_statusreq_t *)sp)->req_sense_len; } else { snsp = sp->req_sense_data; slen = sp->req_sense_len; @@ -5470,22 +5365,16 @@ again: switch (etype) { case RQSTYPE_RESPONSE: - if (resp && rlen >= 4 && - resp[FCP_RSPNS_CODE_OFFSET] != 0) { - isp_prt(isp, ISP_LOGWARN, - "%d.%d.%d FCP RESPONSE: 0x%x", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), - resp[FCP_RSPNS_CODE_OFFSET]); + if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) { + isp_prt(isp, ISP_LOGWARN, "%d.%d.%d FCP RESPONSE: 0x%x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), resp[FCP_RSPNS_CODE_OFFSET]); XS_SETERR(xs, HBA_BOTCH); } if (IS_24XX(isp)) { - isp_parse_status_24xx(isp, - (isp24xx_statusreq_t *)sp, xs, &resid); + isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid); } else { isp_parse_status(isp, (void *)sp, xs, &resid); } - if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && - (*XS_STSP(xs) == SCSI_BUSY)) { + if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) { XS_SETERR(xs, HBA_TGTBSY); } if (IS_SCSI(isp)) { @@ -5497,8 +5386,7 @@ again: */ if (req_status_flags & RQSTF_NEGOTIATION) { int t = XS_TGT(xs); - sdparam *sdp = - SDPARAM(isp, XS_CHANNEL(xs)); + sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs)); sdp->isp_devparam[t].dev_refresh = 1; sdp->update = 1; } @@ -5513,39 +5401,30 @@ again: } if (snsp && slen) { XS_SAVE_SENSE(xs, snsp, slen); + } else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) { + isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff); + isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe); } - isp_prt(isp, ISP_LOGDEBUG2, - "asked for %ld got raw resid %ld settled for %ld", - (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs)); + isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs)); break; case RQSTYPE_REQUEST: case RQSTYPE_A64: case RQSTYPE_T2RQS: case RQSTYPE_T3RQS: case RQSTYPE_T7RQS: - if (sp->req_header.rqs_flags & RQSFLAG_FULL) { + if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) { /* * Force Queue Full status. */ *XS_STSP(xs) = SCSI_QFULL; XS_SETERR(xs, HBA_NOERROR); } else if (XS_NOERR(xs)) { - /* - * ???? - */ XS_SETERR(xs, HBA_BOTCH); - isp_prt(isp, ISP_LOGDEBUG0, - "Request Queue Entry bounced back"); - if ((isp->isp_dblev & ISP_LOGDEBUG1) == 0) { - isp_print_bytes(isp, "Bounced Request", - QENTRY_LEN, qe); - } } XS_SET_RESID(xs, XS_XFRLEN(xs)); break; default: - isp_print_bytes(isp, "Unhandled Response Type", - QENTRY_LEN, qe); + isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BOTCH); } @@ -5584,7 +5463,7 @@ again: isp->isp_nactive--; } complist[ndone++] = xs; /* defer completion call until later */ - MEMZERO(hp, QENTRY_LEN); /* PERF */ + ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */ if (ndone == MAX_REQUESTQ_COMPLETIONS) { break; } @@ -6247,7 +6126,7 @@ isp_handle_other_response(ispsoftc_t *isp, int type, /* FALLTHROUGH */ case RQSTYPE_REQUEST: default: - USEC_DELAY(100); + ISP_DELAY(100); if (type != isp_get_response_type(isp, hp)) { /* * This is questionable- we're just papering over @@ -6303,52 +6182,52 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) case RQCS_TRANSPORT_ERROR: { char buf[172]; - SNPRINTF(buf, sizeof (buf), "states=>"); + ISP_SNPRINTF(buf, sizeof (buf), "states=>"); if (sp->req_state_flags & RQSF_GOT_BUS) { - SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf); } if (sp->req_state_flags & RQSF_GOT_TARGET) { - SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf); } if (sp->req_state_flags & RQSF_SENT_CDB) { - SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf); } if (sp->req_state_flags & RQSF_XFRD_DATA) { - SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf); } if (sp->req_state_flags & RQSF_GOT_STATUS) { - SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf); } if (sp->req_state_flags & RQSF_GOT_SENSE) { - SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf); } if (sp->req_state_flags & RQSF_XFER_COMPLETE) { - SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf); } - SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf); if (sp->req_status_flags & RQSTF_DISCONNECT) { - SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf); } if (sp->req_status_flags & RQSTF_SYNCHRONOUS) { - SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf); } if (sp->req_status_flags & RQSTF_PARITY_ERROR) { - SNPRINTF(buf, sizeof (buf), "%s Parity", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf); } if (sp->req_status_flags & RQSTF_BUS_RESET) { - SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf); } if (sp->req_status_flags & RQSTF_DEVICE_RESET) { - SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf); } if (sp->req_status_flags & RQSTF_ABORTED) { - SNPRINTF(buf, sizeof (buf), "%s Aborted", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf); } if (sp->req_status_flags & RQSTF_TIMEOUT) { - SNPRINTF(buf, sizeof (buf), "%s Timeout", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf); } if (sp->req_status_flags & RQSTF_NEGOTIATION) { - SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf); + ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf); } isp_prt(isp, ISP_LOGERR, "%s", buf); isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s", @@ -6615,12 +6494,10 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT || FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) { mbreg_t mbs; - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_INIT_LIP; + MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0); if (ISP_CAP_2KLOGIN(isp)) { mbs.ibits = (1 << 10); } - mbs.logval = MBLOGALL; isp_mboxcmd_qnw(isp, &mbs, 1); } if (XS_NOERR(xs)) { @@ -6896,7 +6773,7 @@ isp_mbox_continue(ispsoftc_t *isp) /* * Continue with next word. */ - MEMZERO(&mbs, sizeof (mbs)); + ISP_MEMZERO(&mbs, sizeof (mbs)); ptr = isp->isp_mbxworkp; switch (isp->isp_lastmbxcmd) { case MBOX_WRITE_RAM_WORD: @@ -7441,7 +7318,7 @@ isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay) * command. */ if (nodelay) { - USEC_DELAY(1000); + ISP_DELAY(1000); } } @@ -7550,7 +7427,7 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp) cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode]; if (cname == NULL) { cname = tname; - SNPRINTF(tname, sizeof tname, "opcode %x", opcode); + ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode); } /* @@ -7607,7 +7484,7 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp) xname = "TIMEOUT"; break; default: - SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]); + ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]); xname = mname; break; } @@ -7624,9 +7501,7 @@ isp_fw_state(ispsoftc_t *isp, int chan) mbreg_t mbs; fcparam *fcp = FCPARAM(isp, chan); - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_FW_STATE; - mbs.logval = MBLOGALL; + MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0); isp_mboxcmd(isp, &mbs); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { fcp->isp_fwstate = mbs.param[1]; @@ -7668,7 +7543,7 @@ isp_spi_update(ispsoftc_t *isp, int chan) * current device state, get the current parameters. */ - MEMZERO(&mbs, sizeof (mbs)); + MBSINIT(&mbs, 0, MBLOGALL, 0); /* * Refresh overrides set @@ -7723,7 +7598,6 @@ isp_spi_update(ispsoftc_t *isp, int chan) continue; } mbs.param[1] = (chan << 15) | (tgt << 8); - mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { continue; @@ -7867,9 +7741,7 @@ isp_setdfltsdparm(ispsoftc_t *isp) } } } - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_GET_ACT_NEG_STATE; - mbs.logval = MBLOGNONE; + MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { sdp->isp_req_ack_active_neg = 1; @@ -8040,7 +7912,7 @@ isp_reinit(ispsoftc_t *isp) isp_done(xs); } #ifdef ISP_TARGET_MODE - MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **)); + ISP_MEMZERO(isp->isp_tgtlist, isp->isp_maxcmds * sizeof (void **)); #endif } @@ -8167,9 +8039,9 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) uint16_t bit, rqst, junk; ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); - USEC_DELAY(10); + ISP_DELAY(10); ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK); - USEC_DELAY(10); + ISP_DELAY(10); if (IS_FC(isp)) { wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1); @@ -8198,13 +8070,13 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) bit = BIU_NVRAM_SELECT; } ISP_WRITE(isp, BIU_NVRAM, bit); - USEC_DELAY(10); + ISP_DELAY(10); junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK); - USEC_DELAY(10); + ISP_DELAY(10); junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_WRITE(isp, BIU_NVRAM, bit); - USEC_DELAY(10); + ISP_DELAY(10); junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ } /* @@ -8215,18 +8087,18 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) uint16_t rv; *rp <<= 1; ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK); - USEC_DELAY(10); + ISP_DELAY(10); rv = ISP_READ(isp, BIU_NVRAM); if (rv & BIU_NVRAM_DATAIN) { *rp |= 1; } - USEC_DELAY(10); + ISP_DELAY(10); ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); - USEC_DELAY(10); + ISP_DELAY(10); junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ } ISP_WRITE(isp, BIU_NVRAM, 0); - USEC_DELAY(10); + ISP_DELAY(10); junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_SWIZZLE_NVRAM_WORD(isp, rp); } @@ -8240,7 +8112,7 @@ isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp) ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr); for (loops = 0; loops < 5000; loops++) { - USEC_DELAY(10); + ISP_DELAY(10); tmp = ISP_READ(isp, BIU2400_FLASH_ADDR); if ((tmp & (1U << 31)) != 0) { break; diff --git a/qla_isp/common/isp_library.c b/qla_isp/common/isp_library.c index bca43bfa1..1af740d0c 100644 --- a/qla_isp/common/isp_library.c +++ b/qla_isp/common/isp_library.c @@ -1,4 +1,4 @@ -/* $Id: isp_library.c,v 1.51 2008/03/10 18:03:08 mjacob Exp $ */ +/* $Id: isp_library.c,v 1.55 2009/02/01 23:49:49 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -164,7 +164,7 @@ isp_getrqentry(ispsoftc_t *isp, uint32_t *iptrp, #define TBA (4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1) void -isp_print_qentry(ispsoftc_t *isp, char *msg, int idx, void *arg) +isp_print_qentry(ispsoftc_t *isp, const char *msg, int idx, void *arg) { char buf[TBA]; int amt, i, j; @@ -173,9 +173,9 @@ isp_print_qentry(ispsoftc_t *isp, char *msg, int idx, void *arg) isp_prt(isp, ISP_LOGALL, "%s index %d=>", msg, idx); for (buf[0] = 0, amt = i = 0; i < 4; i++) { buf[0] = 0; - SNPRINTF(buf, TBA, " "); + ISP_SNPRINTF(buf, TBA, " "); for (j = 0; j < (QENTRY_LEN >> 2); j++) { - SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff); + ISP_SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff); } isp_prt(isp, ISP_LOGALL, buf); } @@ -196,7 +196,7 @@ isp_print_bytes(ispsoftc_t *isp, const char *msg, int amt, void *arg) int j, to; to = off; for (j = 0; j < 16; j++) { - SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff); + ISP_SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff); if (off == amt) break; } @@ -296,14 +296,13 @@ isp_dump_portdb(ispsoftc_t *isp, int chan) }; fcportdb_t *lp = &fcp->portdb[i]; - if (lp->state == FC_PORTDB_STATE_NIL) { + if (lp->state == FC_PORTDB_STATE_NIL && lp->target_mode == 0) { continue; } - if (lp->ini_map_idx) { - SNPRINTF(mb, sizeof (mb), "%3d", - ((int) lp->ini_map_idx) - 1); + if (lp->dev_map_idx) { + ISP_SNPRINTF(mb, sizeof (mb), "%3d", ((int) lp->dev_map_idx) - 1); } else { - SNPRINTF(mb, sizeof (mb), "---"); + ISP_SNPRINTF(mb, sizeof (mb), "---"); } isp_prt(isp, ISP_LOGALL, "Chan %d [%d]: hdl 0x%x %s al%d tgt %s" " %s 0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x", @@ -1246,7 +1245,7 @@ isp_get_ridacq(ispsoftc_t *isp, isp_ridacq_t *src, isp_ridacq_t *dst) ISP_IOXGET_8(isp, &src->un.type1.ridacq_vp_status, dst->un.type1.ridacq_vp_status); } else { - MEMZERO(&dst->un, sizeof (dst->un)); + ISP_MEMZERO(&dst->un, sizeof (dst->un)); } } @@ -1392,7 +1391,6 @@ isp_put_sns_request(ispsoftc_t *isp, sns_screq_t *src, sns_screq_t *dst) for (i = 0; i < nw; i++) { ISP_IOXPUT_16(isp, src->snscb_data[i], &dst->snscb_data[i]); } - } void @@ -1632,13 +1630,14 @@ isp_get_fc_hdr(ispsoftc_t *isp, fc_hdr_t *src, fc_hdr_t *dst) ISP_IOZGET_8(isp, &src->s_id[1], dst->s_id[1]); ISP_IOZGET_8(isp, &src->s_id[2], dst->s_id[2]); ISP_IOZGET_8(isp, &src->type, dst->type); - ISP_IOZGET_8(isp, &src->f_ctl, dst->f_ctl); + ISP_IOZGET_8(isp, &src->f_ctl[0], dst->f_ctl[0]); + ISP_IOZGET_8(isp, &src->f_ctl[1], dst->f_ctl[1]); + ISP_IOZGET_8(isp, &src->f_ctl[2], dst->f_ctl[2]); ISP_IOZGET_8(isp, &src->seq_id, dst->seq_id); ISP_IOZGET_8(isp, &src->df_ctl, dst->df_ctl); ISP_IOZGET_16(isp, &src->seq_cnt, dst->seq_cnt); - ISP_IOZGET_32(isp, &src->ox_id, dst->parameter); - dst->ox_id = dst->parameter; - dst->rx_id = dst->parameter >> 16; + ISP_IOZGET_16(isp, &src->ox_id, dst->ox_id); + ISP_IOZGET_16(isp, &src->rx_id, dst->rx_id); ISP_IOZGET_32(isp, &src->parameter, dst->parameter); } @@ -2233,7 +2232,7 @@ isp_put_ctio7(ispsoftc_t *isp, ct7_entry_t *src, ct7_entry_t *dst) ISP_IOXPUT_16(isp, src->ct_nphdl, &dst->ct_nphdl); ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout); ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count); - ISP_IOXPUT_8(isp, src->ct_vpindex, &dst->ct_vpindex); + ISP_IOXPUT_8(isp, src->ct_vpidx, &dst->ct_vpidx); ISP_IOXPUT_8(isp, src->ct_xflags, &dst->ct_xflags); ISP_IOXPUT_16(isp, src->ct_iid_lo, &dst->ct_iid_lo); ISP_IOXPUT_8(isp, src->ct_iid_hi, &dst->ct_iid_hi); @@ -2465,7 +2464,7 @@ isp_get_ctio7(ispsoftc_t *isp, ct7_entry_t *src, ct7_entry_t *dst) ISP_IOXGET_16(isp, &src->ct_nphdl, dst->ct_nphdl); ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout); ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count); - ISP_IOXGET_8(isp, &src->ct_vpindex, dst->ct_vpindex); + ISP_IOXGET_8(isp, &src->ct_vpidx, dst->ct_vpidx); ISP_IOXGET_8(isp, &src->ct_xflags, dst->ct_xflags); ISP_IOXGET_16(isp, &src->ct_iid_lo, dst->ct_iid_lo); ISP_IOXGET_8(isp, &src->ct_iid_hi, dst->ct_iid_hi); @@ -2732,7 +2731,7 @@ isp_put_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, ISP_IOXPUT_8(isp, src->in_reserved4[i], &dst->in_reserved4[i]); } ISP_IOXPUT_8(isp, src->in_reserved5, &dst->in_reserved5); - ISP_IOXPUT_8(isp, src->in_vpindex, &dst->in_vpindex); + ISP_IOXPUT_8(isp, src->in_vpidx, &dst->in_vpidx); ISP_IOXPUT_32(isp, src->in_reserved6, &dst->in_reserved6); ISP_IOXPUT_16(isp, src->in_portid_lo, &dst->in_portid_lo); ISP_IOXPUT_8(isp, src->in_portid_hi, &dst->in_portid_hi); @@ -2798,7 +2797,7 @@ isp_get_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src, ISP_IOXGET_8(isp, &src->in_reserved4[i], dst->in_reserved4[i]); } ISP_IOXGET_8(isp, &src->in_reserved5, dst->in_reserved5); - ISP_IOXGET_8(isp, &src->in_vpindex, dst->in_vpindex); + ISP_IOXGET_8(isp, &src->in_vpidx, dst->in_vpidx); ISP_IOXGET_32(isp, &src->in_reserved6, dst->in_reserved6); ISP_IOXGET_16(isp, &src->in_portid_lo, dst->in_portid_lo); ISP_IOXGET_8(isp, &src->in_portid_hi, dst->in_portid_hi); @@ -2920,7 +2919,7 @@ isp_put_notify_24xx_ack(ispsoftc_t *isp, na_fcentry_24xx_t *src, ISP_IOXPUT_8(isp, src->na_reserved3[i], &dst->na_reserved3[i]); } ISP_IOXPUT_8(isp, src->na_reserved4, &dst->na_reserved4); - ISP_IOXPUT_8(isp, src->na_vpindex, &dst->na_vpindex); + ISP_IOXPUT_8(isp, src->na_vpidx, &dst->na_vpidx); ISP_IOXPUT_8(isp, src->na_srr_reject_vunique, &dst->na_srr_reject_vunique); ISP_IOXPUT_8(isp, src->na_srr_reject_explanation, @@ -2998,7 +2997,7 @@ isp_get_notify_ack_24xx(ispsoftc_t *isp, na_fcentry_24xx_t *src, ISP_IOXGET_8(isp, &src->na_reserved3[i], dst->na_reserved3[i]); } ISP_IOXGET_8(isp, &src->na_reserved4, dst->na_reserved4); - ISP_IOXGET_8(isp, &src->na_vpindex, dst->na_vpindex); + ISP_IOXGET_8(isp, &src->na_vpidx, dst->na_vpidx); ISP_IOXGET_8(isp, &src->na_srr_reject_vunique, dst->na_srr_reject_vunique); ISP_IOXGET_8(isp, &src->na_srr_reject_explanation, diff --git a/qla_isp/common/isp_library.h b/qla_isp/common/isp_library.h index 2bda0a104..96a8bb06e 100644 --- a/qla_isp/common/isp_library.h +++ b/qla_isp/common/isp_library.h @@ -1,18 +1,18 @@ -/* $Id: isp_library.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_library.h,v 1.29 2009/01/24 17:55:53 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as published * by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ #ifndef _ISP_LIBRARY_H @@ -63,7 +63,7 @@ uint32_t isp_find_handle(ispsoftc_t *, XS_T *); uint32_t isp_handle_index(uint32_t); void isp_destroy_handle(ispsoftc_t *, uint32_t); int isp_getrqentry(ispsoftc_t *, uint32_t *, uint32_t *, void **); -void isp_print_qentry (ispsoftc_t *, char *, int, void *); +void isp_print_qentry (ispsoftc_t *, const char *, int, void *); void isp_print_bytes(ispsoftc_t *, const char *, int, void *); int isp_fc_runstate(ispsoftc_t *, int, int); void isp_dump_portdb(ispsoftc_t *, int); diff --git a/qla_isp/common/isp_stds.h b/qla_isp/common/isp_stds.h index 94b6a6ca6..8a07f5e7f 100644 --- a/qla_isp/common/isp_stds.h +++ b/qla_isp/common/isp_stds.h @@ -1,18 +1,18 @@ -/* $Id: isp_stds.h,v 1.14 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_stds.h,v 1.15 2008/11/13 22:30:00 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as published * by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ /* @@ -70,7 +70,7 @@ typedef struct { uint8_t cs_ctl; uint8_t s_id[3]; uint8_t type; - uint8_t f_ctl; + uint8_t f_ctl[3]; uint8_t seq_id; uint8_t df_ctl; uint16_t seq_cnt; diff --git a/qla_isp/common/isp_target.c b/qla_isp/common/isp_target.c index 3ca50f0be..b0b995a12 100644 --- a/qla_isp/common/isp_target.c +++ b/qla_isp/common/isp_target.c @@ -1,4 +1,4 @@ -/* $Id: isp_target.c,v 1.75 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_target.c,v 1.83 2009/02/01 23:49:49 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -79,12 +79,9 @@ __FBSDID("$FreeBSD:$"); #endif #ifdef ISP_TARGET_MODE -static const char atiocope[] = - "ATIO returned for lun %d because it was in the middle of Bus Device Reset " - "on bus %d"; -static const char atior[] = - "ATIO returned on for lun %d on from loopid %d because a Bus Reset " - "occurred on bus %d"; +static const char atiocope[] = "ATIO returned for lun %d because it was in the middle of Bus Device Reset on bus %d"; +static const char atior[] = "ATIO returned on for lun %d on from loopid %d because a Bus Reset occurred on bus %d"; +static const char rqo[] = "%s: Request Queue Overflow"; static void isp_got_msg(ispsoftc_t *, in_entry_t *); static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *); @@ -193,7 +190,9 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) #define hdrp unp.hp } unp; uint8_t local[QENTRY_LEN]; + uint16_t iid; int bus, type, level, rval = 1; + isp_notify_t notify; type = isp_get_response_type(isp, (isphdr_t *)vptr); unp.vp = vptr; @@ -208,17 +207,15 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) isp_get_atio7(isp, at7iop, (at7_entry_t *) local); at7iop = (at7_entry_t *) local; /* - * Check for and do something with commands whose IULEN - * extends past a singel queue entry. + * Check for and do something with commands whose + * IULEN extends past a single queue entry. */ len = at7iop->at_ta_len & 0xfffff; if (len > (QENTRY_LEN - 8)) { len -= (QENTRY_LEN - 8); - isp_prt(isp, ISP_LOGINFO, - "long IU length (%d) ignored", len); + isp_prt(isp, ISP_LOGINFO, "long IU length (%d) ignored", len); while (len > 0) { - *optrp = ISP_NXT_QENTRY(*optrp, - RESULT_QUEUE_LEN(isp)); + *optrp = ISP_NXT_QENTRY(*optrp, RESULT_QUEUE_LEN(isp)); len -= QENTRY_LEN; } } @@ -275,29 +272,23 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) break; case RQSTYPE_NOTIFY: - /* - * Either the ISP received a SCSI message it can't - * handle, or it's returning an Immed. Notify entry - * we sent. We can send Immed. Notify entries to - * increment the firmware's resource count for them - * (we set this initially in the Enable Lun entry). - */ bus = 0; if (IS_24XX(isp)) { - isp_get_notify_24xx(isp, inot_24xx, - (in_fcentry_24xx_t *)local); + isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local); inot_24xx = (in_fcentry_24xx_t *) local; isp_handle_24xx_inotify(isp, inot_24xx); break; - } else if (IS_FC(isp)) { - if (ISP_CAP_2KLOGIN(isp)) { - isp_get_notify_fc_e(isp, inote_fcp, - (in_fcentry_e_t *)local); - } else { - isp_get_notify_fc(isp, inot_fcp, - (in_fcentry_t *)local); - } + } + if (IS_FC(isp)) { inot_fcp = (in_fcentry_t *) local; + if (ISP_CAP_2KLOGIN(isp)) { + in_fcentry_e_t *ecp = (in_fcentry_e_t *)local; + isp_get_notify_fc_e(isp, inote_fcp, (in_fcentry_e_t *)local); + iid = ecp->in_iid; + } else { + isp_get_notify_fc(isp, inot_fcp, (in_fcentry_t *)local); + iid = inot_fcp->in_iid; + } status = inot_fcp->in_status; seqid = inot_fcp->in_seqid; } else { @@ -305,15 +296,14 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) inotp = (in_entry_t *) local; status = inotp->in_status & 0xff; seqid = inotp->in_seqid; + iid = inotp->in_iid; if (IS_DUALBUS(isp)) { bus = GET_BUS_VAL(inotp->in_iid); SET_BUS_VAL(inotp->in_iid, 0); } } - isp_prt(isp, ISP_LOGTDEBUG0, - "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", - bus, status, seqid); + isp_prt(isp, ISP_LOGTDEBUG0, "Immediate Notify On Bus %d, status=0x%x seqid=0x%x", bus, status, seqid); switch (status) { case IN_MSG_RECEIVED: @@ -326,38 +316,57 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) break; case IN_RSRC_UNAVAIL: isp_prt(isp, ISP_LOGINFO, "Firmware out of ATIOs"); - isp_notify_ack(isp, local); + (void) isp_notify_ack(isp, local); break; case IN_RESET: - { - /* - * We form the notify structure here because we need - * to mark it as needing a NOTIFY ACK on return. - */ - tmd_notify_t notify; - - MEMZERO(¬ify, sizeof (tmd_notify_t)); + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); notify.nt_hba = isp; - notify.nt_iid = INI_ANY; - /* nt_tgt set in outer layers */ + notify.nt_wwn = INI_ANY; + notify.nt_tgt = TGT_ANY; + notify.nt_nphdl = iid; + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; notify.nt_lun = LUN_ANY; notify.nt_tagval = TAG_ANY; + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); notify.nt_ncode = NT_BUS_RESET; notify.nt_need_ack = 1; + notify.nt_lreserved = local; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; - } case IN_PORT_LOGOUT: + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); + notify.nt_hba = isp; + notify.nt_wwn = INI_ANY; + notify.nt_nphdl = iid; + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; + notify.nt_ncode = NT_LOGOUT; + notify.nt_need_ack = 1; + notify.nt_lreserved = local; + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); + break; case IN_ABORT_TASK: - case IN_PORT_CHANGED: + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); + notify.nt_hba = isp; + notify.nt_wwn = INI_ANY; + notify.nt_nphdl = iid; + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; + notify.nt_ncode = NT_ABORT_TASK; + notify.nt_need_ack = 1; + notify.nt_lreserved = local; + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); + break; + case IN_GLOBAL_LOGO: - isp_async(isp, ISPASYNC_TARGET_ACTION, &local); + case IN_PORT_CHANGED: + isp_prt(isp, ISP_LOGTINFO, "%s: port changed", __func__); + (void) isp_notify_ack(isp, local); break; default: - isp_prt(isp, ISP_LOGINFO, - "isp_target_notify: unknown status (0x%x)", - status); - isp_notify_ack(isp, local); + isp_prt(isp, ISP_LOGTINFO, "%s: unknown status (0x%x)", __func__, status); + (void) isp_notify_ack(isp, local); break; } break; @@ -368,25 +377,19 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) * Immediate Notify entry for some asynchronous event. */ if (IS_24XX(isp)) { - isp_get_notify_ack_24xx(isp, nack_24xx, - (na_fcentry_24xx_t *) local); + isp_get_notify_ack_24xx(isp, nack_24xx, (na_fcentry_24xx_t *) local); nack_24xx = (na_fcentry_24xx_t *) local; if (nack_24xx->na_status != NA_OK) { level = ISP_LOGINFO; } else { level = ISP_LOGTDEBUG1; } - isp_prt(isp, level, - "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", - nack_24xx->na_status, nack_24xx->na_status_subcode, - nack_24xx->na_rxid); + isp_prt(isp, level, "Notify Ack Status=0x%x; Subcode 0x%x seqid=0x%x", nack_24xx->na_status, nack_24xx->na_status_subcode, nack_24xx->na_rxid); } else if (IS_FC(isp)) { if (ISP_CAP_2KLOGIN(isp)) { - isp_get_notify_ack_fc_e(isp, nacke_fcp, - (na_fcentry_e_t *)local); + isp_get_notify_ack_fc_e(isp, nacke_fcp, (na_fcentry_e_t *)local); } else { - isp_get_notify_ack_fc(isp, nack_fcp, - (na_fcentry_t *)local); + isp_get_notify_ack_fc(isp, nack_fcp, (na_fcentry_t *)local); } nack_fcp = (na_fcentry_t *)local; if (nack_fcp->na_status != NA_OK) { @@ -394,9 +397,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) } else { level = ISP_LOGTDEBUG1; } - isp_prt(isp, level, - "Notify Ack Status=0x%x seqid 0x%x", - nack_fcp->na_status, nack_fcp->na_seqid); + isp_prt(isp, level, "Notify Ack Status=0x%x seqid 0x%x", nack_fcp->na_status, nack_fcp->na_seqid); } else { isp_get_notify_ack(isp, nackp, (na_entry_t *)local); nackp = (na_entry_t *)local; @@ -405,9 +406,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) } else { level = ISP_LOGTDEBUG1; } - isp_prt(isp, level, - "Notify Ack event 0x%x status=0x%x seqid 0x%x", - nackp->na_event, nackp->na_status, nackp->na_seqid); + isp_prt(isp, level, "Notify Ack event 0x%x status=0x%x seqid 0x%x", nackp->na_event, nackp->na_status, nackp->na_seqid); } break; @@ -423,15 +422,11 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) } else { level = ISP_LOGTDEBUG0; } - isp_prt(isp, level, - "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", - abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, - abts_rsp->abts_rsp_payload.rsp.subcode1, - abts_rsp->abts_rsp_payload.rsp.subcode2); + isp_prt(isp, level, "ABTS RSP response[0x%x]: status=0x%x sub=(0x%x 0x%x)", abts_rsp->abts_rsp_rxid_task, abts_rsp->abts_rsp_status, + abts_rsp->abts_rsp_payload.rsp.subcode1, abts_rsp->abts_rsp_payload.rsp.subcode2); break; default: - isp_prt(isp, ISP_LOGERR, - "Unknown entry type 0x%x in isp_target_notify", type); + isp_prt(isp, ISP_LOGERR, "Unknown entry type 0x%x in isp_target_notify", type); rval = 0; break; } @@ -467,7 +462,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp) * * Note that not all of bus, target or lun can be paid attention to. * Note also that this action will not be complete until the f/w writes - * response entry. The caller is responsible for synchronizing this. + * a response entry. The caller is responsible for synchronizing with this. */ int isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt) @@ -476,8 +471,7 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cn uint32_t nxti, optr; void *outp; - - MEMZERO(&el, sizeof (el)); + ISP_MEMZERO(&el, sizeof (el)); if (IS_DUALBUS(isp)) { el.le_rsvd = (bus & 0x1) << 7; } @@ -510,8 +504,7 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cn el.le_timeout = 30; if (isp_getrqentry(isp, &nxti, &optr, &outp)) { - isp_prt(isp, ISP_LOGERR, - "Request Queue Overflow in isp_lun_cmd"); + isp_prt(isp, ISP_LOGERR, rqo, __func__); return (-1); } ISP_TDQE(isp, "isp_lun_cmd", (int) optr, &el); @@ -529,8 +522,7 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap) uint8_t etype = ((isphdr_t *) ap)->rqs_entry_type; if (isp_getrqentry(isp, &nxti, &optr, &outp)) { - isp_prt(isp, ISP_LOGWARN, - "Request Queue Overflow in isp_target_put_entry"); + isp_prt(isp, ISP_LOGWARN, rqo, __func__); return (-1); } switch (etype) { @@ -539,11 +531,9 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap) break; case RQSTYPE_ATIO2: if (ISP_CAP_2KLOGIN(isp)) { - isp_put_atio2e(isp, (at2e_entry_t *) ap, - (at2e_entry_t *) outp); + isp_put_atio2e(isp, (at2e_entry_t *) ap, (at2e_entry_t *) outp); } else { - isp_put_atio2(isp, (at2_entry_t *) ap, - (at2_entry_t *) outp); + isp_put_atio2(isp, (at2_entry_t *) ap, (at2_entry_t *) outp); } break; case RQSTYPE_CTIO: @@ -551,22 +541,19 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap) break; case RQSTYPE_CTIO2: if (ISP_CAP_2KLOGIN(isp)) { - isp_put_ctio2e(isp, (ct2e_entry_t *) ap, - (ct2e_entry_t *) outp); + isp_put_ctio2e(isp, (ct2e_entry_t *) ap, (ct2e_entry_t *) outp); } else { - isp_put_ctio2(isp, (ct2_entry_t *) ap, - (ct2_entry_t *) outp); + isp_put_ctio2(isp, (ct2_entry_t *) ap, (ct2_entry_t *) outp); } break; case RQSTYPE_CTIO7: isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp); break; default: - isp_prt(isp, ISP_LOGERR, - "Unknown type 0x%x in isp_put_entry", etype); + isp_prt(isp, ISP_LOGERR, "%s: Unknown type 0x%x", __func__, etype); return (-1); } - ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap); + ISP_TDQE(isp, __func__, (int) optr, ap); ISP_ADD_REQUEST(isp, nxti); return (0); } @@ -580,7 +567,7 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg) at2e_entry_t _atio2e; } atun; - MEMZERO(&atun, sizeof atun); + ISP_MEMZERO(&atun, sizeof atun); if (IS_FC(isp)) { at2_entry_t *aep = arg; atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2; @@ -644,7 +631,7 @@ isp_endcmd(ispsoftc_t *isp, ...) } un; va_list ap; - MEMZERO(&un, sizeof un); + ISP_MEMZERO(&un, sizeof un); if (IS_24XX(isp)) { int vpidx, nphdl; @@ -654,34 +641,48 @@ isp_endcmd(ispsoftc_t *isp, ...) va_start(ap, isp); aep = va_arg(ap, at7_entry_t *); nphdl = va_arg(ap, int); + /* + * Note that vpidx may equal 0xff (unknown) here + */ vpidx = va_arg(ap, int); code = va_arg(ap, uint32_t); hdl = va_arg(ap, uint32_t); va_end(ap); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] chan %d code %x", __func__, aep->at_rxid, vpidx, code); - sts = code; + sts = code & 0xff; cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; cto->ct_header.rqs_entry_count = 1; cto->ct_nphdl = nphdl; cto->ct_rxid = aep->at_rxid; - cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | - aep->at_hdr.s_id[2]; + cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; cto->ct_iid_hi = aep->at_hdr.s_id[0]; cto->ct_oxid = aep->at_hdr.ox_id; cto->ct_scsi_status = sts; - cto->ct_vpindex = vpidx; - cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS; - if (sts == SCSI_CHECK && (code & ECMD_SVALID)) { - cto->rsp.m1.ct_resplen = 16; + cto->ct_vpidx = vpidx; + cto->ct_flags = CT7_NOACK; + if (code & ECMD_TERMINATE) { + cto->ct_flags |= CT7_TERMINATE; + } else if (code & ECMD_SVALID) { + cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; + cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); + cto->rsp.m1.ct_resplen = cto->ct_senselen = min(16, MAXRESPLEN_24XX); + ISP_MEMZERO(cto->rsp.m1.ct_resp, sizeof (cto->rsp.m1.ct_resp)); cto->rsp.m1.ct_resp[0] = 0xf0; cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf; cto->rsp.m1.ct_resp[7] = 8; cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff; cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff; + } else { + cto->ct_flags |= CT7_FLAG_MODE1 | CT7_SENDSTATUS; } if (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl) { cto->ct_resid = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; - cto->ct_scsi_status |= CT2_DATA_UNDER; + if (cto->ct_resid < 0) { + cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); + } else if (cto->ct_resid > 0) { + cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); + } } cto->ct_syshandle = hdl; } else if (IS_FC(isp)) { @@ -693,8 +694,10 @@ isp_endcmd(ispsoftc_t *isp, ...) code = va_arg(ap, uint32_t); hdl = va_arg(ap, uint32_t); va_end(ap); - sts = code; + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] code %x", __func__, aep->at_rxid, code); + + sts = code & 0xff; cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; cto->ct_header.rqs_entry_count = 1; if (ISP_CAP_SCCFW(isp) == 0) { @@ -734,6 +737,7 @@ isp_endcmd(ispsoftc_t *isp, ...) code = va_arg(ap, uint32_t); hdl = va_arg(ap, uint32_t); va_end(ap); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [IID %d] code %x", __func__, aep->at_iid, code); sts = code; cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; @@ -760,30 +764,33 @@ isp_endcmd(ispsoftc_t *isp, ...) /* * These are either broadcast events or specifically CTIO fast completion */ + int isp_target_async(ispsoftc_t *isp, int bus, int event) { - tmd_notify_t notify; + isp_notify_t notify; - MEMZERO(¬ify, sizeof (tmd_notify_t)); + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); notify.nt_hba = isp; - notify.nt_iid = INI_ANY; - /* nt_tgt set in outer layers */ - notify.nt_lun = LUN_ANY; + notify.nt_wwn = INI_ANY; + notify.nt_nphdl = NIL_HANDLE; + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; + notify.nt_tgt = TGT_ANY; notify.nt_channel = bus; + notify.nt_lun = LUN_ANY; notify.nt_tagval = TAG_ANY; - - if (IS_SCSI(isp)) { - TAG_INSERT_BUS(notify.nt_tagval, bus); - } + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); switch (event) { case ASYNC_LOOP_UP: case ASYNC_PTPMODE: + isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP UP", __func__); notify.nt_ncode = NT_LINK_UP; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; case ASYNC_LOOP_DOWN: + isp_prt(isp, ISP_LOGTDEBUG0, "%s: LOOP DOWN", __func__); notify.nt_ncode = NT_LINK_DOWN; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; @@ -791,21 +798,25 @@ isp_target_async(ispsoftc_t *isp, int bus, int event) case ASYNC_LIP_F8: case ASYNC_LIP_OCCURRED: case ASYNC_LOOP_RESET: + isp_prt(isp, ISP_LOGTDEBUG0, "%s: LIP RESET", __func__); notify.nt_ncode = NT_LIP_RESET; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; case ASYNC_BUS_RESET: case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */ + isp_prt(isp, ISP_LOGTDEBUG0, "%s: BUS RESET", __func__); notify.nt_ncode = NT_BUS_RESET; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; case ASYNC_DEVICE_RESET: + isp_prt(isp, ISP_LOGTDEBUG0, "%s: DEVICE RESET", __func__); notify.nt_ncode = NT_TARGET_RESET; isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); break; case ASYNC_CTIO_DONE: { uint8_t storage[QENTRY_LEN]; + isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO DONE", __func__); memset(storage, 0, QENTRY_LEN); if (IS_24XX(isp)) { ct7_entry_t *ct = (ct7_entry_t *) storage; @@ -831,10 +842,9 @@ isp_target_async(ispsoftc_t *isp, int bus, int event) break; } default: - isp_prt(isp, ISP_LOGERR, - "isp_target_async: unknown event 0x%x", event); + isp_prt(isp, ISP_LOGERR, "%s: unknown event 0x%x", __func__, event); if (isp->isp_state == ISP_RUNSTATE) { - isp_notify_ack(isp, NULL); + (void) isp_notify_ack(isp, NULL); } break; } @@ -853,51 +863,54 @@ isp_target_async(ispsoftc_t *isp, int bus, int event) static void isp_got_msg(ispsoftc_t *isp, in_entry_t *inp) { - tmd_notify_t nt; + isp_notify_t notify; uint8_t status = inp->in_status & ~QLTM_SVALID; - MEMZERO(&nt, sizeof (nt)); - nt.nt_hba = isp; - nt.nt_iid = GET_IID_VAL(inp->in_iid); - nt.nt_tgt = inp->in_tgt; - nt.nt_lun = inp->in_lun; - IN_MAKE_TAGID(nt.nt_tagval, GET_BUS_VAL(inp->in_iid), 0, inp); - nt.nt_lreserved = inp; + ISP_MEMZERO(¬ify, sizeof (notify)); + notify.nt_hba = isp; + notify.nt_wwn = INI_ANY; + notify.nt_nphdl = GET_IID_VAL(inp->in_iid); + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; + notify.nt_channel = GET_BUS_VAL(inp->in_iid); + notify.nt_tgt = inp->in_tgt; + notify.nt_lun = inp->in_lun; + IN_MAKE_TAGID(notify.nt_tagval, inp); + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); + notify.nt_lreserved = inp; if (status == IN_IDE_RECEIVED || status == IN_MSG_RECEIVED) { switch (inp->in_msg[0]) { case MSG_ABORT: - nt.nt_ncode = NT_ABORT_TASK_SET; + notify.nt_ncode = NT_ABORT_TASK_SET; break; case MSG_BUS_DEV_RESET: - nt.nt_ncode = NT_TARGET_RESET; + notify.nt_ncode = NT_TARGET_RESET; break; case MSG_ABORT_TAG: - nt.nt_ncode = NT_ABORT_TASK; + notify.nt_ncode = NT_ABORT_TASK; break; case MSG_CLEAR_QUEUE: - nt.nt_ncode = NT_CLEAR_TASK_SET; + notify.nt_ncode = NT_CLEAR_TASK_SET; break; case MSG_REL_RECOVERY: - nt.nt_ncode = NT_CLEAR_ACA; + notify.nt_ncode = NT_CLEAR_ACA; break; case MSG_TERM_IO_PROC: - nt.nt_ncode = NT_ABORT_TASK; + notify.nt_ncode = NT_ABORT_TASK; break; case MSG_LUN_RESET: - nt.nt_ncode = NT_LUN_RESET; + notify.nt_ncode = NT_LUN_RESET; break; default: - isp_prt(isp, ISP_LOGERR, - "unhandled message 0x%x", inp->in_msg[0]); - isp_notify_ack(isp, inp); + isp_prt(isp, ISP_LOGERR, "%s: unhandled message 0x%x", __func__, inp->in_msg[0]); + (void) isp_notify_ack(isp, inp); return; } - isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); } else { - isp_prt(isp, ISP_LOGERR, - "unknown immediate notify status 0x%x", inp->in_status); - isp_notify_ack(isp, inp); + isp_prt(isp, ISP_LOGERR, "%s: unknown immediate notify status 0x%x", __func__, inp->in_status); + (void) isp_notify_ack(isp, inp); } } @@ -907,188 +920,161 @@ isp_got_msg(ispsoftc_t *isp, in_entry_t *inp) static void isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp) { - tmd_notify_t nt; + isp_notify_t notify; static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x"; - static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x " - "task flags 0x%x seq 0x%x\n"; + static const char f2[] = "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n"; uint16_t seqid, loopid; - MEMZERO(&nt, sizeof (tmd_notify_t)); - nt.nt_hba = isp; + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); + notify.nt_hba = isp; + notify.nt_wwn = INI_ANY; if (ISP_CAP_2KLOGIN(isp)) { - nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid; + notify.nt_nphdl = ((in_fcentry_e_t *)inp)->in_iid; loopid = ((in_fcentry_e_t *)inp)->in_iid; seqid = ((in_fcentry_e_t *)inp)->in_seqid; } else { - nt.nt_iid = inp->in_iid; + notify.nt_nphdl = inp->in_iid; loopid = inp->in_iid; seqid = inp->in_seqid; } + notify.nt_sid = PORT_ANY; + notify.nt_did = PORT_ANY; + /* nt_tgt set in outer layers */ if (ISP_CAP_SCCFW(isp)) { - nt.nt_lun = inp->in_scclun; + notify.nt_lun = inp->in_scclun; } else { - nt.nt_lun = inp->in_lun; + notify.nt_lun = inp->in_lun; } - IN_FC_MAKE_TAGID(nt.nt_tagval, 0, 0, seqid); - nt.nt_need_ack = 1; - nt.nt_lreserved = inp; + notify.nt_tagval = seqid; + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); + notify.nt_need_ack = 1; + notify.nt_lreserved = inp; if (inp->in_status != IN_MSG_RECEIVED) { - isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", - inp->in_status, nt.nt_lun, loopid, inp->in_task_flags, - inp->in_seqid); - isp_notify_ack(isp, inp); + isp_prt(isp, ISP_LOGINFO, f2, "immediate notify status", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid); + (void) isp_notify_ack(isp, inp); return; } if (inp->in_task_flags & TASK_FLAGS_ABORT_TASK_SET) { - isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", - loopid, nt.nt_lun, inp->in_seqid); - nt.nt_ncode = NT_ABORT_TASK_SET; + isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", loopid, notify.nt_lun, inp->in_seqid); + notify.nt_ncode = NT_ABORT_TASK_SET; } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_TASK_SET) { - isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", - loopid, nt.nt_lun, inp->in_seqid); - nt.nt_ncode = NT_CLEAR_TASK_SET; + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", loopid, notify.nt_lun, inp->in_seqid); + notify.nt_ncode = NT_CLEAR_TASK_SET; } else if (inp->in_task_flags & TASK_FLAGS_LUN_RESET) { - isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", - loopid, nt.nt_lun, inp->in_seqid); - nt.nt_ncode = NT_LUN_RESET; + isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", loopid, notify.nt_lun, inp->in_seqid); + notify.nt_ncode = NT_LUN_RESET; } else if (inp->in_task_flags & TASK_FLAGS_TARGET_RESET) { - isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", - loopid, nt.nt_lun, inp->in_seqid); - nt.nt_ncode = NT_TARGET_RESET; + isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", loopid, notify.nt_lun, inp->in_seqid); + notify.nt_ncode = NT_TARGET_RESET; } else if (inp->in_task_flags & TASK_FLAGS_CLEAR_ACA) { - isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", - loopid, nt.nt_lun, inp->in_seqid); - nt.nt_ncode = NT_CLEAR_ACA; + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", loopid, notify.nt_lun, inp->in_seqid); + notify.nt_ncode = NT_CLEAR_ACA; } else { - isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, - nt.nt_lun, loopid, inp->in_task_flags, inp->in_seqid); - isp_notify_ack(isp, inp); + isp_prt(isp, ISP_LOGWARN, f2, "task flag", inp->in_status, notify.nt_lun, loopid, inp->in_task_flags, inp->in_seqid); + (void) isp_notify_ack(isp, inp); return; } - isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); } -#define HILO(x) (uint32_t) (x >> 32), (uint32_t) x static void isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep) { - tmd_notify_t nt; - static const char f1[] = - "%s from PortID 0x%06x lun %d seq 0x%08x%08x"; - static const char f2[] = - "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x"; + isp_notify_t notify; + static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%08x"; + static const char f2[] = "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x"; uint16_t chan; uint32_t sid, did; - MEMZERO(&nt, sizeof (tmd_notify_t)); - nt.nt_hba = isp; - nt.nt_iid = INI_ANY; - nt.nt_lun = - (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | - (aep->at_cmnd.fcp_cmnd_lun[1]); - nt.nt_tagval = aep->at_rxid; - nt.nt_lreserved = aep; - sid = - (aep->at_hdr.s_id[0] << 16) | - (aep->at_hdr.s_id[1] << 8) | - (aep->at_hdr.s_id[2]); + ISP_MEMZERO(¬ify, sizeof (isp_notify_t)); + notify.nt_hba = isp; + notify.nt_wwn = INI_ANY; + notify.nt_lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | (aep->at_cmnd.fcp_cmnd_lun[1]); + notify.nt_tagval = aep->at_rxid; + notify.nt_tagval |= (((uint64_t)(isp->isp_serno++)) << 32); + notify.nt_lreserved = aep; + sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | (aep->at_hdr.s_id[2]); /* Channel has to derived from D_ID */ did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; for (chan = 0; chan < isp->isp_nchan; chan++) { if (FCPARAM(isp, chan)->isp_portid == did) { - break; + break; } } if (chan == isp->isp_nchan) { - isp_prt(isp, ISP_LOGWARN, - "%s: D_ID 0x%x not found on any channel", __FUNCTION__, did); + isp_prt(isp, ISP_LOGWARN, "%s: D_ID 0x%x not found on any channel", __func__, did); /* just drop on the floor */ return; } - nt.nt_channel = chan; - if (aep->at_cmnd.fcp_cmnd_task_management & - FCP_CMND_TMF_ABORT_TASK_SET) { - isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", - sid, nt.nt_lun, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_ABORT_TASK_SET; - } else if (aep->at_cmnd.fcp_cmnd_task_management & - FCP_CMND_TMF_CLEAR_TASK_SET) { - isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", - sid, nt.nt_lun, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_CLEAR_TASK_SET; - } else if (aep->at_cmnd.fcp_cmnd_task_management & - FCP_CMND_TMF_LUN_RESET) { - isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", - sid, nt.nt_lun, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_LUN_RESET; - } else if (aep->at_cmnd.fcp_cmnd_task_management & - FCP_CMND_TMF_TGT_RESET) { - isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", - sid, nt.nt_lun, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_TARGET_RESET; - nt.nt_lun = LUN_ANY; - } else if (aep->at_cmnd.fcp_cmnd_task_management & - FCP_CMND_TMF_CLEAR_ACA) { - isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", - sid, nt.nt_lun, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_CLEAR_ACA; + notify.nt_nphdl = NIL_HANDLE; /* unknown here */ + notify.nt_sid = sid; + notify.nt_did = did; + notify.nt_channel = chan; + if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_ABORT_TASK_SET) { + isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET", sid, notify.nt_lun, aep->at_rxid); + notify.nt_ncode = NT_ABORT_TASK_SET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_TASK_SET) { + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET", sid, notify.nt_lun, aep->at_rxid); + notify.nt_ncode = NT_CLEAR_TASK_SET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_LUN_RESET) { + isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET", sid, notify.nt_lun, aep->at_rxid); + notify.nt_ncode = NT_LUN_RESET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_TGT_RESET) { + isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET", sid, notify.nt_lun, aep->at_rxid); + notify.nt_ncode = NT_TARGET_RESET; + } else if (aep->at_cmnd.fcp_cmnd_task_management & FCP_CMND_TMF_CLEAR_ACA) { + isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA", sid, notify.nt_lun, aep->at_rxid); + notify.nt_ncode = NT_CLEAR_ACA; } else { - isp_prt(isp, ISP_LOGWARN, f2, - aep->at_cmnd.fcp_cmnd_task_management, - nt.nt_lun, sid, HILO(nt.nt_tagval)); - nt.nt_ncode = NT_UNKNOWN; + isp_prt(isp, ISP_LOGWARN, f2, aep->at_cmnd.fcp_cmnd_task_management, notify.nt_lun, sid, aep->at_rxid); + notify.nt_ncode = NT_UNKNOWN; return; } - isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt); + isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify); } -void +int isp_notify_ack(ispsoftc_t *isp, void *arg) { char storage[QENTRY_LEN]; uint32_t nxti, optr; void *outp; - if (isp_getrqentry(isp, &nxti, &optr, &outp)) { - isp_prt(isp, ISP_LOGWARN, - "Request Queue Overflow For isp_notify_ack"); - return; - } - - MEMZERO(storage, QENTRY_LEN); - + /* + * This is in case a Task Management Function ends up here. + */ if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) { at7_entry_t *aep = arg; -isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl"); - isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0); - return; - } else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) { - abts_rsp_t *abts_rsp = (abts_rsp_t *) storage; - /* - * The caller will have set response values as appropriate - * in the ABTS structure just before calling us. - */ - MEMCPY(abts_rsp, arg, QENTRY_LEN); - isp_put_abts_rsp(isp, abts_rsp, (abts_rsp_t *)outp); - } else if (IS_24XX(isp)) { + return (isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0)); + } + + if (isp_getrqentry(isp, &nxti, &optr, &outp)) { + isp_prt(isp, ISP_LOGWARN, rqo, __func__); + return (1); + } + + ISP_MEMZERO(storage, QENTRY_LEN); + + if (IS_24XX(isp)) { na_fcentry_24xx_t *na = (na_fcentry_24xx_t *) storage; if (arg) { in_fcentry_24xx_t *in = arg; na->na_nphdl = in->in_nphdl; + na->na_flags = in->in_flags & IN24XX_FLAG_PUREX_IOCB; na->na_status = in->in_status; na->na_status_subcode = in->in_status_subcode; na->na_rxid = in->in_rxid; na->na_oxid = in->in_oxid; - na->na_vpindex = in->in_vpindex; - na->na_srr_rxid = in->in_srr_rxid; - na->na_srr_reloff_hi = in->in_srr_reloff_hi; - na->na_srr_reloff_lo = in->in_srr_reloff_lo; - na->na_srr_iu = in->in_srr_iu; + na->na_vpidx = in->in_vpidx; if (in->in_status == IN24XX_SRR_RCVD) { + na->na_srr_rxid = in->in_srr_rxid; + na->na_srr_reloff_hi = in->in_srr_reloff_hi; + na->na_srr_reloff_lo = in->in_srr_reloff_lo; + na->na_srr_iu = in->in_srr_iu; na->na_srr_flags = 1; na->na_srr_reject_vunique = 0; na->na_srr_reject_explanation = 1; @@ -1104,17 +1090,15 @@ isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl"); if (arg) { in_fcentry_t *inp = arg; - MEMCPY(storage, arg, sizeof (isphdr_t)); + ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); if (ISP_CAP_2KLOGIN(isp)) { - ((na_fcentry_e_t *)na)->na_iid = - ((in_fcentry_e_t *)inp)->in_iid; + ((na_fcentry_e_t *)na)->na_iid = ((in_fcentry_e_t *)inp)->in_iid; iid = ((na_fcentry_e_t *)na)->na_iid; } else { na->na_iid = inp->in_iid; iid = na->na_iid; } - na->na_task_flags = - inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; + na->na_task_flags = inp->in_task_flags & TASK_FLAGS_RESERVED_MASK; na->na_seqid = inp->in_seqid; na->na_flags = NAFC_RCOUNT; na->na_status = inp->in_status; @@ -1131,19 +1115,17 @@ isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl"); na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; na->na_header.rqs_entry_count = 1; if (ISP_CAP_2KLOGIN(isp)) { - isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, - (na_fcentry_e_t *)outp); + isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na, (na_fcentry_e_t *)outp); } else { isp_put_notify_ack_fc(isp, na, (na_fcentry_t *)outp); } - isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x " - "flags %x tflags %x response %x", iid, na->na_seqid, + isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u seqid %x flags %x tflags %x response %x", iid, na->na_seqid, na->na_flags, na->na_task_flags, na->na_response); } else { na_entry_t *na = (na_entry_t *) storage; if (arg) { in_entry_t *inp = arg; - MEMCPY(storage, arg, sizeof (isphdr_t)); + ISP_MEMCPY(storage, arg, sizeof (isphdr_t)); na->na_iid = inp->in_iid; na->na_lun = inp->in_lun; na->na_tgt = inp->in_tgt; @@ -1157,12 +1139,91 @@ isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl"); na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; na->na_header.rqs_entry_count = 1; isp_put_notify_ack(isp, na, (na_entry_t *)outp); - isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt " - "%u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, + isp_prt(isp, ISP_LOGTDEBUG0, "notify ack loopid %u lun %u tgt %u seqid %x event %x", na->na_iid, na->na_lun, na->na_tgt, na->na_seqid, na->na_event); } ISP_TDQE(isp, "isp_notify_ack", (int) optr, storage); ISP_ADD_REQUEST(isp, nxti); + return (0); +} + +int +isp_acknak_abts(ispsoftc_t *isp, void *arg, int errno) +{ + char storage[QENTRY_LEN]; + uint16_t tmpw; + uint8_t tmpb; + abts_t *abts = arg; + abts_rsp_t *rsp = (abts_rsp_t *) storage; + uint32_t nxti, optr; + void *outp; + + if (!IS_24XX(isp)) { + isp_prt(isp, ISP_LOGERR, "%s: called for non-24XX card", __func__); + return (0); + } + + if (abts->abts_header.rqs_entry_type != RQSTYPE_ABTS_RCVD) { + isp_prt(isp, ISP_LOGERR, "%s: called for non-ABTS entry (0x%x)", __func__, abts->abts_header.rqs_entry_type); + return (0); + } + + if (isp_getrqentry(isp, &nxti, &optr, &outp)) { + isp_prt(isp, ISP_LOGWARN, rqo, __func__); + return (1); + } + + ISP_MEMCPY(rsp, abts, QENTRY_LEN); + rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; + + /* + * Swap destination and source for response. + */ + rsp->abts_rsp_r_ctl = BA_ACC; + tmpw = rsp->abts_rsp_did_lo; + tmpb = rsp->abts_rsp_did_hi; + rsp->abts_rsp_did_lo = rsp->abts_rsp_sid_lo; + rsp->abts_rsp_did_hi = rsp->abts_rsp_sid_hi; + rsp->abts_rsp_sid_lo = tmpw; + rsp->abts_rsp_sid_hi = tmpb; + + rsp->abts_rsp_f_ctl_hi ^= 0x80; /* invert Exchange Context */ + rsp->abts_rsp_f_ctl_hi &= ~0x7f; /* clear Sequence Initiator and other bits */ + rsp->abts_rsp_f_ctl_hi |= 0x10; /* abort the whole exchange */ + rsp->abts_rsp_f_ctl_hi |= 0x8; /* last data frame of sequence */ + rsp->abts_rsp_f_ctl_hi |= 0x1; /* transfer Sequence Initiative */ + rsp->abts_rsp_f_ctl_lo = 0; + + if (errno == 0) { + uint16_t rx_id, ox_id; + + rx_id = rsp->abts_rsp_rx_id; + ox_id = rsp->abts_rsp_ox_id; + ISP_MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); + isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS of 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts, rsp->abts_rsp_rxid_task); + rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id; + rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id; + rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff; + } else { + ISP_MEMZERO(&rsp->abts_rsp_payload.ba_rjt, sizeof (rsp->abts_rsp_payload.ba_acc)); + switch (errno) { + case ENOMEM: + rsp->abts_rsp_payload.ba_rjt.reason = 5; /* Logical Busy */ + break; + default: + rsp->abts_rsp_payload.ba_rjt.reason = 9; /* Unable to perform command request */ + break; + } + } + + /* + * The caller will have set response values as appropriate + * in the ABTS structure just before calling us. + */ + isp_put_abts_rsp(isp, rsp, (abts_rsp_t *)outp); + ISP_TDQE(isp, "isp_acknak_abts", (int) optr, storage); + ISP_ADD_REQUEST(isp, nxti); + return (0); } static void @@ -1187,8 +1248,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) /* * ATIO rejected by the firmware due to disabled lun. */ - isp_prt(isp, ISP_LOGERR, - "rejected ATIO for disabled lun %d", lun); + isp_prt(isp, ISP_LOGERR, "rejected ATIO for disabled lun %d", lun); break; case AT_NOCAP: /* @@ -1196,9 +1256,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) * We sent an ATIO that overflowed the firmware's * command resource count. */ - isp_prt(isp, ISP_LOGERR, - "rejected ATIO for lun %d because of command count" - " overflow", lun); + isp_prt(isp, ISP_LOGERR, "rejected ATIO for lun %d because of command count overflow", lun); break; case AT_BDR_MSG: @@ -1211,8 +1269,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) * not increment it. Therefore we should never get * this status here. */ - isp_prt(isp, ISP_LOGERR, atiocope, lun, - GET_BUS_VAL(aep->at_iid)); + isp_prt(isp, ISP_LOGERR, atiocope, lun, GET_BUS_VAL(aep->at_iid)); break; case AT_CDB: /* Got a CDB */ @@ -1232,15 +1289,12 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep) * Ignore it because the async event will clear things * up for us. */ - isp_prt(isp, ISP_LOGWARN, atior, lun, - GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid)); + isp_prt(isp, ISP_LOGWARN, atior, lun, GET_IID_VAL(aep->at_iid), GET_BUS_VAL(aep->at_iid)); break; default: - isp_prt(isp, ISP_LOGERR, - "Unknown ATIO status 0x%x from loopid %d for lun %d", - aep->at_status, aep->at_iid, lun); + isp_prt(isp, ISP_LOGERR, "Unknown ATIO status 0x%x from loopid %d for lun %d", aep->at_status, aep->at_iid, lun); (void) isp_target_put_atio(isp, aep); break; } @@ -1280,8 +1334,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) /* * ATIO rejected by the firmware due to disabled lun. */ - isp_prt(isp, ISP_LOGERR, - "rejected ATIO2 for disabled lun %d", lun); + isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for disabled lun %d", lun); break; case AT_NOCAP: /* @@ -1289,8 +1342,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) * We sent an ATIO that overflowed the firmware's * command resource count. */ - isp_prt(isp, ISP_LOGERR, - "rejected ATIO2 for lun %d- command count overflow", lun); + isp_prt(isp, ISP_LOGERR, "rejected ATIO2 for lun %d- command count overflow", lun); break; case AT_BDR_MSG: @@ -1327,9 +1379,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep) default: - isp_prt(isp, ISP_LOGERR, - "Unknown ATIO2 status 0x%x from loopid %d for lun %d", - aep->at_status, iid, lun); + isp_prt(isp, ISP_LOGERR, "Unknown ATIO2 status 0x%x from loopid %d for lun %d", aep->at_status, iid, lun); (void) isp_target_put_atio(isp, aep); break; } @@ -1367,8 +1417,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) /* * Nothing to do in this case. */ - isp_prt(isp, pl, "CTIO- iid %d disconnected OK", - ct->ct_iid); + isp_prt(isp, pl, "CTIO- iid %d disconnected OK", ct->ct_iid); return; } break; @@ -1397,7 +1446,6 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) */ if (fmsg == NULL) fmsg = "ABORT TAG message sent by Initiator"; - isp_prt(isp, ISP_LOGTDEBUG0, "CTIO destroyed by %s", fmsg); break; @@ -1406,9 +1454,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) * CTIO rejected by the firmware due to disabled lun. * "Cannot Happen". */ - isp_prt(isp, ISP_LOGERR, - "Firmware rejected CTIO for disabled lun %d", - ct->ct_lun); + isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for disabled lun %d", ct->ct_lun); break; case CT_NOPATH: @@ -1418,9 +1464,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) * we tried to access the bus while a non-disconnecting * command is in process. */ - isp_prt(isp, ISP_LOGERR, - "Firmware rejected CTIO for bad nexus %d/%d/%d", - ct->ct_iid, ct->ct_tgt, ct->ct_lun); + isp_prt(isp, ISP_LOGERR, "Firmware rejected CTIO for bad nexus %d/%d/%d", ct->ct_iid, ct->ct_tgt, ct->ct_lun); break; case CT_RSELTMO: @@ -1454,8 +1498,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) isp_prt(isp, ISP_LOGERR, "CTIO returned by f/w- %s", fmsg); break; default: - isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", - ct->ct_status & ~QLTM_SVALID); + isp_prt(isp, ISP_LOGERR, "Unknown CTIO status 0x%x", ct->ct_status & ~QLTM_SVALID); break; } @@ -1469,16 +1512,12 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct) */ if (ct->ct_syshandle == 0) { if ((ct->ct_flags & CT_SENDSTATUS) == 0) { - isp_prt(isp, pl, - "intermediate CTIO completed ok"); + isp_prt(isp, pl, "intermediate CTIO completed ok"); } else { - isp_prt(isp, pl, - "unmonitored CTIO completed ok"); + isp_prt(isp, pl, "unmonitored CTIO completed ok"); } } else { - isp_prt(isp, pl, - "NO xs for CTIO (handle 0x%x) status 0x%x", - ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); + isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); } } else { /* @@ -1553,8 +1592,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) fmsg = "ABORT"; } - isp_prt(isp, ISP_LOGTDEBUG0, - "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); + isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); break; case CT_INVAL: @@ -1599,13 +1637,11 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) * CTIO rejected by the firmware because an invalid RX_ID. * Just print a message. */ - isp_prt(isp, ISP_LOGWARN, - "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); + isp_prt(isp, ISP_LOGWARN, "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid); break; default: - isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", - ct->ct_status & ~QLTM_SVALID); + isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x", ct->ct_status & ~QLTM_SVALID); break; } @@ -1619,16 +1655,12 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct) */ if (ct->ct_syshandle == 0) { if ((ct->ct_flags & CT2_SENDSTATUS) == 0) { - isp_prt(isp, pl, - "intermediate CTIO completed ok"); + isp_prt(isp, pl, "intermediate CTIO completed ok"); } else { - isp_prt(isp, pl, - "unmonitored CTIO completed ok"); + isp_prt(isp, pl, "unmonitored CTIO completed ok"); } } else { - isp_prt(isp, pl, - "NO xs for CTIO (handle 0x%x) status 0x%x", - ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); + isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_status & ~QLTM_SVALID); } } else { if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { @@ -1704,8 +1736,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) if (fmsg == NULL) { fmsg = "ABORT"; } - isp_prt(isp, ISP_LOGTDEBUG0, - "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); + isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid); break; case CT7_TIMEOUT: @@ -1740,8 +1771,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) * CTIO rejected by the firmware because an invalid RX_ID. * Just print a message. */ - isp_prt(isp, ISP_LOGWARN, - "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); + isp_prt(isp, ISP_LOGWARN, "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid); break; case CT7_REASSY_ERR: @@ -1753,8 +1783,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) break; default: - isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", - ct->ct_nphdl); + isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x", ct->ct_nphdl); break; } @@ -1768,26 +1797,20 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct) */ if (ct->ct_syshandle == 0) { if (ct->ct_flags & CT7_TERMINATE) { - isp_prt(isp, ISP_LOGINFO, - "termination of 0x%x complete", - ct->ct_rxid); + isp_prt(isp, ISP_LOGINFO, "termination of 0x%x complete", ct->ct_rxid); } else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) { - isp_prt(isp, pl, - "intermediate CTIO completed ok"); + isp_prt(isp, pl, "intermediate CTIO completed ok"); } else { - isp_prt(isp, pl, - "unmonitored CTIO completed ok"); + isp_prt(isp, pl, "unmonitored CTIO completed ok"); } } else { - isp_prt(isp, pl, - "NO xs for CTIO (handle 0x%x) status 0x%x", - ct->ct_syshandle, ct->ct_nphdl); + isp_prt(isp, pl, "NO xs for CTIO (handle 0x%x) status 0x%x", ct->ct_syshandle, ct->ct_nphdl); } } else { - if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { + if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { ISP_DMAFREE(isp, xs, ct->ct_syshandle); } - if (ct->ct_flags & CT2_SENDSTATUS) { + if (ct->ct_flags & CT7_SENDSTATUS) { /* * Sent status and command complete. * @@ -1816,30 +1839,25 @@ isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) { uint8_t ochan, chan, lochan, hichan; - /* * Check to see whether we got a wildcard channel. * If so, we have to iterate over all channels. */ - ochan = chan = inot_24xx->in_vpindex; + ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx); if (chan == 0xff) { lochan = 0; hichan = isp->isp_nchan; } else { if (chan >= isp->isp_nchan) { - isp_prt(isp, ISP_LOGINFO, - "%s: bad channel %d for status 0x%x", - __FUNCTION__, chan, inot_24xx->in_status); - isp_notify_ack(isp, inot_24xx); + isp_prt(isp, ISP_LOGINFO, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status); + isp_print_bytes(isp, "XXX", QENTRY_LEN, inot_24xx); + (void) isp_notify_ack(isp, inot_24xx); return; } lochan = chan; hichan = chan + 1; } - isp_prt(isp, ISP_LOGTDEBUG0, - "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", - __FUNCTION__, lochan, hichan-1, inot_24xx->in_status, - inot_24xx->in_rxid); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid); for (chan = lochan; chan < hichan; chan++) { switch (inot_24xx->in_status) { case IN24XX_LIP_RESET: @@ -1849,17 +1867,15 @@ isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx) case IN24XX_LINK_FAILED: case IN24XX_SRR_RCVD: case IN24XX_ELS_RCVD: - inot_24xx->in_vpindex = chan; + inot_24xx->in_vpidx = chan; isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx); break; default: - isp_prt(isp, ISP_LOGINFO, - "%s: unhandled status (0x%x) for chan %d", - __FUNCTION__, inot_24xx->in_status, chan); - isp_notify_ack(isp, inot_24xx); + isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d", __func__, inot_24xx->in_status, chan); + (void) isp_notify_ack(isp, inot_24xx); break; } } - inot_24xx->in_vpindex = ochan; + inot_24xx->in_vpidx = ochan; } #endif diff --git a/qla_isp/common/isp_target.h b/qla_isp/common/isp_target.h index 672251222..f04cc689e 100644 --- a/qla_isp/common/isp_target.h +++ b/qla_isp/common/isp_target.h @@ -1,18 +1,18 @@ -/* $Id: isp_target.h,v 1.60 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_target.h,v 1.63 2009/02/01 23:49:49 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as published * by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ /* @@ -58,897 +58,53 @@ #ifndef _ISP_TARGET_H #define _ISP_TARGET_H -#define QLTM_SENSELEN 18 /* non-FC cards only */ -#define QLTM_SVALID 0x80 - /* - * Structure for Enable Lun and Modify Lun queue entries + * Notify structure- these are for asynchronous events that need to be sent + * as notifications to the outer layer. It should be pretty self-explanatory. */ -typedef struct { - isphdr_t le_header; - uint32_t le_reserved; - uint8_t le_lun; - uint8_t le_rsvd; - uint8_t le_ops; /* Modify LUN only */ - uint8_t le_tgt; /* Not for FC */ - uint32_t le_flags; /* Not for FC */ - uint8_t le_status; - uint8_t le_reserved2; - uint8_t le_cmd_count; - uint8_t le_in_count; - uint8_t le_cdb6len; /* Not for FC */ - uint8_t le_cdb7len; /* Not for FC */ - uint16_t le_timeout; - uint16_t le_reserved3[20]; -} lun_entry_t; - -/* - * le_flags values - */ -#define LUN_TQAE 0x00000002 /* bit1 Tagged Queue Action Enable */ -#define LUN_DSSM 0x01000000 /* bit24 Disable Sending SDP Message */ -#define LUN_DISAD 0x02000000 /* bit25 Disable autodisconnect */ -#define LUN_DM 0x40000000 /* bit30 Disconnects Mandatory */ - -/* - * le_ops values - */ -#define LUN_CCINCR 0x01 /* increment command count */ -#define LUN_CCDECR 0x02 /* decrement command count */ -#define LUN_ININCR 0x40 /* increment immed. notify count */ -#define LUN_INDECR 0x80 /* decrement immed. notify count */ - -/* - * le_status values - */ -#define LUN_OK 0x01 /* we be rockin' */ -#define LUN_ERR 0x04 /* request completed with error */ -#define LUN_INVAL 0x06 /* invalid request */ -#define LUN_NOCAP 0x16 /* can't provide requested capability */ -#define LUN_ENABLED 0x3E /* LUN already enabled */ - -/* - * Immediate Notify Entry structure - */ -#define IN_MSGLEN 8 /* 8 bytes */ -#define IN_RSVDLEN 8 /* 8 words */ -typedef struct { - isphdr_t in_header; - uint32_t in_reserved; - uint8_t in_lun; /* lun */ - uint8_t in_iid; /* initiator */ - uint8_t in_reserved2; - uint8_t in_tgt; /* target */ - uint32_t in_flags; - uint8_t in_status; - uint8_t in_rsvd2; - uint8_t in_tag_val; /* tag value */ - uint8_t in_tag_type; /* tag type */ - uint16_t in_seqid; /* sequence id */ - uint8_t in_msg[IN_MSGLEN]; /* SCSI message bytes */ - uint16_t in_reserved3[IN_RSVDLEN]; - uint8_t in_sense[QLTM_SENSELEN];/* suggested sense data */ -} in_entry_t; - -typedef struct { - isphdr_t in_header; - uint32_t in_reserved; - uint8_t in_lun; /* lun */ - uint8_t in_iid; /* initiator */ - uint16_t in_scclun; - uint32_t in_reserved2; - uint16_t in_status; - uint16_t in_task_flags; - uint16_t in_seqid; /* sequence id */ -} in_fcentry_t; - -typedef struct { - isphdr_t in_header; - uint32_t in_reserved; - uint16_t in_iid; /* initiator */ - uint16_t in_scclun; - uint32_t in_reserved2; - uint16_t in_status; - uint16_t in_task_flags; - uint16_t in_seqid; /* sequence id */ -} in_fcentry_e_t; - -/* - * Values for the in_status field - */ -#define IN_REJECT 0x0D /* Message Reject message received */ -#define IN_RESET 0x0E /* Bus Reset occurred */ -#define IN_NO_RCAP 0x16 /* requested capability not available */ -#define IN_IDE_RECEIVED 0x33 /* Initiator Detected Error msg received */ -#define IN_RSRC_UNAVAIL 0x34 /* resource unavailable */ -#define IN_MSG_RECEIVED 0x36 /* SCSI message received */ -#define IN_ABORT_TASK 0x20 /* task named in RX_ID is being aborted (FC) */ -#define IN_PORT_LOGOUT 0x29 /* port has logged out (FC) */ -#define IN_PORT_CHANGED 0x2A /* port changed */ -#define IN_GLOBAL_LOGO 0x2E /* all ports logged out */ -#define IN_NO_NEXUS 0x3B /* Nexus not established */ - -/* - * Values for the in_task_flags field- should only get one at a time! - */ -#define TASK_FLAGS_RESERVED_MASK (0xe700) -#define TASK_FLAGS_CLEAR_ACA (1<<14) -#define TASK_FLAGS_TARGET_RESET (1<<13) -#define TASK_FLAGS_LUN_RESET (1<<12) -#define TASK_FLAGS_CLEAR_TASK_SET (1<<10) -#define TASK_FLAGS_ABORT_TASK_SET (1<<9) - -/* - * ISP24XX Immediate Notify - */ -typedef struct { - isphdr_t in_header; - uint32_t in_reserved; - uint16_t in_nphdl; - uint16_t in_reserved1; - uint16_t in_flags; - uint16_t in_srr_rxid; - uint16_t in_status; - uint8_t in_status_subcode; - uint8_t in_reserved2; - uint32_t in_rxid; - uint16_t in_srr_reloff_lo; - uint16_t in_srr_reloff_hi; - uint16_t in_srr_iu; - uint16_t in_srr_oxid; - /* - * If bit 2 is set in in_flags, the following - * two tags are valid. If the received ELS is - * a LOGO, then these tags contain the N Port ID - * from the LOGO payload. If the received ELS - * request is TPRLO, these tags contain the - * Third Party Originator N Port ID. - */ - uint16_t in_nport_id_hi; - uint8_t in_nport_id_lo; - uint8_t in_reserved3; - /* - * If bit 2 is set in in_flags, the following - * tag is valid. If the received ELS is a LOGO, - * then this tag contains the n-port handle - * from the LOGO payload. If the received ELS - * request is TPRLO, this tag contain the - * n-port handle for the Third Party Originator. - */ - uint16_t in_np_handle; - uint8_t in_reserved4[12]; - uint8_t in_reserved5; - uint8_t in_vpindex; - uint32_t in_reserved6; - uint16_t in_portid_lo; - uint8_t in_portid_hi; - uint8_t in_reserved7; - uint16_t in_reserved8; - uint16_t in_oxid; -} in_fcentry_24xx_t; - -#define IN24XX_FLAG_PUREX_IOCB 0x1 -#define IN24XX_FLAG_GLOBAL_LOGOUT 0x2 -#define IN24XX_FLAG_NPHDL_VALID 0x4 - -#define IN24XX_LIP_RESET 0x0E -#define IN24XX_LINK_RESET 0x0F -#define IN24XX_PORT_LOGOUT 0x29 -#define IN24XX_PORT_CHANGED 0x2A -#define IN24XX_LINK_FAILED 0x2E -#define IN24XX_SRR_RCVD 0x45 -#define IN24XX_ELS_RCVD 0x46 /* - * login-affectin ELS received- check - * subcode for specific opcode - */ - -/* - * For f/w > 4.0.25, these offsets in the Immediate Notify contain - * the WWNN/WWPN if the ELS is PLOGI, PDISC or ADISC. The WWN is in - * Big Endian format. - */ -#define IN24XX_PLOGI_WWNN_OFF 0x20 -#define IN24XX_PLOGI_WWPN_OFF 0x28 - -/* - * For f/w > 4.0.25, this offset in the Immediate Notify contain - * the WWPN if the ELS is LOGO. The WWN is in Big Endian format. - */ -#define IN24XX_LOGO_WWPN_OFF 0x28 - -/* - * Notify Acknowledge Entry structure - */ -#define NA_RSVDLEN 22 -typedef struct { - isphdr_t na_header; - uint32_t na_reserved; - uint8_t na_lun; /* lun */ - uint8_t na_iid; /* initiator */ - uint8_t na_reserved2; - uint8_t na_tgt; /* target */ - uint32_t na_flags; - uint8_t na_status; - uint8_t na_event; - uint16_t na_seqid; /* sequence id */ - uint16_t na_reserved3[NA_RSVDLEN]; -} na_entry_t; - -/* - * Value for the na_event field - */ -#define NA_RST_CLRD 0x80 /* Clear an async event notification */ -#define NA_OK 0x01 /* Notify Acknowledge Succeeded */ -#define NA_INVALID 0x06 /* Invalid Notify Acknowledge */ - -#define NA2_RSVDLEN 21 -typedef struct { - isphdr_t na_header; - uint32_t na_reserved; - uint8_t na_reserved1; - uint8_t na_iid; /* initiator loop id */ - uint16_t na_response; - uint16_t na_flags; - uint16_t na_reserved2; - uint16_t na_status; - uint16_t na_task_flags; - uint16_t na_seqid; /* sequence id */ - uint16_t na_reserved3[NA2_RSVDLEN]; -} na_fcentry_t; - -typedef struct { - isphdr_t na_header; - uint32_t na_reserved; - uint16_t na_iid; /* initiator loop id */ - uint16_t na_response; /* response code */ - uint16_t na_flags; - uint16_t na_reserved2; - uint16_t na_status; - uint16_t na_task_flags; - uint16_t na_seqid; /* sequence id */ - uint16_t na_reserved3[NA2_RSVDLEN]; -} na_fcentry_e_t; - -#define NAFC_RCOUNT 0x80 /* increment resource count */ -#define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */ -#define NAFC_TVALID 0x10 /* task mangement response code is valid */ - -/* - * ISP24XX Notify Acknowledge - */ - -typedef struct { - isphdr_t na_header; - uint32_t na_handle; - uint16_t na_nphdl; - uint16_t na_reserved1; - uint16_t na_flags; - uint16_t na_srr_rxid; - uint16_t na_status; - uint8_t na_status_subcode; - uint8_t na_reserved2; - uint32_t na_rxid; - uint16_t na_srr_reloff_lo; - uint16_t na_srr_reloff_hi; - uint16_t na_srr_iu; - uint16_t na_srr_flags; - uint8_t na_reserved3[18]; - uint8_t na_reserved4; - uint8_t na_vpindex; - uint8_t na_srr_reject_vunique; - uint8_t na_srr_reject_explanation; - uint8_t na_srr_reject_code; - uint8_t na_reserved5; - uint8_t na_reserved6[6]; - uint16_t na_oxid; -} na_fcentry_24xx_t; - -/* - * Accept Target I/O Entry structure - */ -#define ATIO_CDBLEN 26 - -typedef struct { - isphdr_t at_header; - uint16_t at_reserved; - uint16_t at_handle; - uint8_t at_lun; /* lun */ - uint8_t at_iid; /* initiator */ - uint8_t at_cdblen; /* cdb length */ - uint8_t at_tgt; /* target */ - uint32_t at_flags; - uint8_t at_status; /* firmware status */ - uint8_t at_scsi_status; /* scsi status */ - uint8_t at_tag_val; /* tag value */ - uint8_t at_tag_type; /* tag type */ - uint8_t at_cdb[ATIO_CDBLEN]; /* received CDB */ - uint8_t at_sense[QLTM_SENSELEN];/* suggested sense data */ -} at_entry_t; - -/* - * at_flags values - */ -#define AT_NODISC 0x00008000 /* disconnect disabled */ -#define AT_TQAE 0x00000002 /* Tagged Queue Action enabled */ - -/* - * at_status values - */ -#define AT_PATH_INVALID 0x07 /* ATIO sent to firmware for disabled lun */ -#define AT_RESET 0x0E /* SCSI Bus Reset Occurred */ -#define AT_PHASE_ERROR 0x14 /* Bus phase sequence error */ -#define AT_NOCAP 0x16 /* Requested capability not available */ -#define AT_BDR_MSG 0x17 /* Bus Device Reset msg received */ -#define AT_CDB 0x3D /* CDB received */ -/* - * Macros to create and fetch and test concatenated handle and tag value macros - */ - -#define AT_MAKE_TAGID(tid, bus, inst, aep) \ - tid = aep->at_handle; \ - if (aep->at_flags & AT_TQAE) { \ - tid |= (aep->at_tag_val << 16); \ - tid |= (1 << 24); \ - } \ - tid |= (bus << 25); \ - tid |= (inst << 26) - -#define CT_MAKE_TAGID(tid, bus, inst, ct) \ - tid = ct->ct_fwhandle; \ - if (ct->ct_flags & CT_TQAE) { \ - tid |= (ct->ct_tag_val << 16); \ - tid |= (1 << 24); \ - } \ - tid |= ((bus & 0x1) << 25); \ - tid |= (inst << 26) - -#define AT_HAS_TAG(val) ((val) & (1 << 24)) -#define AT_GET_TAG(val) (((val) >> 16) & 0xff) -#define AT_GET_INST(val) (((val) >> 26) & 0x3f) -#define AT_GET_BUS(val) (((val) >> 25) & 0x1) -#define AT_GET_HANDLE(val) ((val) & 0xffff) - -#define IN_MAKE_TAGID(tid, bus, inst, inp) \ - tid = inp->in_seqid; \ - tid |= (inp->in_tag_val << 16); \ - tid |= (1 << 24); \ - tid |= (bus << 25); \ - tid |= (inst << 26) - -#define TAG_INSERT_INST(tid, inst) \ - tid &= ~(0x3ffffff); \ - tid |= (inst << 26) - -#define TAG_INSERT_BUS(tid, bus) \ - tid &= ~(1 << 25); \ - tid |= (bus << 25) - -/* - * Accept Target I/O Entry structure, Type 2 - */ -#define ATIO2_CDBLEN 16 - -typedef struct { - isphdr_t at_header; - uint32_t at_reserved; - uint8_t at_lun; /* lun or reserved */ - uint8_t at_iid; /* initiator */ - uint16_t at_rxid; /* response ID */ - uint16_t at_flags; - uint16_t at_status; /* firmware status */ - uint8_t at_crn; /* command reference number */ - uint8_t at_taskcodes; - uint8_t at_taskflags; - uint8_t at_execodes; - uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */ - uint32_t at_datalen; /* allocated data len */ - uint16_t at_scclun; /* SCC Lun or reserved */ - uint16_t at_wwpn[4]; /* WWPN of initiator */ - uint16_t at_reserved2[6]; - uint16_t at_oxid; -} at2_entry_t; - -typedef struct { - isphdr_t at_header; - uint32_t at_reserved; - uint16_t at_iid; /* initiator */ - uint16_t at_rxid; /* response ID */ - uint16_t at_flags; - uint16_t at_status; /* firmware status */ - uint8_t at_crn; /* command reference number */ - uint8_t at_taskcodes; - uint8_t at_taskflags; - uint8_t at_execodes; - uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */ - uint32_t at_datalen; /* allocated data len */ - uint16_t at_scclun; /* SCC Lun or reserved */ - uint16_t at_wwpn[4]; /* WWPN of initiator */ - uint16_t at_reserved2[6]; - uint16_t at_oxid; -} at2e_entry_t; - -#define ATIO2_WWPN_OFFSET 0x2A -#define ATIO2_OXID_OFFSET 0x3E - -#define ATIO2_TC_ATTR_MASK 0x7 -#define ATIO2_TC_ATTR_SIMPLEQ 0 -#define ATIO2_TC_ATTR_HEADOFQ 1 -#define ATIO2_TC_ATTR_ORDERED 2 -#define ATIO2_TC_ATTR_ACAQ 4 -#define ATIO2_TC_ATTR_UNTAGGED 5 - -#define ATIO2_EX_WRITE 0x1 -#define ATIO2_EX_READ 0x2 -/* - * Macros to create and fetch and test concatenated handle and tag value macros - */ -#define AT2_MAKE_TAGID(tid, bus, inst, aep) \ - tid = aep->at_rxid; \ - tid |= (((uint64_t)inst) << 32); \ - tid |= (((uint64_t)bus) << 48) - -#define CT2_MAKE_TAGID(tid, bus, inst, ct) \ - tid = ct->ct_rxid; \ - tid |= (((uint64_t)inst) << 32); \ - tid |= (((uint64_t)(bus & 0xff)) << 48) - -#define AT2_HAS_TAG(val) 1 -#define AT2_GET_TAG(val) ((val) & 0xffffffff) -#define AT2_GET_INST(val) (((val) >> 32) & 0xffff) -#define AT2_GET_HANDLE AT2_GET_TAG -#define AT2_GET_BUS(val) (((val) >> 48) & 0xff) - -#define FC_HAS_TAG AT2_HAS_TAG -#define FC_GET_TAG AT2_GET_TAG -#define FC_GET_INST AT2_GET_INST -#define FC_GET_HANDLE AT2_GET_HANDLE - -#define IN_FC_MAKE_TAGID(tid, bus, inst, seqid) \ - tid = seqid; \ - tid |= (((uint64_t)inst) << 32); \ - tid |= (((uint64_t)(bus & 0xff)) << 48) - -#define FC_TAG_INSERT_INST(tid, inst) \ - tid &= ~0x0000ffff00000000ull; \ - tid |= (((uint64_t)inst) << 32) - -/* - * 24XX ATIO Definition - * - * This is *quite* different from other entry types. - * First of all, it has its own queue it comes in on. - * - * Secondly, it doesn't have a normal header. - * - * Thirdly, it's just a passthru of the FCP CMND IU - * which is recorded in big endian mode. - */ -typedef struct { - uint8_t at_type; - uint8_t at_count; - /* - * Task attribute in high four bits, - * the rest is the FCP CMND IU Length. - * NB: the command can extend past the - * length for a single queue entry. - */ - uint16_t at_ta_len; - uint32_t at_rxid; - fc_hdr_t at_hdr; - fcp_cmnd_iu_t at_cmnd; -} at7_entry_t; -#define AT7_NORESRC_RXID 0xffffffff - - -/* - * Continue Target I/O Entry structure - * Request from driver. The response from the - * ISP firmware is the same except that the last 18 - * bytes are overwritten by suggested sense data if - * the 'autosense valid' bit is set in the status byte. - */ -typedef struct { - isphdr_t ct_header; - uint16_t ct_syshandle; - uint16_t ct_fwhandle; /* required by f/w */ - uint8_t ct_lun; /* lun */ - uint8_t ct_iid; /* initiator id */ - uint8_t ct_reserved2; - uint8_t ct_tgt; /* our target id */ - uint32_t ct_flags; - uint8_t ct_status; /* isp status */ - uint8_t ct_scsi_status; /* scsi status */ - uint8_t ct_tag_val; /* tag value */ - uint8_t ct_tag_type; /* tag type */ - uint32_t ct_xfrlen; /* transfer length */ - uint32_t ct_resid; /* residual length */ - uint16_t ct_timeout; - uint16_t ct_seg_count; - ispds_t ct_dataseg[ISP_RQDSEG]; -} ct_entry_t; - -/* - * For some of the dual port SCSI adapters, port (bus #) is reported - * in the MSbit of ct_iid. Bit fields are a bit too awkward here. - * - * Note that this does not apply to FC adapters at all which can and - * do report IIDs between 0x81 && 0xfe (or 0x7ff) which represent devices - * that have logged in across a SCSI fabric. - */ -#define GET_IID_VAL(x) (x & 0x3f) -#define GET_BUS_VAL(x) ((x >> 7) & 0x1) -#define SET_IID_VAL(y, x) y = ((y & ~0x3f) | (x & 0x3f)) -#define SET_BUS_VAL(y, x) y = ((y & 0x3f) | ((x & 0x1) << 7)) - -/* - * ct_flags values - */ -#define CT_TQAE 0x00000002 /* bit 1, Tagged Queue Action enable */ -#define CT_DATA_IN 0x00000040 /* bits 6&7, Data direction */ -#define CT_DATA_OUT 0x00000080 /* bits 6&7, Data direction */ -#define CT_NO_DATA 0x000000C0 /* bits 6&7, Data direction */ -#define CT_CCINCR 0x00000100 /* bit 8, autoincrement atio count */ -#define CT_DATAMASK 0x000000C0 /* bits 6&7, Data direction */ -#define CT_INISYNCWIDE 0x00004000 /* bit 14, Do Sync/Wide Negotiation */ -#define CT_NODISC 0x00008000 /* bit 15, Disconnects disabled */ -#define CT_DSDP 0x01000000 /* bit 24, Disable Save Data Pointers */ -#define CT_SENDRDP 0x04000000 /* bit 26, Send Restore Pointers msg */ -#define CT_SENDSTATUS 0x80000000 /* bit 31, Send SCSI status byte */ - -/* - * ct_status values - * - set by the firmware when it returns the CTIO - */ -#define CT_OK 0x01 /* completed without error */ -#define CT_ABORTED 0x02 /* aborted by host */ -#define CT_ERR 0x04 /* see sense data for error */ -#define CT_INVAL 0x06 /* request for disabled lun */ -#define CT_NOPATH 0x07 /* invalid ITL nexus */ -#define CT_INVRXID 0x08 /* (FC only) Invalid RX_ID */ -#define CT_DATA_OVER 0x09 /* (FC only) Data Overrun */ -#define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */ -#define CT_TIMEOUT 0x0B /* timed out */ -#define CT_RESET 0x0E /* SCSI Bus Reset occurred */ -#define CT_PARITY 0x0F /* Uncorrectable Parity Error */ -#define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */ -#define CT_PANIC 0x13 /* Unrecoverable Error */ -#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */ -#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */ -#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */ -#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */ -#define CT_PORTUNAVAIL 0x28 /* port not available */ -#define CT_LOGOUT 0x29 /* port logout */ -#define CT_PORTCHANGED 0x2A /* port changed */ -#define CT_IDE 0x33 /* Initiator Detected Error */ -#define CT_NOACK 0x35 /* Outstanding Immed. Notify. entry */ -#define CT_SRR 0x45 /* SRR Received */ -#define CT_LUN_RESET 0x48 /* Lun Reset Received */ - -/* - * When the firmware returns a CTIO entry, it may overwrite the last - * part of the structure with sense data. This starts at offset 0x2E - * into the entry, which is in the middle of ct_dataseg[1]. Rather - * than define a new struct for this, I'm just using the sense data - * offset. - */ -#define CTIO_SENSE_OFFSET 0x2E - -/* - * Entry length in u_longs. All entries are the same size so - * any one will do as the numerator. - */ -#define UINT32_ENTRY_SIZE (sizeof(at_entry_t)/sizeof(uint32_t)) - -/* - * QLA2100 CTIO (type 2) entry - */ -#define MAXRESPLEN 26 -typedef struct { - isphdr_t ct_header; - uint32_t ct_syshandle; - uint8_t ct_lun; /* lun */ - uint8_t ct_iid; /* initiator id */ - uint16_t ct_rxid; /* response ID */ - uint16_t ct_flags; - uint16_t ct_status; /* isp status */ - uint16_t ct_timeout; - uint16_t ct_seg_count; - uint32_t ct_reloff; /* relative offset */ - int32_t ct_resid; /* residual length */ - union { - /* - * The three different modes that the target driver - * can set the CTIO{2,3,4} up as. - * - * The first is for sending FCP_DATA_IUs as well as - * (optionally) sending a terminal SCSI status FCP_RSP_IU. - * - * The second is for sending SCSI sense data in an FCP_RSP_IU. - * Note that no FCP_DATA_IUs will be sent. - * - * The third is for sending FCP_RSP_IUs as built specifically - * in system memory as located by the isp_dataseg. - */ - struct { - uint32_t _reserved; - uint16_t _reserved2; - uint16_t ct_scsi_status; - uint32_t ct_xfrlen; - union { - ispds_t ct_dataseg[ISP_RQDSEG_T2]; - ispds64_t ct_dataseg64[ISP_RQDSEG_T3]; - ispdslist_t ct_dslist; - } u; - } m0; - struct { - uint16_t _reserved; - uint16_t _reserved2; - uint16_t ct_senselen; - uint16_t ct_scsi_status; - uint16_t ct_resplen; - uint8_t ct_resp[MAXRESPLEN]; - } m1; - struct { - uint32_t _reserved; - uint16_t _reserved2; - uint16_t _reserved3; - uint32_t ct_datalen; - ispds_t ct_fcp_rsp_iudata; - } m2; - } rsp; -} ct2_entry_t; - -typedef struct { - isphdr_t ct_header; - uint32_t ct_syshandle; - uint16_t ct_iid; /* initiator id */ - uint16_t ct_rxid; /* response ID */ - uint16_t ct_flags; - uint16_t ct_status; /* isp status */ - uint16_t ct_timeout; - uint16_t ct_seg_count; - uint32_t ct_reloff; /* relative offset */ - int32_t ct_resid; /* residual length */ - union { - struct { - uint32_t _reserved; - uint16_t _reserved2; - uint16_t ct_scsi_status; - uint32_t ct_xfrlen; - union { - ispds_t ct_dataseg[ISP_RQDSEG_T2]; - ispds64_t ct_dataseg64[ISP_RQDSEG_T3]; - ispdslist_t ct_dslist; - } u; - } m0; - struct { - uint16_t _reserved; - uint16_t _reserved2; - uint16_t ct_senselen; - uint16_t ct_scsi_status; - uint16_t ct_resplen; - uint8_t ct_resp[MAXRESPLEN]; - } m1; - struct { - uint32_t _reserved; - uint16_t _reserved2; - uint16_t _reserved3; - uint32_t ct_datalen; - ispds_t ct_fcp_rsp_iudata; - } m2; - } rsp; -} ct2e_entry_t; - -/* - * ct_flags values for CTIO2 - */ -#define CT2_FLAG_MODE0 0x0000 -#define CT2_FLAG_MODE1 0x0001 -#define CT2_FLAG_MODE2 0x0002 -#define CT2_FLAG_MMASK 0x0003 -#define CT2_DATA_IN 0x0040 -#define CT2_DATA_OUT 0x0080 -#define CT2_NO_DATA 0x00C0 -#define CT2_DATAMASK 0x00C0 -#define CT2_CCINCR 0x0100 -#define CT2_FASTPOST 0x0200 -#define CT2_CONFIRM 0x2000 -#define CT2_TERMINATE 0x4000 -#define CT2_SENDSTATUS 0x8000 - -/* - * ct_status values are (mostly) the same as that for ct_entry. - */ - -/* - * ct_scsi_status values- the low 8 bits are the normal SCSI status - * we know and love. The upper 8 bits are validity markers for FCP_RSP_IU - * fields. - */ -#define CT2_RSPLEN_VALID 0x0100 -#define CT2_SNSLEN_VALID 0x0200 -#define CT2_DATA_OVER 0x0400 -#define CT2_DATA_UNDER 0x0800 - -/* - * ISP24XX CTIO - */ -#define MAXRESPLEN_24XX 24 -typedef struct { - isphdr_t ct_header; - uint32_t ct_syshandle; - uint16_t ct_nphdl; /* status on returned CTIOs */ - uint16_t ct_timeout; - uint16_t ct_seg_count; - uint8_t ct_vpindex; - uint8_t ct_xflags; - uint16_t ct_iid_lo; /* low 16 bits of portid */ - uint8_t ct_iid_hi; /* hi 8 bits of portid */ - uint8_t ct_reserved; - uint32_t ct_rxid; - uint16_t ct_senselen; /* mode 1 only */ - uint16_t ct_flags; - int32_t ct_resid; /* residual length */ - uint16_t ct_oxid; - uint16_t ct_scsi_status; /* modes 0 && 1 only */ - union { - struct { - uint32_t reloff; - uint32_t reserved0; - uint32_t ct_xfrlen; - uint32_t reserved1; - ispds64_t ds; - } m0; - struct { - uint16_t ct_resplen; - uint16_t reserved; - uint8_t ct_resp[MAXRESPLEN_24XX]; - } m1; - struct { - uint32_t reserved0; - uint32_t ct_datalen; - uint32_t reserved1; - ispds64_t ct_fcp_rsp_iudata; - } m2; - } rsp; -} ct7_entry_t; - -/* - * ct_flags values for CTIO7 - */ -#define CT7_DATA_IN 0x0002 -#define CT7_DATA_OUT 0x0001 -#define CT7_NO_DATA 0x0000 -#define CT7_DATAMASK 0x003 -#define CT7_DSD_ENABLE 0x0004 -#define CT7_CONF_STSFD 0x0010 -#define CT7_EXPLCT_CONF 0x0020 -#define CT7_FLAG_MODE0 0x0000 -#define CT7_FLAG_MODE1 0x0040 -#define CT7_FLAG_MODE2 0x0080 -#define CT7_FLAG_MMASK 0x00C0 -#define CT7_NOACK 0x0100 -#define CT7_TASK_ATTR_SHIFT 9 -#define CT7_CONFIRM 0x2000 -#define CT7_TERMINATE 0x4000 -#define CT7_SENDSTATUS 0x8000 - -/* - * Type 7 CTIO status codes - */ -#define CT7_OK 0x01 /* completed without error */ -#define CT7_ABORTED 0x02 /* aborted by host */ -#define CT7_ERR 0x04 /* see sense data for error */ -#define CT7_INVAL 0x06 /* request for disabled lun */ -#define CT7_INVRXID 0x08 /* (FC only) Invalid RX_ID */ -#define CT7_DATA_OVER 0x09 /* (FC only) Data Overrun */ -#define CT7_TIMEOUT 0x0B /* timed out */ -#define CT7_RESET 0x0E /* LIP Rset Received */ -#define CT7_BUS_ERROR 0x10 /* DMA PCI Error */ -#define CT7_REASSY_ERR 0x11 /* DMA reassembly error */ -#define CT7_DATA_UNDER 0x15 /* (FC only) Data Underrun */ -#define CT7_PORTUNAVAIL 0x28 /* port not available */ -#define CT7_LOGOUT 0x29 /* port logout */ -#define CT7_PORTCHANGED 0x2A /* port changed */ -#define CT7_SRR 0x45 /* SRR Received */ - -/* - * Other 24XX related target IOCBs - */ - -/* - * ABTS Received - */ -typedef struct { - isphdr_t abts_header; - uint8_t abts_reserved0[6]; - uint16_t abts_nphdl; - uint16_t abts_reserved1; - uint16_t abts_sof; - uint32_t abts_rxid_abts; - uint16_t abts_did_lo; - uint8_t abts_did_hi; - uint8_t abts_r_ctl; - uint16_t abts_sid_lo; - uint8_t abts_sid_hi; - uint8_t abts_cs_ctl; - uint16_t abts_fs_ctl; - uint8_t abts_f_ctl; - uint8_t abts_type; - uint16_t abts_seq_cnt; - uint8_t abts_df_ctl; - uint8_t abts_seq_id; - uint16_t abts_rx_id; - uint16_t abts_ox_id; - uint32_t abts_param; - uint8_t abts_reserved2[16]; - uint32_t abts_rxid_task; -} abts_t; - -typedef struct { - isphdr_t abts_rsp_header; - uint32_t abts_rsp_handle; - uint16_t abts_rsp_status; - uint16_t abts_rsp_nphdl; - uint16_t abts_rsp_ctl_flags; - uint16_t abts_rsp_sof; - uint32_t abts_rsp_rxid_abts; - uint16_t abts_rsp_did_lo; - uint8_t abts_rsp_did_hi; - uint8_t abts_rsp_r_ctl; - uint16_t abts_rsp_sid_lo; - uint8_t abts_rsp_sid_hi; - uint8_t abts_rsp_cs_ctl; - uint16_t abts_rsp_f_ctl_lo; - uint8_t abts_rsp_f_ctl_hi; - uint8_t abts_rsp_type; - uint16_t abts_rsp_seq_cnt; - uint8_t abts_rsp_df_ctl; - uint8_t abts_rsp_seq_id; - uint16_t abts_rsp_rx_id; - uint16_t abts_rsp_ox_id; - uint32_t abts_rsp_param; - union { - struct { - uint16_t reserved; - uint8_t last_seq_id; - uint8_t seq_id_valid; - uint16_t aborted_rx_id; - uint16_t aborted_ox_id; - uint16_t high_seq_cnt; - uint16_t low_seq_cnt; - uint8_t reserved2[4]; - } ba_acc; - struct { - uint8_t vendor_unique; - uint8_t explanation; - uint8_t reason; - uint8_t reserved; - uint8_t reserved2[12]; - } ba_rjt; - struct { - uint8_t reserved[8]; - uint32_t subcode1; - uint32_t subcode2; - } rsp; - uint8_t reserved[16]; - } abts_rsp_payload; - uint32_t abts_rsp_rxid_task; -} abts_rsp_t; - -/* terminate this ABTS exchange */ -#define ISP24XX_ABTS_RSP_TERMINATE 0x01 - -#define ISP24XX_ABTS_RSP_COMPLETE 0x00 -#define ISP24XX_ABTS_RSP_RESET 0x04 -#define ISP24XX_ABTS_RSP_ABORTED 0x05 -#define ISP24XX_ABTS_RSP_TIMEOUT 0x06 -#define ISP24XX_ABTS_RSP_INVXID 0x08 -#define ISP24XX_ABTS_RSP_LOGOUT 0x29 -#define ISP24XX_ABTS_RSP_SUBCODE 0x31 - -#define ISP24XX_NO_TASK 0xffffffff +typedef enum { + NT_UNKNOWN=0x999, + NT_ABORT_TASK=0x1000, + NT_ABORT_TASK_SET, + NT_CLEAR_ACA, + NT_CLEAR_TASK_SET, + NT_LUN_RESET, + NT_TARGET_RESET, + NT_BUS_RESET, + NT_LIP_RESET, + NT_LINK_UP, + NT_LINK_DOWN, + NT_LOGOUT, + NT_HBA_RESET +} isp_ncode_t; +typedef struct isp_notify { + void * nt_hba; /* HBA tag */ + void * nt_tmd; + void * nt_lreserved; + void * nt_hreserved; + uint64_t nt_wwn; /* source (wwn) */ + uint64_t nt_tgt; /* destination (wwn) */ + uint64_t nt_tagval; /* tag value */ + uint32_t + nt_channel : 6, /* channel id */ + nt_sid : 24; /* source port id */ + uint32_t + nt_failed : 1, /* notify operation failed */ + nt_need_ack : 1, /* this notify needs an ACK */ + nt_did : 24; /* destination port id */ + uint32_t + nt_lun : 16, /* logical unit */ + nt_nphdl : 16; /* n-port handle */ + isp_ncode_t nt_ncode; /* action */ +} isp_notify_t; +#define MATCH_TMD(tmd, iid, lun, tag) \ + ( \ + (tmd) && \ + (iid == INI_ANY || iid == tmd->cd_iid) && \ + (lun == LUN_ANY || lun == tmd->cd_lun) && \ + (tag == TAG_ANY || tag == tmd->cd_tagval) \ + ) /* * Debug macros */ @@ -956,56 +112,12 @@ typedef struct { #define ISP_TDQE(isp, msg, idx, arg) \ if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg) -#ifndef ISP_TOOLS /* - * The functions below are for the publicly available - * target mode functions that are internal to the Qlogic driver. + * Special Constatns */ - -/* - * This function handles new response queue entry appropriate for target mode. - */ -int isp_target_notify(ispsoftc_t *, void *, uint32_t *); - -/* - * This function externalizes the ability to acknowledge an Immediate Notify - * request. - */ -void isp_notify_ack(ispsoftc_t *, void *); - -/* - * Enable/Disable/Modify a logical unit. - * (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt) - */ -#define DFLT_CMND_CNT 0xfe /* unmonitored */ -#define DFLT_INOT_CNT 0xfe /* unmonitored */ -int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int); - -/* - * General request queue 'put' routine for target mode entries. - */ -int isp_target_put_entry(ispsoftc_t *isp, void *); - -/* - * General routine to put back an ATIO entry- - * used for replenishing f/w resource counts. - * The argument is a pointer to a source ATIO - * or ATIO2. - */ -int isp_target_put_atio(ispsoftc_t *, void *); - -/* - * General routine to send a final CTIO for a command- used mostly for - * local responses. - */ -int isp_endcmd(ispsoftc_t *, ...); -#define ECMD_SVALID 0x100 - -/* - * Handle an asynchronous event - * - * Return nonzero if the interrupt that generated this event has been dismissed. - */ -int isp_target_async(ispsoftc_t *, int, int); -#endif +#define INI_ANY ((uint64_t) -1) +#define VALID_INI(ini) (ini != INI_NONE && ini != INI_ANY) +#define LUN_ANY 0xffff +#define TGT_ANY ((uint64_t) -1) +#define TAG_ANY ((uint64_t) 0) #endif /* _ISP_TARGET_H */ diff --git a/qla_isp/common/isp_tpublic.h b/qla_isp/common/isp_tpublic.h index d5f713b67..95c853296 100644 --- a/qla_isp/common/isp_tpublic.h +++ b/qla_isp/common/isp_tpublic.h @@ -1,18 +1,18 @@ -/* $Id: isp_tpublic.h,v 1.43 2008/04/15 22:40:52 mjacob Exp $ */ +/* $Id: isp_tpublic.h,v 1.44 2008/12/03 18:35:05 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as * published by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ /* @@ -71,6 +71,10 @@ #ifndef _ISP_TPUBLIC_H #define _ISP_TPUBLIC_H 1 +/* + * Include general target definitions + */ +#include "isp_target.h" /* * Action codes set by the Inner Layer for the outer layer to figure out what to do with. @@ -81,7 +85,7 @@ typedef enum { QOUT_DISABLE, /* the argument is a pointer to a enadis_t */ QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */ QOUT_TMD_DONE, /* the argument is a pointer to a tmd_xact_t */ - QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */ + QOUT_NOTIFY, /* the argument is a pointer to a isp_notify_t */ QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */ } tact_e; @@ -98,7 +102,7 @@ typedef enum { QIN_DISABLE, /* the argument is a pointer to a enadis_t */ QIN_TMD_CONT, /* the argument is a pointer to a tmd_xact_t */ QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */ - QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */ + QIN_NOTIFY_ACK, /* the argument is a pointer to a isp_notify_t */ QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */ } qact_e; @@ -160,57 +164,6 @@ typedef struct { uint64_t * d_wwpns; } fc_dlist_t; -/* - * Notify structure- these are for asynchronous events that need to be sent - * as notifications to the outer layer. It should be pretty self-explanatory. - */ -typedef enum { - NT_UNKNOWN=0x999, - NT_ABORT_TASK=0x1000, - NT_ABORT_TASK_SET, - NT_CLEAR_ACA, - NT_CLEAR_TASK_SET, - NT_LUN_RESET, - NT_TARGET_RESET, - NT_BUS_RESET, - NT_LIP_RESET, - NT_LINK_UP, - NT_LINK_DOWN, - NT_LOGOUT, - NT_HBA_RESET -} tmd_ncode_t; - -typedef struct tmd_notify { - void * nt_hba; /* HBA tag */ - uint64_t nt_iid; /* inititator id */ - uint64_t nt_tgt; /* target id */ - uint16_t nt_lun; /* logical unit */ - uint16_t : 15, - nt_need_ack : 1; /* this notify needs an ACK */ - uint64_t nt_tagval; /* tag value */ - uint32_t nt_channel; /* channel id */ - tmd_ncode_t nt_ncode; /* action */ - void * nt_tmd; /* TMD for this notify */ - void * nt_lreserved; - void * nt_hreserved; -} tmd_notify_t; -#define LUN_ANY 0xffff -#define TGT_ANY ((uint64_t) -1) -#ifdef INI_ANY -#define INI_ANY ((uint64_t) -1) -#endif -#ifndef INI_NONE -#define INI_NONE ((uint64_t) 0) -#endif -#define TAG_ANY ((uint64_t) 0) -#define MATCH_TMD(tmd, iid, lun, tag) \ - ( \ - (tmd) && \ - (iid == INI_ANY || iid == tmd->cd_iid) && \ - (lun == LUN_ANY || lun == tmd->cd_lun) && \ - (tag == TAG_ANY || tag == tmd->cd_tagval) \ - ) - /* * Lun ENABLE/DISABLE * @@ -290,6 +243,7 @@ typedef struct tmd_xact { #define TDFL_SENTSTATUS 0x01 /* this transaction sent status */ #define TDFL_SENTSENSE 0x02 /* this transaction sent sense data */ #define TDFL_ERROR 0x04 /* this transaction had an error */ +#define TDFL_SYNCERROR 0x08 /* ... and didn't even start because of it */ #define TDFL_PRIVATE 0xF0 /* private inner layer usage */ /* @@ -349,7 +303,7 @@ typedef struct tmd_xact { * The cd_xact tag is the first or only transaction structure related to this command. * * The tag cd_lreserved, cd_hreserved are scratch areas for use for the outer and inner layers respectively. - * + * */ #ifndef TMD_CDBLEN @@ -441,6 +395,7 @@ struct tmd_cmd { * * void scsi_target_handler(tact_e, void *arg) */ + #endif /* _ISP_TPUBLIC_H */ /* * vim:ts=4:sw=4:expandtab diff --git a/qla_isp/common/ispmbox.h b/qla_isp/common/ispmbox.h index 39acdd327..09d6ddbb3 100644 --- a/qla_isp/common/ispmbox.h +++ b/qla_isp/common/ispmbox.h @@ -1,18 +1,18 @@ -/* $Id: ispmbox.h,v 1.72 2008/03/12 22:57:37 mjacob Exp $ */ +/* $Id: ispmbox.h,v 1.76 2009/02/01 23:49:49 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as published * by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ /* @@ -326,7 +326,9 @@ typedef struct { #define RQSFLAG_FULL 0x02 #define RQSFLAG_BADHEADER 0x04 #define RQSFLAG_BADPACKET 0x08 -#define RQSFLAG_MASK 0x0f +#define RQSFLAG_BADCOUNT 0x10 +#define RQSFLAG_BADORDER 0x20 +#define RQSFLAG_MASK 0x3f /* RQS entry_type definitions */ #define RQSTYPE_REQUEST 0x01 @@ -399,7 +401,7 @@ typedef struct { uint16_t mrk_lun; uint8_t mrk_reserved1[48]; } isp_marker_t; - + typedef struct { isphdr_t mrk_header; uint32_t mrk_handle; @@ -412,7 +414,7 @@ typedef struct { uint8_t mrk_lun[8]; uint8_t mrk_reserved3[40]; } isp_marker_24xx_t; - + #define SYNC_DEVICE 0 #define SYNC_TARGET 1 @@ -666,7 +668,7 @@ typedef struct { uint8_t req_rsp_sense[28]; } isp24xx_statusreq_t; -/* +/* * For Qlogic 2X00, the high order byte of SCSI status has * additional meaning. */ @@ -719,7 +721,7 @@ typedef struct { ispds64_t ms_dataseg[2]; } isp_ms_t; -/* +/* * Completion Status Codes. */ #define RQCS_COMPLETE 0x0000 @@ -771,7 +773,7 @@ typedef struct { /* - * 1X00 specific State Flags + * 1X00 specific State Flags */ #define RQSF_GOT_BUS 0x0100 #define RQSF_GOT_TARGET 0x0200 @@ -857,6 +859,9 @@ typedef struct { #define ISP_CAP_MULTI_ID(isp) \ (IS_24XX(isp)? (isp->isp_fwattr & ISP2400_FW_ATTR_MULTIID) : 0) +#define ISP_GET_VPIDX(isp, tag) \ + (ISP_CAP_MULTI_ID(isp) ? tag : 0) + /* * Reduced Interrupt Operation Response Queue Entreis */ @@ -952,7 +957,7 @@ typedef struct { #define ICBXOPT_RIO_32BIT 2 #define ICBXOPT_RIO_16BIT_IOCB 3 #define ICBXOPT_RIO_32BIT_IOCB 4 -#define ICBXOPT_ZIO 5 +#define ICBXOPT_ZIO 5 #define ICBXOPT_TIMER_MASK 0x7 #define ICBZOPT_RATE_MASK 0xC000 @@ -1045,7 +1050,7 @@ typedef struct { uint16_t icb_prqstqlen; uint16_t icb_rqstaddr[4]; uint16_t icb_respaddr[4]; - uint16_t icb_priaddr[4]; + uint16_t icb_priaddr[4]; uint16_t icb_reserved1[4]; uint16_t icb_atio_in; uint16_t icb_atioqlen; @@ -1619,14 +1624,14 @@ typedef struct { typedef struct { uint16_t handle; uint16_t lun; - uint32_t + uint32_t channel : 8, portid : 24; uint32_t timeout; union { struct { uint32_t data_length; - uint32_t + uint32_t no_wait : 1, do_read : 1; uint8_t cdb[16]; @@ -1641,4 +1646,906 @@ typedef struct { } end; } fcd; } isp_xcmd_t; + +/* + * Target Mode related definitions + */ +#define QLTM_SENSELEN 18 /* non-FC cards only */ +#define QLTM_SVALID 0x80 + +/* + * Structure for Enable Lun and Modify Lun queue entries + */ +typedef struct { + isphdr_t le_header; + uint32_t le_reserved; + uint8_t le_lun; + uint8_t le_rsvd; + uint8_t le_ops; /* Modify LUN only */ + uint8_t le_tgt; /* Not for FC */ + uint32_t le_flags; /* Not for FC */ + uint8_t le_status; + uint8_t le_reserved2; + uint8_t le_cmd_count; + uint8_t le_in_count; + uint8_t le_cdb6len; /* Not for FC */ + uint8_t le_cdb7len; /* Not for FC */ + uint16_t le_timeout; + uint16_t le_reserved3[20]; +} lun_entry_t; + +/* + * le_flags values + */ +#define LUN_TQAE 0x00000002 /* bit1 Tagged Queue Action Enable */ +#define LUN_DSSM 0x01000000 /* bit24 Disable Sending SDP Message */ +#define LUN_DISAD 0x02000000 /* bit25 Disable autodisconnect */ +#define LUN_DM 0x40000000 /* bit30 Disconnects Mandatory */ + +/* + * le_ops values + */ +#define LUN_CCINCR 0x01 /* increment command count */ +#define LUN_CCDECR 0x02 /* decrement command count */ +#define LUN_ININCR 0x40 /* increment immed. notify count */ +#define LUN_INDECR 0x80 /* decrement immed. notify count */ + +/* + * le_status values + */ +#define LUN_OK 0x01 /* we be rockin' */ +#define LUN_ERR 0x04 /* request completed with error */ +#define LUN_INVAL 0x06 /* invalid request */ +#define LUN_NOCAP 0x16 /* can't provide requested capability */ +#define LUN_ENABLED 0x3E /* LUN already enabled */ + +/* + * Immediate Notify Entry structure + */ +#define IN_MSGLEN 8 /* 8 bytes */ +#define IN_RSVDLEN 8 /* 8 words */ +typedef struct { + isphdr_t in_header; + uint32_t in_reserved; + uint8_t in_lun; /* lun */ + uint8_t in_iid; /* initiator */ + uint8_t in_reserved2; + uint8_t in_tgt; /* target */ + uint32_t in_flags; + uint8_t in_status; + uint8_t in_rsvd2; + uint8_t in_tag_val; /* tag value */ + uint8_t in_tag_type; /* tag type */ + uint16_t in_seqid; /* sequence id */ + uint8_t in_msg[IN_MSGLEN]; /* SCSI message bytes */ + uint16_t in_reserved3[IN_RSVDLEN]; + uint8_t in_sense[QLTM_SENSELEN];/* suggested sense data */ +} in_entry_t; + +typedef struct { + isphdr_t in_header; + uint32_t in_reserved; + uint8_t in_lun; /* lun */ + uint8_t in_iid; /* initiator */ + uint16_t in_scclun; + uint32_t in_reserved2; + uint16_t in_status; + uint16_t in_task_flags; + uint16_t in_seqid; /* sequence id */ +} in_fcentry_t; + +typedef struct { + isphdr_t in_header; + uint32_t in_reserved; + uint16_t in_iid; /* initiator */ + uint16_t in_scclun; + uint32_t in_reserved2; + uint16_t in_status; + uint16_t in_task_flags; + uint16_t in_seqid; /* sequence id */ +} in_fcentry_e_t; + +/* + * Values for the in_status field + */ +#define IN_REJECT 0x0D /* Message Reject message received */ +#define IN_RESET 0x0E /* Bus Reset occurred */ +#define IN_NO_RCAP 0x16 /* requested capability not available */ +#define IN_IDE_RECEIVED 0x33 /* Initiator Detected Error msg received */ +#define IN_RSRC_UNAVAIL 0x34 /* resource unavailable */ +#define IN_MSG_RECEIVED 0x36 /* SCSI message received */ +#define IN_ABORT_TASK 0x20 /* task named in RX_ID is being aborted (FC) */ +#define IN_PORT_LOGOUT 0x29 /* port has logged out (FC) */ +#define IN_PORT_CHANGED 0x2A /* port changed */ +#define IN_GLOBAL_LOGO 0x2E /* all ports logged out */ +#define IN_NO_NEXUS 0x3B /* Nexus not established */ + +/* + * Values for the in_task_flags field- should only get one at a time! + */ +#define TASK_FLAGS_RESERVED_MASK (0xe700) +#define TASK_FLAGS_CLEAR_ACA (1<<14) +#define TASK_FLAGS_TARGET_RESET (1<<13) +#define TASK_FLAGS_LUN_RESET (1<<12) +#define TASK_FLAGS_CLEAR_TASK_SET (1<<10) +#define TASK_FLAGS_ABORT_TASK_SET (1<<9) + +/* + * ISP24XX Immediate Notify + */ +typedef struct { + isphdr_t in_header; + uint32_t in_reserved; + uint16_t in_nphdl; + uint16_t in_reserved1; + uint16_t in_flags; + uint16_t in_srr_rxid; + uint16_t in_status; + uint8_t in_status_subcode; + uint8_t in_reserved2; + uint32_t in_rxid; + uint16_t in_srr_reloff_lo; + uint16_t in_srr_reloff_hi; + uint16_t in_srr_iu; + uint16_t in_srr_oxid; + /* + * If bit 2 is set in in_flags, the following + * two tags are valid. If the received ELS is + * a LOGO, then these tags contain the N Port ID + * from the LOGO payload. If the received ELS + * request is TPRLO, these tags contain the + * Third Party Originator N Port ID. + */ + uint16_t in_nport_id_hi; + uint8_t in_nport_id_lo; + uint8_t in_reserved3; + /* + * If bit 2 is set in in_flags, the following + * tag is valid. If the received ELS is a LOGO, + * then this tag contains the n-port handle + * from the LOGO payload. If the received ELS + * request is TPRLO, this tag contain the + * n-port handle for the Third Party Originator. + */ + uint16_t in_np_handle; + uint8_t in_reserved4[12]; + uint8_t in_reserved5; + uint8_t in_vpidx; + uint32_t in_reserved6; + uint16_t in_portid_lo; + uint8_t in_portid_hi; + uint8_t in_reserved7; + uint16_t in_reserved8; + uint16_t in_oxid; +} in_fcentry_24xx_t; + +#define IN24XX_FLAG_PUREX_IOCB 0x1 +#define IN24XX_FLAG_GLOBAL_LOGOUT 0x2 +#define IN24XX_FLAG_NPHDL_VALID 0x4 + +#define IN24XX_LIP_RESET 0x0E +#define IN24XX_LINK_RESET 0x0F +#define IN24XX_PORT_LOGOUT 0x29 +#define IN24XX_PORT_CHANGED 0x2A +#define IN24XX_LINK_FAILED 0x2E +#define IN24XX_SRR_RCVD 0x45 +#define IN24XX_ELS_RCVD 0x46 /* + * login-affectin ELS received- check + * subcode for specific opcode + */ + +/* + * For f/w > 4.0.25, these offsets in the Immediate Notify contain + * the WWNN/WWPN if the ELS is PLOGI, PDISC or ADISC. The WWN is in + * Big Endian format. + */ +#define IN24XX_PLOGI_WWNN_OFF 0x20 +#define IN24XX_PLOGI_WWPN_OFF 0x28 + +/* + * For f/w > 4.0.25, this offset in the Immediate Notify contain + * the WWPN if the ELS is LOGO. The WWN is in Big Endian format. + */ +#define IN24XX_LOGO_WWPN_OFF 0x28 + +/* + * Immediate Notify Status Subcodes for IN24XX_PORT_LOGOUT + */ +#define IN24XX_PORT_LOGOUT_PDISC_TMO 0x00 +#define IN24XX_PORT_LOGOUT_UXPR_DISC 0x01 +#define IN24XX_PORT_LOGOUT_OWN_OPN 0x02 +#define IN24XX_PORT_LOGOUT_OWN_OPN_SFT 0x03 +#define IN24XX_PORT_LOGOUT_ABTS_TMO 0x04 +#define IN24XX_PORT_LOGOUT_DISC_RJT 0x05 +#define IN24XX_PORT_LOGOUT_LOGIN_NEEDED 0x06 +#define IN24XX_PORT_LOGOUT_BAD_DISC 0x07 +#define IN24XX_PORT_LOGOUT_LOST_ALPA 0x08 +#define IN24XX_PORT_LOGOUT_XMIT_FAILURE 0x09 + +/* + * Immediate Notify Status Subcodes for IN24XX_PORT_CHANGED + */ +#define IN24XX_PORT_CHANGED_BADFAN 0x00 +#define IN24XX_PORT_CHANGED_TOPO_CHANGE 0x01 +#define IN24XX_PORT_CHANGED_FLOGI_ACC 0x02 +#define IN24XX_PORT_CHANGED_FLOGI_RJT 0x03 +#define IN24XX_PORT_CHANGED_TIMEOUT 0x04 +#define IN24XX_PORT_CHANGED_PORT_CHANGE 0x05 + +/* + * Notify Acknowledge Entry structure + */ +#define NA_RSVDLEN 22 +typedef struct { + isphdr_t na_header; + uint32_t na_reserved; + uint8_t na_lun; /* lun */ + uint8_t na_iid; /* initiator */ + uint8_t na_reserved2; + uint8_t na_tgt; /* target */ + uint32_t na_flags; + uint8_t na_status; + uint8_t na_event; + uint16_t na_seqid; /* sequence id */ + uint16_t na_reserved3[NA_RSVDLEN]; +} na_entry_t; + +/* + * Value for the na_event field + */ +#define NA_RST_CLRD 0x80 /* Clear an async event notification */ +#define NA_OK 0x01 /* Notify Acknowledge Succeeded */ +#define NA_INVALID 0x06 /* Invalid Notify Acknowledge */ + +#define NA2_RSVDLEN 21 +typedef struct { + isphdr_t na_header; + uint32_t na_reserved; + uint8_t na_reserved1; + uint8_t na_iid; /* initiator loop id */ + uint16_t na_response; + uint16_t na_flags; + uint16_t na_reserved2; + uint16_t na_status; + uint16_t na_task_flags; + uint16_t na_seqid; /* sequence id */ + uint16_t na_reserved3[NA2_RSVDLEN]; +} na_fcentry_t; + +typedef struct { + isphdr_t na_header; + uint32_t na_reserved; + uint16_t na_iid; /* initiator loop id */ + uint16_t na_response; /* response code */ + uint16_t na_flags; + uint16_t na_reserved2; + uint16_t na_status; + uint16_t na_task_flags; + uint16_t na_seqid; /* sequence id */ + uint16_t na_reserved3[NA2_RSVDLEN]; +} na_fcentry_e_t; + +#define NAFC_RCOUNT 0x80 /* increment resource count */ +#define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */ +#define NAFC_TVALID 0x10 /* task mangement response code is valid */ + +/* + * ISP24XX Notify Acknowledge + */ + +typedef struct { + isphdr_t na_header; + uint32_t na_handle; + uint16_t na_nphdl; + uint16_t na_reserved1; + uint16_t na_flags; + uint16_t na_srr_rxid; + uint16_t na_status; + uint8_t na_status_subcode; + uint8_t na_reserved2; + uint32_t na_rxid; + uint16_t na_srr_reloff_lo; + uint16_t na_srr_reloff_hi; + uint16_t na_srr_iu; + uint16_t na_srr_flags; + uint8_t na_reserved3[18]; + uint8_t na_reserved4; + uint8_t na_vpidx; + uint8_t na_srr_reject_vunique; + uint8_t na_srr_reject_explanation; + uint8_t na_srr_reject_code; + uint8_t na_reserved5; + uint8_t na_reserved6[6]; + uint16_t na_oxid; +} na_fcentry_24xx_t; + +/* + * Accept Target I/O Entry structure + */ +#define ATIO_CDBLEN 26 + +typedef struct { + isphdr_t at_header; + uint16_t at_reserved; + uint16_t at_handle; + uint8_t at_lun; /* lun */ + uint8_t at_iid; /* initiator */ + uint8_t at_cdblen; /* cdb length */ + uint8_t at_tgt; /* target */ + uint32_t at_flags; + uint8_t at_status; /* firmware status */ + uint8_t at_scsi_status; /* scsi status */ + uint8_t at_tag_val; /* tag value */ + uint8_t at_tag_type; /* tag type */ + uint8_t at_cdb[ATIO_CDBLEN]; /* received CDB */ + uint8_t at_sense[QLTM_SENSELEN];/* suggested sense data */ +} at_entry_t; + +/* + * at_flags values + */ +#define AT_NODISC 0x00008000 /* disconnect disabled */ +#define AT_TQAE 0x00000002 /* Tagged Queue Action enabled */ + +/* + * at_status values + */ +#define AT_PATH_INVALID 0x07 /* ATIO sent to firmware for disabled lun */ +#define AT_RESET 0x0E /* SCSI Bus Reset Occurred */ +#define AT_PHASE_ERROR 0x14 /* Bus phase sequence error */ +#define AT_NOCAP 0x16 /* Requested capability not available */ +#define AT_BDR_MSG 0x17 /* Bus Device Reset msg received */ +#define AT_CDB 0x3D /* CDB received */ +/* + * Macros to create and fetch and test concatenated handle and tag value macros + * (SPI only) + */ +#define AT_MAKE_TAGID(tid, aep) \ + tid = aep->at_handle; \ + if (aep->at_flags & AT_TQAE) { \ + tid |= (aep->at_tag_val << 16); \ + tid |= (1 << 24); \ + } + +#define CT_MAKE_TAGID(tid, ct) \ + tid = ct->ct_fwhandle; \ + if (ct->ct_flags & CT_TQAE) { \ + tid |= (ct->ct_tag_val << 16); \ + tid |= (1 << 24); \ + } + +#define AT_HAS_TAG(val) ((val) & (1 << 24)) +#define AT_GET_TAG(val) (((val) >> 16) & 0xff) +#define AT_GET_HANDLE(val) ((val) & 0xffff) + +#define IN_MAKE_TAGID(tid, inp) \ + tid = inp->in_seqid; \ + tid |= (inp->in_tag_val << 16); \ + tid |= (1 << 24) + +/* + * Accept Target I/O Entry structure, Type 2 + */ +#define ATIO2_CDBLEN 16 + +typedef struct { + isphdr_t at_header; + uint32_t at_reserved; + uint8_t at_lun; /* lun or reserved */ + uint8_t at_iid; /* initiator */ + uint16_t at_rxid; /* response ID */ + uint16_t at_flags; + uint16_t at_status; /* firmware status */ + uint8_t at_crn; /* command reference number */ + uint8_t at_taskcodes; + uint8_t at_taskflags; + uint8_t at_execodes; + uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */ + uint32_t at_datalen; /* allocated data len */ + uint16_t at_scclun; /* SCC Lun or reserved */ + uint16_t at_wwpn[4]; /* WWPN of initiator */ + uint16_t at_reserved2[6]; + uint16_t at_oxid; +} at2_entry_t; + +typedef struct { + isphdr_t at_header; + uint32_t at_reserved; + uint16_t at_iid; /* initiator */ + uint16_t at_rxid; /* response ID */ + uint16_t at_flags; + uint16_t at_status; /* firmware status */ + uint8_t at_crn; /* command reference number */ + uint8_t at_taskcodes; + uint8_t at_taskflags; + uint8_t at_execodes; + uint8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */ + uint32_t at_datalen; /* allocated data len */ + uint16_t at_scclun; /* SCC Lun or reserved */ + uint16_t at_wwpn[4]; /* WWPN of initiator */ + uint16_t at_reserved2[6]; + uint16_t at_oxid; +} at2e_entry_t; + +#define ATIO2_WWPN_OFFSET 0x2A +#define ATIO2_OXID_OFFSET 0x3E + +#define ATIO2_TC_ATTR_MASK 0x7 +#define ATIO2_TC_ATTR_SIMPLEQ 0 +#define ATIO2_TC_ATTR_HEADOFQ 1 +#define ATIO2_TC_ATTR_ORDERED 2 +#define ATIO2_TC_ATTR_ACAQ 4 +#define ATIO2_TC_ATTR_UNTAGGED 5 + +#define ATIO2_EX_WRITE 0x1 +#define ATIO2_EX_READ 0x2 +/* + * Macros to create and fetch and test concatenated handle and tag value macros + */ +#define AT2_MAKE_TAGID(tid, bus, inst, aep) \ + tid = aep->at_rxid; \ + tid |= (((uint64_t)inst) << 32); \ + tid |= (((uint64_t)bus) << 48) + +#define CT2_MAKE_TAGID(tid, bus, inst, ct) \ + tid = ct->ct_rxid; \ + tid |= (((uint64_t)inst) << 32); \ + tid |= (((uint64_t)(bus & 0xff)) << 48) + +#define AT2_HAS_TAG(val) 1 +#define AT2_GET_TAG(val) ((val) & 0xffffffff) +#define AT2_GET_INST(val) (((val) >> 32) & 0xffff) +#define AT2_GET_HANDLE AT2_GET_TAG +#define AT2_GET_BUS(val) (((val) >> 48) & 0xff) + +#define FC_HAS_TAG AT2_HAS_TAG +#define FC_GET_TAG AT2_GET_TAG +#define FC_GET_INST AT2_GET_INST +#define FC_GET_HANDLE AT2_GET_HANDLE + +#define IN_FC_MAKE_TAGID(tid, bus, inst, seqid) \ + tid = seqid; \ + tid |= (((uint64_t)inst) << 32); \ + tid |= (((uint64_t)(bus & 0xff)) << 48) + +#define FC_TAG_INSERT_INST(tid, inst) \ + tid &= ~0x0000ffff00000000ull; \ + tid |= (((uint64_t)inst) << 32) + +/* + * 24XX ATIO Definition + * + * This is *quite* different from other entry types. + * First of all, it has its own queue it comes in on. + * + * Secondly, it doesn't have a normal header. + * + * Thirdly, it's just a passthru of the FCP CMND IU + * which is recorded in big endian mode. + */ +typedef struct { + uint8_t at_type; + uint8_t at_count; + /* + * Task attribute in high four bits, + * the rest is the FCP CMND IU Length. + * NB: the command can extend past the + * length for a single queue entry. + */ + uint16_t at_ta_len; + uint32_t at_rxid; + fc_hdr_t at_hdr; + fcp_cmnd_iu_t at_cmnd; +} at7_entry_t; +#define AT7_NORESRC_RXID 0xffffffff + + +/* + * Continue Target I/O Entry structure + * Request from driver. The response from the + * ISP firmware is the same except that the last 18 + * bytes are overwritten by suggested sense data if + * the 'autosense valid' bit is set in the status byte. + */ +typedef struct { + isphdr_t ct_header; + uint16_t ct_syshandle; + uint16_t ct_fwhandle; /* required by f/w */ + uint8_t ct_lun; /* lun */ + uint8_t ct_iid; /* initiator id */ + uint8_t ct_reserved2; + uint8_t ct_tgt; /* our target id */ + uint32_t ct_flags; + uint8_t ct_status; /* isp status */ + uint8_t ct_scsi_status; /* scsi status */ + uint8_t ct_tag_val; /* tag value */ + uint8_t ct_tag_type; /* tag type */ + uint32_t ct_xfrlen; /* transfer length */ + int32_t ct_resid; /* residual length */ + uint16_t ct_timeout; + uint16_t ct_seg_count; + ispds_t ct_dataseg[ISP_RQDSEG]; +} ct_entry_t; + +/* + * For some of the dual port SCSI adapters, port (bus #) is reported + * in the MSbit of ct_iid. Bit fields are a bit too awkward here. + * + * Note that this does not apply to FC adapters at all which can and + * do report IIDs between 0x81 && 0xfe (or 0x7ff) which represent devices + * that have logged in across a SCSI fabric. + */ +#define GET_IID_VAL(x) (x & 0x3f) +#define GET_BUS_VAL(x) ((x >> 7) & 0x1) +#define SET_IID_VAL(y, x) y = ((y & ~0x3f) | (x & 0x3f)) +#define SET_BUS_VAL(y, x) y = ((y & 0x3f) | ((x & 0x1) << 7)) + +/* + * ct_flags values + */ +#define CT_TQAE 0x00000002 /* bit 1, Tagged Queue Action enable */ +#define CT_DATA_IN 0x00000040 /* bits 6&7, Data direction */ +#define CT_DATA_OUT 0x00000080 /* bits 6&7, Data direction */ +#define CT_NO_DATA 0x000000C0 /* bits 6&7, Data direction */ +#define CT_CCINCR 0x00000100 /* bit 8, autoincrement atio count */ +#define CT_DATAMASK 0x000000C0 /* bits 6&7, Data direction */ +#define CT_INISYNCWIDE 0x00004000 /* bit 14, Do Sync/Wide Negotiation */ +#define CT_NODISC 0x00008000 /* bit 15, Disconnects disabled */ +#define CT_DSDP 0x01000000 /* bit 24, Disable Save Data Pointers */ +#define CT_SENDRDP 0x04000000 /* bit 26, Send Restore Pointers msg */ +#define CT_SENDSTATUS 0x80000000 /* bit 31, Send SCSI status byte */ + +/* + * ct_status values + * - set by the firmware when it returns the CTIO + */ +#define CT_OK 0x01 /* completed without error */ +#define CT_ABORTED 0x02 /* aborted by host */ +#define CT_ERR 0x04 /* see sense data for error */ +#define CT_INVAL 0x06 /* request for disabled lun */ +#define CT_NOPATH 0x07 /* invalid ITL nexus */ +#define CT_INVRXID 0x08 /* (FC only) Invalid RX_ID */ +#define CT_DATA_OVER 0x09 /* (FC only) Data Overrun */ +#define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */ +#define CT_TIMEOUT 0x0B /* timed out */ +#define CT_RESET 0x0E /* SCSI Bus Reset occurred */ +#define CT_PARITY 0x0F /* Uncorrectable Parity Error */ +#define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */ +#define CT_PANIC 0x13 /* Unrecoverable Error */ +#define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */ +#define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */ +#define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */ +#define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */ +#define CT_PORTUNAVAIL 0x28 /* port not available */ +#define CT_LOGOUT 0x29 /* port logout */ +#define CT_PORTCHANGED 0x2A /* port changed */ +#define CT_IDE 0x33 /* Initiator Detected Error */ +#define CT_NOACK 0x35 /* Outstanding Immed. Notify. entry */ +#define CT_SRR 0x45 /* SRR Received */ +#define CT_LUN_RESET 0x48 /* Lun Reset Received */ + +/* + * When the firmware returns a CTIO entry, it may overwrite the last + * part of the structure with sense data. This starts at offset 0x2E + * into the entry, which is in the middle of ct_dataseg[1]. Rather + * than define a new struct for this, I'm just using the sense data + * offset. + */ +#define CTIO_SENSE_OFFSET 0x2E + +/* + * Entry length in u_longs. All entries are the same size so + * any one will do as the numerator. + */ +#define UINT32_ENTRY_SIZE (sizeof(at_entry_t)/sizeof(uint32_t)) + +/* + * QLA2100 CTIO (type 2) entry + */ +#define MAXRESPLEN 26 +typedef struct { + isphdr_t ct_header; + uint32_t ct_syshandle; + uint8_t ct_lun; /* lun */ + uint8_t ct_iid; /* initiator id */ + uint16_t ct_rxid; /* response ID */ + uint16_t ct_flags; + uint16_t ct_status; /* isp status */ + uint16_t ct_timeout; + uint16_t ct_seg_count; + uint32_t ct_reloff; /* relative offset */ + int32_t ct_resid; /* residual length */ + union { + /* + * The three different modes that the target driver + * can set the CTIO{2,3,4} up as. + * + * The first is for sending FCP_DATA_IUs as well as + * (optionally) sending a terminal SCSI status FCP_RSP_IU. + * + * The second is for sending SCSI sense data in an FCP_RSP_IU. + * Note that no FCP_DATA_IUs will be sent. + * + * The third is for sending FCP_RSP_IUs as built specifically + * in system memory as located by the isp_dataseg. + */ + struct { + uint32_t _reserved; + uint16_t _reserved2; + uint16_t ct_scsi_status; + uint32_t ct_xfrlen; + union { + ispds_t ct_dataseg[ISP_RQDSEG_T2]; + ispds64_t ct_dataseg64[ISP_RQDSEG_T3]; + ispdslist_t ct_dslist; + } u; + } m0; + struct { + uint16_t _reserved; + uint16_t _reserved2; + uint16_t ct_senselen; + uint16_t ct_scsi_status; + uint16_t ct_resplen; + uint8_t ct_resp[MAXRESPLEN]; + } m1; + struct { + uint32_t _reserved; + uint16_t _reserved2; + uint16_t _reserved3; + uint32_t ct_datalen; + ispds_t ct_fcp_rsp_iudata; + } m2; + } rsp; +} ct2_entry_t; + +typedef struct { + isphdr_t ct_header; + uint32_t ct_syshandle; + uint16_t ct_iid; /* initiator id */ + uint16_t ct_rxid; /* response ID */ + uint16_t ct_flags; + uint16_t ct_status; /* isp status */ + uint16_t ct_timeout; + uint16_t ct_seg_count; + uint32_t ct_reloff; /* relative offset */ + int32_t ct_resid; /* residual length */ + union { + struct { + uint32_t _reserved; + uint16_t _reserved2; + uint16_t ct_scsi_status; + uint32_t ct_xfrlen; + union { + ispds_t ct_dataseg[ISP_RQDSEG_T2]; + ispds64_t ct_dataseg64[ISP_RQDSEG_T3]; + ispdslist_t ct_dslist; + } u; + } m0; + struct { + uint16_t _reserved; + uint16_t _reserved2; + uint16_t ct_senselen; + uint16_t ct_scsi_status; + uint16_t ct_resplen; + uint8_t ct_resp[MAXRESPLEN]; + } m1; + struct { + uint32_t _reserved; + uint16_t _reserved2; + uint16_t _reserved3; + uint32_t ct_datalen; + ispds_t ct_fcp_rsp_iudata; + } m2; + } rsp; +} ct2e_entry_t; + +/* + * ct_flags values for CTIO2 + */ +#define CT2_FLAG_MODE0 0x0000 +#define CT2_FLAG_MODE1 0x0001 +#define CT2_FLAG_MODE2 0x0002 +#define CT2_FLAG_MMASK 0x0003 +#define CT2_DATA_IN 0x0040 +#define CT2_DATA_OUT 0x0080 +#define CT2_NO_DATA 0x00C0 +#define CT2_DATAMASK 0x00C0 +#define CT2_CCINCR 0x0100 +#define CT2_FASTPOST 0x0200 +#define CT2_CONFIRM 0x2000 +#define CT2_TERMINATE 0x4000 +#define CT2_SENDSTATUS 0x8000 + +/* + * ct_status values are (mostly) the same as that for ct_entry. + */ + +/* + * ct_scsi_status values- the low 8 bits are the normal SCSI status + * we know and love. The upper 8 bits are validity markers for FCP_RSP_IU + * fields. + */ +#define CT2_RSPLEN_VALID 0x0100 +#define CT2_SNSLEN_VALID 0x0200 +#define CT2_DATA_OVER 0x0400 +#define CT2_DATA_UNDER 0x0800 + +/* + * ISP24XX CTIO + */ +#define MAXRESPLEN_24XX 24 +typedef struct { + isphdr_t ct_header; + uint32_t ct_syshandle; + uint16_t ct_nphdl; /* status on returned CTIOs */ + uint16_t ct_timeout; + uint16_t ct_seg_count; + uint8_t ct_vpidx; + uint8_t ct_xflags; + uint16_t ct_iid_lo; /* low 16 bits of portid */ + uint8_t ct_iid_hi; /* hi 8 bits of portid */ + uint8_t ct_reserved; + uint32_t ct_rxid; + uint16_t ct_senselen; /* mode 1 only */ + uint16_t ct_flags; + int32_t ct_resid; /* residual length */ + uint16_t ct_oxid; + uint16_t ct_scsi_status; /* modes 0 && 1 only */ + union { + struct { + uint32_t reloff; + uint32_t reserved0; + uint32_t ct_xfrlen; + uint32_t reserved1; + ispds64_t ds; + } m0; + struct { + uint16_t ct_resplen; + uint16_t reserved; + uint8_t ct_resp[MAXRESPLEN_24XX]; + } m1; + struct { + uint32_t reserved0; + uint32_t ct_datalen; + uint32_t reserved1; + ispds64_t ct_fcp_rsp_iudata; + } m2; + } rsp; +} ct7_entry_t; + +/* + * ct_flags values for CTIO7 + */ +#define CT7_DATA_IN 0x0002 +#define CT7_DATA_OUT 0x0001 +#define CT7_NO_DATA 0x0000 +#define CT7_DATAMASK 0x003 +#define CT7_DSD_ENABLE 0x0004 +#define CT7_CONF_STSFD 0x0010 +#define CT7_EXPLCT_CONF 0x0020 +#define CT7_FLAG_MODE0 0x0000 +#define CT7_FLAG_MODE1 0x0040 +#define CT7_FLAG_MODE2 0x0080 +#define CT7_FLAG_MMASK 0x00C0 +#define CT7_NOACK 0x0100 +#define CT7_TASK_ATTR_SHIFT 9 +#define CT7_CONFIRM 0x2000 +#define CT7_TERMINATE 0x4000 +#define CT7_SENDSTATUS 0x8000 + +/* + * Type 7 CTIO status codes + */ +#define CT7_OK 0x01 /* completed without error */ +#define CT7_ABORTED 0x02 /* aborted by host */ +#define CT7_ERR 0x04 /* see sense data for error */ +#define CT7_INVAL 0x06 /* request for disabled lun */ +#define CT7_INVRXID 0x08 /* (FC only) Invalid RX_ID */ +#define CT7_DATA_OVER 0x09 /* (FC only) Data Overrun */ +#define CT7_TIMEOUT 0x0B /* timed out */ +#define CT7_RESET 0x0E /* LIP Rset Received */ +#define CT7_BUS_ERROR 0x10 /* DMA PCI Error */ +#define CT7_REASSY_ERR 0x11 /* DMA reassembly error */ +#define CT7_DATA_UNDER 0x15 /* (FC only) Data Underrun */ +#define CT7_PORTUNAVAIL 0x28 /* port not available */ +#define CT7_LOGOUT 0x29 /* port logout */ +#define CT7_PORTCHANGED 0x2A /* port changed */ +#define CT7_SRR 0x45 /* SRR Received */ + +/* + * Other 24XX related target IOCBs + */ + +/* + * ABTS Received + */ +typedef struct { + isphdr_t abts_header; + uint8_t abts_reserved0[6]; + uint16_t abts_nphdl; + uint16_t abts_reserved1; + uint16_t abts_sof; + uint32_t abts_rxid_abts; + uint16_t abts_did_lo; + uint8_t abts_did_hi; + uint8_t abts_r_ctl; + uint16_t abts_sid_lo; + uint8_t abts_sid_hi; + uint8_t abts_cs_ctl; + uint16_t abts_fs_ctl; + uint8_t abts_f_ctl; + uint8_t abts_type; + uint16_t abts_seq_cnt; + uint8_t abts_df_ctl; + uint8_t abts_seq_id; + uint16_t abts_rx_id; + uint16_t abts_ox_id; + uint32_t abts_param; + uint8_t abts_reserved2[16]; + uint32_t abts_rxid_task; +} abts_t; + +typedef struct { + isphdr_t abts_rsp_header; + uint32_t abts_rsp_handle; + uint16_t abts_rsp_status; + uint16_t abts_rsp_nphdl; + uint16_t abts_rsp_ctl_flags; + uint16_t abts_rsp_sof; + uint32_t abts_rsp_rxid_abts; + uint16_t abts_rsp_did_lo; + uint8_t abts_rsp_did_hi; + uint8_t abts_rsp_r_ctl; + uint16_t abts_rsp_sid_lo; + uint8_t abts_rsp_sid_hi; + uint8_t abts_rsp_cs_ctl; + uint16_t abts_rsp_f_ctl_lo; + uint8_t abts_rsp_f_ctl_hi; + uint8_t abts_rsp_type; + uint16_t abts_rsp_seq_cnt; + uint8_t abts_rsp_df_ctl; + uint8_t abts_rsp_seq_id; + uint16_t abts_rsp_rx_id; + uint16_t abts_rsp_ox_id; + uint32_t abts_rsp_param; + union { + struct { + uint16_t reserved; + uint8_t last_seq_id; + uint8_t seq_id_valid; + uint16_t aborted_rx_id; + uint16_t aborted_ox_id; + uint16_t high_seq_cnt; + uint16_t low_seq_cnt; + uint8_t reserved2[4]; + } ba_acc; + struct { + uint8_t vendor_unique; + uint8_t explanation; + uint8_t reason; + uint8_t reserved; + uint8_t reserved2[12]; + } ba_rjt; + struct { + uint8_t reserved[8]; + uint32_t subcode1; + uint32_t subcode2; + } rsp; + uint8_t reserved[16]; + } abts_rsp_payload; + uint32_t abts_rsp_rxid_task; +} abts_rsp_t; + +/* terminate this ABTS exchange */ +#define ISP24XX_ABTS_RSP_TERMINATE 0x01 + +#define ISP24XX_ABTS_RSP_COMPLETE 0x00 +#define ISP24XX_ABTS_RSP_RESET 0x04 +#define ISP24XX_ABTS_RSP_ABORTED 0x05 +#define ISP24XX_ABTS_RSP_TIMEOUT 0x06 +#define ISP24XX_ABTS_RSP_INVXID 0x08 +#define ISP24XX_ABTS_RSP_LOGOUT 0x29 +#define ISP24XX_ABTS_RSP_SUBCODE 0x31 + +#define ISP24XX_NO_TASK 0xffffffff #endif /* _ISPMBOX_H */ diff --git a/qla_isp/common/ispreg.h b/qla_isp/common/ispreg.h index da2b0aeff..5c6e9f2c7 100644 --- a/qla_isp/common/ispreg.h +++ b/qla_isp/common/ispreg.h @@ -1,18 +1,18 @@ -/* $Id: ispreg.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: ispreg.h,v 1.30 2009/01/24 17:55:53 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -24,32 +24,32 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * + * + * * Alternatively, this software may be distributed under the terms of the * the GNU Public License ("GPL") with platforms where the prevalant license * is the GNU Public License: - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of The Version 2 GNU General Public License as published * by the Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * + * + * * Matthew Jacob * Feral Software * 421 Laurel Avenue * Menlo Park, CA 94025 * USA - * + * * gplbsd at feral com */ /* @@ -374,7 +374,7 @@ /* * 2400 Interface Offsets and Register Definitions - * + * * The 2400 looks quite different in terms of registers from other QLogic cards. * It is getting to be a genuine pain and challenge to keep the same model * for all. @@ -476,7 +476,7 @@ #define OUTMAILBOX7 (MBOX_BLOCK+0xE) /* - * Strictly speaking, it's + * Strictly speaking, it's * SCSI && 2100 : 8 MBOX registers * 2200: 24 MBOX registers * 2300/2400: 32 MBOX registers @@ -497,10 +497,21 @@ typedef struct { uint16_t param[MAILBOX_STORAGE]; uint16_t ibits; uint16_t obits; - uint32_t : 28, + uint32_t + lineno : 16, + : 12, logval : 4; uint32_t timeout; + const char *func; } mbreg_t; +#define MBSINIT(mbxp, code, loglev, timo) \ + ISP_MEMZERO((mbxp), sizeof (mbreg_t)); \ + (mbxp)->param[0] = code; \ + (mbxp)->lineno = __LINE__; \ + (mbxp)->func = __func__; \ + (mbxp)->logval = loglev; \ + (mbxp)->timeout = timo + /* * Fibre Protocol Module and Frame Buffer Register Offsets/Definitions (2X00). diff --git a/qla_isp/common/ispvar.h b/qla_isp/common/ispvar.h index 1892754f3..a4ae1ce6c 100644 --- a/qla_isp/common/ispvar.h +++ b/qla_isp/common/ispvar.h @@ -1,4 +1,4 @@ -/* $Id: ispvar.h,v 1.99 2008/06/16 23:53:18 mjacob Exp $ */ +/* $Id: ispvar.h,v 1.103 2009/02/01 23:49:49 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -292,9 +292,8 @@ typedef struct { /* * Special Constants */ -#define INI_NONE ((uint64_t) 0) -#define INI_ANY ((uint64_t) -1) -#define VALID_INI(ini) (ini != INI_NONE && ini != INI_ANY) +#define INI_NONE ((uint64_t) 0) +#define ISP_NOCHAN 0xff /* * Special Port IDs @@ -317,11 +316,11 @@ typedef struct { * * It has a state. If the state if VALID, that means that we've logged into * the device. We also *may* have a initiator map index entry. This is a value - * from 0..MAX_FC_TARG that is used to index into the isp_ini_map array. If + * from 0..MAX_FC_TARG that is used to index into the isp_dev_map array. If * the value therein is non-zero, then that value minus one is used to index * into the Port Database to find the handle for forming commands. There is * back-index minus one value within to Port Database entry that tells us - * which entry in isp_ini_map points to us (to avoid searching). + * which entry in isp_dev_map points to us (to avoid searching). * * Local loop devices the firmware automatically performs PLOGI on for us * (which is why that handle is imposed upon us). Fabric devices we assign @@ -354,7 +353,7 @@ typedef struct { * * + There can never be two non-NIL entries with the same handle. * - * + There can never be two non-NIL entries which have the same ini_map_idx + * + There can never be two non-NIL entries which have the same dev_map_idx * value. */ typedef struct { @@ -366,8 +365,8 @@ typedef struct { uint16_t handle; /* - * The ini_map_idx, if nonzero, is the system virtual target ID (+1) - * as a cross-reference with the isp_ini_map. + * The dev_map_idx, if nonzero, is the system virtual target ID (+1) + * as a cross-reference with the isp_dev_map. * * A device is 'autologin' if the firmware automatically logs into * it (re-logins as needed). Basically, local private loop devices. @@ -381,10 +380,10 @@ typedef struct { * * The 'target_mode' tag means that this entry arrived via a * target mode command and is immune from normal flushing rules. - * You should also never see anything with no initiator role + * You should also never see anything with an initiator role * with this set. */ - uint16_t ini_map_idx : 12, + uint16_t dev_map_idx : 12, autologin : 1, /* F/W does PLOGI/PLOGO */ state : 3; uint32_t reserved : 5, @@ -464,7 +463,7 @@ typedef struct { * subtract one to get the portdb index. This means that * entries which are zero are unmapped (i.e., don't exist). */ - uint16_t isp_ini_map[MAX_FC_TARG]; + uint16_t isp_dev_map[MAX_FC_TARG]; /* * Scratch DMA mapped in area to fetch Port Database stuff, etc. @@ -571,6 +570,7 @@ struct ispsoftc { volatile uint32_t isp_resodx; /* index of next result */ volatile uint32_t isp_lasthdls; /* last handle seed */ volatile uint32_t isp_obits; /* mailbox command output */ + volatile uint32_t isp_serno; /* rolling serial number */ volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE]; volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */ volatile uint16_t isp_mbxwrk0; @@ -937,11 +937,11 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * * ISP_FC_SCRLEN FC scratch area DMA length * - * MEMZERO(dst, src) platform zeroing function - * MEMCPY(dst, src, count) platform copying function - * SNPRINTF(buf, bufsize, fmt, ...) snprintf - * USEC_DELAY(usecs) microsecond spindelay function - * USEC_SLEEP(isp, usecs) microsecond sleep function + * ISP_MEMZERO(dst, src) platform zeroing function + * ISP_MEMCPY(dst, src, count) platform copying function + * ISP_SNPRINTF(buf, bufsize, fmt, ...) snprintf + * ISP_DELAY(usecs) microsecond spindelay function + * ISP_SLEEP(isp, usecs) microsecond sleep function * * NANOTIME_T nanosecond time type * @@ -1051,4 +1051,61 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * ISP_SWAP32(ispsoftc_t *, uint32_t srcval) */ +#ifdef ISP_TARGET_MODE +/* + * The functions below are for the publicly available + * target mode functions that are internal to the Qlogic driver. + */ + +/* + * This function handles new response queue entry appropriate for target mode. + */ +int isp_target_notify(ispsoftc_t *, void *, uint32_t *); + +/* + * This function externalizes the ability to acknowledge an Immediate Notify request. + */ +int isp_notify_ack(ispsoftc_t *, void *); + +/* + * This function externalized acknowledging (success/fail) an ABTS frame + */ +int isp_acknak_abts(ispsoftc_t *, void *, int); + +/* + * Enable/Disable/Modify a logical unit. + * (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt) + */ +#define DFLT_CMND_CNT 0xfe /* unmonitored */ +#define DFLT_INOT_CNT 0xfe /* unmonitored */ +int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int); + +/* + * General request queue 'put' routine for target mode entries. + */ +int isp_target_put_entry(ispsoftc_t *isp, void *); + +/* + * General routine to put back an ATIO entry- + * used for replenishing f/w resource counts. + * The argument is a pointer to a source ATIO + * or ATIO2. + */ +int isp_target_put_atio(ispsoftc_t *, void *); + +/* + * General routine to send a final CTIO for a command- used mostly for + * local responses. + */ +int isp_endcmd(ispsoftc_t *, ...); +#define ECMD_SVALID 0x100 +#define ECMD_TERMINATE 0x200 + +/* + * Handle an asynchronous event + * + * Return nonzero if the interrupt that generated this event has been dismissed. + */ +int isp_target_async(ispsoftc_t *, int, int); +#endif #endif /* _ISPVAR_H */ diff --git a/qla_isp/linux/isp_cb_ops.c b/qla_isp/linux/isp_cb_ops.c index 005f4e55a..6d54ccba3 100644 --- a/qla_isp/linux/isp_cb_ops.c +++ b/qla_isp/linux/isp_cb_ops.c @@ -1,4 +1,4 @@ -/* $Id: isp_cb_ops.c,v 1.95 2008/09/12 20:53:44 mjacob Exp $ */ +/* $Id: isp_cb_ops.c,v 1.98 2009/02/01 23:49:55 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -198,7 +198,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l io = len; } else if (strncmp(buf, "bins", 4) == 0) { ISP_LOCKU_SOFTC(isp); - MEMZERO(isp->isp_osinfo.bins, sizeof (isp->isp_osinfo.bins)); + memset(isp->isp_osinfo.bins, 0, sizeof (isp->isp_osinfo.bins)); ISP_UNLKU_SOFTC(isp); io = len; } @@ -296,10 +296,10 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) { continue; } - if (fcp->portdb[i].ini_map_idx) { + if (fcp->portdb[i].dev_map_idx) { copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s (target %d)\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n", i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles], - fcp->portdb[i].ini_map_idx - 1, (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn); + fcp->portdb[i].dev_map_idx - 1, (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn); } else { copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n", i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles], @@ -422,7 +422,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) { isp_stats_t stats; - MEMZERO(&stats, sizeof stats); + memset(&stats, 0, sizeof stats); stats.isp_stat_version = ISP_STATS_VERSION; stats.isp_type = isp->isp_type; stats.isp_revision = isp->isp_revision; @@ -642,7 +642,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) break; } - MEMZERO(&mbs, sizeof (mbs)); + memset(&mbs, 0, sizeof (mbs)); needmarker = 0; loopid = fct->loopid; if (ISP_CAP_2KLOGIN(isp) == 0) { @@ -771,7 +771,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) uint8_t local[QENTRY_LEN]; ispreq_t *reqp; int time, result = 0; - DECLARE_MUTEX_LOCKED(rsem); + struct semaphore rsem; unsigned long flags; time = cmd->timeout / 1000; @@ -781,7 +781,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) if (IS_24XX(isp) && time > 0x1999) { time = 0x1999; } - MEMZERO(local, sizeof (local)); + memset(local, 0, sizeof (local)); Cmnd = isp_kzalloc(sizeof (struct scsi_cmnd), GFP_KERNEL); if (Cmnd == NULL) { result = -ENOMEM; @@ -797,6 +797,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) dev->host = host; Cmnd->scsi_done = isp_run_cmd_done; Cmnd->SCp.ptr = (char *)&rsem; + sema_init(&rsem, 0); ISP_LOCKU_SOFTC(isp); if (isp_getrqentry(isp, &nxti, &optr, (void *)&reqp)) { diff --git a/qla_isp/linux/isp_ioctl.h b/qla_isp/linux/isp_ioctl.h index 8629e4fec..85b5bc2bc 100644 --- a/qla_isp/linux/isp_ioctl.h +++ b/qla_isp/linux/isp_ioctl.h @@ -1,4 +1,4 @@ -/* $Id: isp_ioctl.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */ +/* $Id: isp_ioctl.h,v 1.29 2008/09/12 22:24:31 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. diff --git a/qla_isp/linux/isp_linux.c b/qla_isp/linux/isp_linux.c index 041149c6f..224c2d039 100644 --- a/qla_isp/linux/isp_linux.c +++ b/qla_isp/linux/isp_linux.c @@ -1,4 +1,4 @@ -/* $Id: isp_linux.c,v 1.234 2008/08/20 15:50:56 mjacob Exp $ */ +/* $Id: isp_linux.c,v 1.240 2009/02/01 23:49:55 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -96,6 +96,7 @@ static char *isp_wwnns; #ifdef ISP_TARGET_MODE + #ifndef ISP_PARENT_TARGET #define ISP_PARENT_TARGET scsi_target_handler #endif @@ -838,7 +839,7 @@ isp_init_target(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, "cannot allocate TMD structures"); return (-ENOMEM); } - npool = isp_kzalloc(N_NOTIFIES * sizeof (isp_notify_t), GFP_KERNEL); + npool = isp_kzalloc(N_NOTIFIES * sizeof (notify_t), GFP_KERNEL); if (npool == NULL) { isp_prt(isp, ISP_LOGERR, "cannot allocate TMD NOTIFY structures"); isp_kfree(pool, NTGT_CMDS * TMD_SIZE); @@ -856,8 +857,8 @@ isp_init_target(ispsoftc_t *isp) for (i = 0; i < N_NOTIFIES-1; i++) { isp->isp_osinfo.npool[i].notify.nt_lreserved = &isp->isp_osinfo.npool[i+1]; } - MEMZERO(isp->isp_osinfo.auxbmap, sizeof (isp->isp_osinfo.auxbmap)); - MEMCPY(isp->isp_osinfo.inqdata, inqdsd, DEFAULT_INQSIZE); + memset(isp->isp_osinfo.auxbmap, 0, sizeof (isp->isp_osinfo.auxbmap)); + memcpy(isp->isp_osinfo.inqdata, inqdsd, DEFAULT_INQSIZE); isp->isp_osinfo.pending_t = NULL; isp->isp_osinfo.tfreelist = isp->isp_osinfo.pool; isp->isp_osinfo.bfreelist = &isp->isp_osinfo.pool[NTGT_CMDS-1]; @@ -902,7 +903,7 @@ isp_deinit_target(ispsoftc_t *isp) isp_kfree(pool, NTGT_CMDS * TMD_SIZE); } if (npool) { - isp_kfree(npool, N_NOTIFIES * sizeof (isp_notify_t)); + isp_kfree(npool, N_NOTIFIES * sizeof (notify_t)); } } @@ -932,7 +933,7 @@ isp_detach_target(ispsoftc_t *isp) static void isp_tgt_tq(ispsoftc_t *isp) { - isp_notify_t *ins; + notify_t *ins; tmd_cmd_t *tmd; tmd_xact_t *xact; unsigned long flags; @@ -952,7 +953,7 @@ isp_tgt_tq(ispsoftc_t *isp) } ISP_UNLK_SOFTC(isp); while (ins != NULL) { - isp_notify_t *next = ins->notify.nt_lreserved; + notify_t *next = ins->notify.nt_lreserved; ins->notify.nt_lreserved = NULL; isp_prt(isp, ISP_LOGTDEBUG2, "isp_tgt_tq -> notify 0x%x", ins->notify.nt_ncode); ISP_PARENT_TARGET(QOUT_NOTIFY, ins); @@ -1057,7 +1058,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 return; } lp = &fcp->portdb[i]; - MEMZERO(lp, sizeof (fcportdb_t)); + memset(lp, 0, sizeof (fcportdb_t)); lp->target_mode = 1; lp->handle = nphdl; lp->portid = s_id; @@ -1081,7 +1082,7 @@ isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 if (ini == INI_ANY && nphdl == NIL_HANDLE && s_id == PORT_ANY) { isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cleared due to wildcard call", __func__, chan, (ull) lp->port_wwn, lp->handle, lp->portid); - MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); + memset(&fcp->portdb[i], 0, sizeof (fcportdb_t)); continue; } if ((s_id == PORT_ANY || lp->portid == s_id) && lp->handle == nphdl) { @@ -1097,7 +1098,7 @@ isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 } else { isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cleared", __func__, chan, (ull) lp->port_wwn, nphdl, lp->portid); - MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); + memset(&fcp->portdb[i], 0, sizeof (fcportdb_t)); } } @@ -1327,7 +1328,7 @@ isp_taction(qact_e action, void *arg) case QIN_NOTIFY_ACK: { - isp_notify_t *ins = (isp_notify_t *) arg; + notify_t *ins = (notify_t *) arg; isp = ins->notify.nt_hba; if (isp == NULL) { @@ -1342,10 +1343,18 @@ isp_taction(qact_e action, void *arg) isp_prt(isp, ISP_LOGINFO, "s/w notify code %x acked", ins->notify.nt_ncode); break; default: + if (ins->notify.nt_failed) { + isp_prt(isp, ISP_LOGWARN, "[%llx] notify code 0x%x returned back with failure", (ull) ins->notify.nt_tagval, ins->notify.nt_ncode); + } if (isp->isp_state != ISP_RUNSTATE) { - isp_prt(isp, ISP_LOGINFO, "[%llx] Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", + isp_prt(isp, ISP_LOGTINFO, "[%llx] Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", (ull) ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); - } else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ATIO) { + } + + /* + * This case is for a Task Management Function, which shows up as an ATIO7 entry. + */ + if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ATIO) { ct7_entry_t local, *cto = &local; at7_entry_t *aep = (at7_entry_t *)ins->qentry; fcportdb_t *lp; @@ -1358,40 +1367,51 @@ isp_taction(qact_e action, void *arg) } else { nphdl = NIL_HANDLE; } - MEMZERO(&local, sizeof (local)); + memset(&local, 0, sizeof (local)); cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; cto->ct_header.rqs_entry_count = 1; cto->ct_nphdl = nphdl; cto->ct_rxid = aep->at_rxid; - cto->ct_vpindex = ins->notify.nt_channel; + cto->ct_vpidx = ins->notify.nt_channel; cto->ct_iid_lo = sid; cto->ct_iid_hi = sid >> 16; cto->ct_oxid = aep->at_hdr.ox_id; cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1; cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT; - (void) isp_target_put_entry(isp, &local); - } else if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ABTS_RSP) { - abts_t *abt = (abts_t *)ins->qentry; - abts_rsp_t *rsp = (abts_rsp_t *)ins->qentry; - uint16_t rx_id, ox_id; + WARN_ON(isp_target_put_entry(isp, &local)); /* XXX FIX ME XXX */ + break; + } - isp_prt(isp, ISP_LOGTINFO, "ABTS for 0x%x being BA_ACC'd", rsp->abts_rsp_rxid_abts); - rx_id = abt->abts_rx_id; - ox_id = abt->abts_ox_id; - rsp->abts_rsp_handle = rsp->abts_rsp_rxid_abts; - rsp->abts_rsp_r_ctl = BA_ACC; - MEMZERO(&rsp->abts_rsp_payload.ba_acc, sizeof (rsp->abts_rsp_payload.ba_acc)); - rsp->abts_rsp_payload.ba_acc.aborted_rx_id = rx_id; - rsp->abts_rsp_payload.ba_acc.aborted_ox_id = ox_id; - rsp->abts_rsp_payload.ba_acc.high_seq_cnt = 0xffff; - isp_notify_ack(isp, ins->qentry); - } else if (ins->notify.nt_need_ack) { - isp_prt(isp, ISP_LOGINFO, "[%llx] Notify Code 0x%x (qevalid=%d) being acked", (ull) ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); - if (ins->qevalid) { - isp_notify_ack(isp, ins->qentry); - } else { - isp_notify_ack(isp, NULL); - } + /* + * This case is for a responding to an ABTS frame + */ + if (IS_24XX(isp) && ins->qevalid && ((isphdr_t *)ins->qentry)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { + uint8_t storage[QENTRY_LEN]; + ct7_entry_t *cto = (ct7_entry_t *) storage; + abts_t *abts = (abts_t *)ins->qentry; + + ISP_MEMZERO(cto, sizeof (ct7_entry_t)); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task); + cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; + cto->ct_header.rqs_entry_count = 1; + cto->ct_nphdl = ins->notify.nt_nphdl; + cto->ct_rxid = abts->abts_rxid_task; + cto->ct_iid_lo = ins->notify.nt_sid; + cto->ct_iid_hi = ins->notify.nt_sid >> 16; + cto->ct_oxid = abts->abts_ox_id; + cto->ct_vpidx = ins->notify.nt_channel; + cto->ct_flags = CT7_NOACK|CT7_TERMINATE; + WARN_ON(isp_target_put_entry(isp, cto)); + WARN_ON(isp_acknak_abts(isp, ins->qentry, 0)); + break; + } + + /* + * General purpose acknowledgement + */ + if (ins->notify.nt_need_ack) { + isp_prt(isp, ISP_LOGTINFO, "[%llx] Notify Code 0x%x (qevalid=%d) being acked", (ull) ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); + WARN_ON(isp_notify_ack(isp, ins->qevalid? ins->qentry : NULL)); } break; } @@ -1490,7 +1510,7 @@ static void isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) { void *qe; - uint32_t handle; + uint32_t handle, orig_xfrlen = 0; uint32_t nxti, optr; uint8_t local[QENTRY_LEN]; unsigned long flags; @@ -1500,11 +1520,24 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) xact->td_lflags &= ~TDFL_ERROR; xact->td_error = 0; + /* + * Use this lock to protect tmd fields + */ + ISP_LOCK_SOFTC(isp); + + /* + * Pre-increment cd_moved so we know how many bytes are actually in transit. If we actually fail to move + * the bytes, we'll subtract things out when we collect status. If we fail to even start the transfer + * (due to inability to even get queue space), we'll subtract that as well too. + */ + orig_xfrlen = xact->td_xfrlen; + tmd->cd_moved += orig_xfrlen; + /* * Check for commands that are already dead */ if (tmd->cd_lflags & CDFL_ABORTED) { - isp_prt(isp, ISP_LOGINFO, "[%llx] already ABORTED- not sending a CTIO", (ull) tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "[%llx] already ABORTED- not sending a CTIO", (ull) tmd->cd_tagval); xact->td_error = -ENXIO; goto out; } @@ -1540,18 +1573,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) isp_prt(isp, ISP_LOGWARN, "[%llx] cdb0 0x%02x CHECK CONDITION but bogus sense 0x%x/0x%x/0x%x", (ull) tmd->cd_tagval, tmd->cd_cdb[0], tmd->cd_sense[0], tmd->cd_sense[12], tmd->cd_sense[13]); } - MEMZERO(local, QENTRY_LEN); - - /* - * Use this lock to protect tmd fields - */ - ISP_LOCK_SOFTC(isp); - - /* - * Pre-increment cd_moved so we know how many bytes are actually in transit. If we actually fail to move - * the bytes, we'll subtract things out when we collect status. - */ - tmd->cd_moved += xact->td_xfrlen; + memset(local, 0, QENTRY_LEN); /* * Set the residual to be equal to the total length less the amount previously moved plus this transfer size @@ -1568,11 +1590,11 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; cto->ct_header.rqs_entry_count = 1; cto->ct_nphdl = tmd->cd_nphdl; - cto->ct_rxid = AT2_GET_TAG(tmd->cd_tagval); + cto->ct_rxid = tmd->cd_tagval; cto->ct_iid_lo = tmd->cd_portid; cto->ct_iid_hi = tmd->cd_portid >> 16; cto->ct_oxid = tmd->cd_oxid; - cto->ct_vpindex = tmd->cd_channel; + cto->ct_vpidx = tmd->cd_channel; cto->ct_scsi_status = tmd->cd_scsi_status; cto->ct_timeout = ISP_CT_TIMEOUT; @@ -1599,7 +1621,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) cto->ct_flags |= CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS; if ((xact->td_hflags & TDFH_SNSVALID) != 0) { cto->rsp.m1.ct_resplen = cto->ct_senselen = min(TMD_SENSELEN, MAXRESPLEN_24XX); - MEMCPY(cto->rsp.m1.ct_resp, tmd->cd_sense, cto->ct_senselen); + memcpy(cto->rsp.m1.ct_resp, tmd->cd_sense, cto->ct_senselen); cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); } } else { @@ -1637,11 +1659,10 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) if (ISP_CAP_SCCFW(isp)) { cto->ct_lun = L0LUN_TO_FLATLUN(tmd->cd_lun); } - cto->ct_rxid = AT2_GET_TAG(tmd->cd_tagval); + cto->ct_rxid = tmd->cd_tagval; if (cto->ct_rxid == 0) { isp_prt(isp, ISP_LOGERR, "a tagval of zero is not acceptable"); xact->td_error = -EINVAL; - ISP_UNLK_SOFTC(isp); goto out; } cto->ct_timeout = ISP_CT_TIMEOUT; @@ -1658,7 +1679,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) *ssptr = tmd->cd_scsi_status; if ((xact->td_hflags & TDFH_SNSVALID) != 0) { cto->rsp.m1.ct_senselen = min(TMD_SENSELEN, MAXRESPLEN); - MEMCPY(cto->rsp.m1.ct_resp, tmd->cd_sense, cto->rsp.m1.ct_senselen); + memcpy(cto->rsp.m1.ct_resp, tmd->cd_sense, cto->rsp.m1.ct_senselen); cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; } } else { @@ -1737,14 +1758,12 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) if (isp_getrqentry(isp, &nxti, &optr, &qe)) { isp_prt(isp, ISP_LOGWARN, "%s: request queue overflow", __func__); xact->td_error = -ENOMEM; - ISP_UNLK_SOFTC(isp); goto out; } if (isp_save_xs_tgt(isp, xact, &handle)) { isp_prt(isp, ISP_LOGERR, "isp_target_start_ctio: No XFLIST pointers"); xact->td_error = -ENOMEM; - ISP_UNLK_SOFTC(isp); goto out; } @@ -1768,31 +1787,39 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) switch (ISP_DMASETUP(isp, (XS_T *)xact, (ispreq_t *) local, &nxti, optr)) { case CMD_QUEUED: ISP_ADD_REQUEST(isp, nxti); + tmd->cd_req_cnt += 1; ISP_UNLK_SOFTC(isp); return; case CMD_EAGAIN: xact->td_error = -ENOMEM; - isp_destroy_tgt_handle(isp, handle); - break; + /* FALLTHROUGH */ case CMD_COMPLETE: + BUG_ON(xact->td_error == 0); isp_destroy_tgt_handle(isp, handle); break; default: - xact->td_error = -EFAULT; /* probably dma mapping failure */ - isp_destroy_tgt_handle(isp, handle); + BUG(); break; } - ISP_UNLK_SOFTC(isp); + out: + /* + * XXX: Note that this is different from the vanilla Feral driver + * XXX: which requires a callback no matter what. SCST requires + * XXX: synchronous error returns if you can't start a command + * XXX: and to avoid race conditions and locks we don't do an + * XXX: upcall in this case. + */ if (xact->td_error) { - xact->td_lflags |= TDFL_ERROR; - } - if ((tmd->cd_lflags & CDFL_LCL) == 0) { + xact->td_lflags |= TDFL_ERROR|TDFL_SYNCERROR; + tmd->cd_moved -= orig_xfrlen; + } else if ((tmd->cd_lflags & CDFL_LCL) == 0) { CALL_PARENT_XFR(isp, xact); } + ISP_UNLK_SOFTC(isp); } static void @@ -1831,7 +1858,7 @@ isp_lcl_respond(ispsoftc_t *isp, void *aep, tmd_cmd_t *tmd) ISP_BSET(isp->isp_osinfo.auxbmap, i); xact = &isp->isp_osinfo.auxinfo[i].xact; dp = &isp->isp_osinfo.auxinfo[i].sg; - MEMZERO(dp, sizeof (*dp)); + memset(dp, 0, sizeof (*dp)); sg_assign_page(dp, virt_to_page(isp->isp_osinfo.inqdata)); dp->offset = offset_in_page(isp->isp_osinfo.inqdata); dp->length = DEFAULT_INQSIZE; @@ -1888,7 +1915,7 @@ isp_lcl_respond(ispsoftc_t *isp, void *aep, tmd_cmd_t *tmd) isp_endcmd(isp, aep, 0x25005102, 0); } } - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); if (isp->isp_osinfo.tfreelist) { isp->isp_osinfo.bfreelist->cd_next = tmd; } else { @@ -1948,7 +1975,7 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep) if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) { isp->isp_osinfo.bfreelist = NULL; } - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); /* * Set the local flags to BUSY. Also set the flags @@ -1964,11 +1991,11 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep) tmd->cd_flags |= CDF_NODISC; } if (status & QLTM_SVALID) { - MEMCPY(tmd->cd_sense, aep->at_sense, QLTM_SENSELEN); + memcpy(tmd->cd_sense, aep->at_sense, QLTM_SENSELEN); tmd->cd_flags |= CDF_SNSVALID; } - MEMCPY(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO_CDBLEN)); - AT_MAKE_TAGID(tmd->cd_tagval, tmd->cd_channel, isp->isp_unit, aep); + memcpy(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO_CDBLEN)); + AT_MAKE_TAGID(tmd->cd_tagval, aep); tmd->cd_tagtype = aep->at_tag_type; tmd->cd_hba = isp; isp_prt(isp, ISP_LOGTDEBUG0, "ATIO[%llx] CDB=0x%x bus %d iid%d->lun%d ttype 0x%x %s", (ull) tmd->cd_tagval, aep->at_cdb[0] & 0xff, @@ -2039,7 +2066,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) { isp->isp_osinfo.bfreelist = NULL; } - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); /* * Set the local flags to BUSY. Also set the flags @@ -2056,7 +2083,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) tmd->cd_nphdl = loopid; tmd->cd_tgt = FCPARAM(isp, 0)->isp_wwpn; FLATLUN_TO_L0LUN(tmd->cd_lun, lun); - MEMCPY(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO2_CDBLEN)); + memcpy(tmd->cd_cdb, aep->at_cdb, min(TMD_CDBLEN, ATIO2_CDBLEN)); switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) { case ATIO2_TC_ATTR_SIMPLEQ: @@ -2092,7 +2119,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) break; } - AT2_MAKE_TAGID(tmd->cd_tagval, 0, isp->isp_unit, aep); + tmd->cd_tagval = aep->at_rxid; tmd->cd_hba = isp; tmd->cd_totlen = aep->at_datalen; if ((isp->isp_dblev & ISP_LOGTDEBUG0) || isp->isp_osinfo.hcb == 0) { @@ -2186,7 +2213,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) { isp->isp_osinfo.bfreelist = NULL; } - MEMCPY(tmd, aep, sizeof (at7_entry_t)); + memcpy(tmd, aep, sizeof (at7_entry_t)); /* we should be safe here ... */ tmd->cd_lflags = CDFL_BUSY; tmd->cd_next = isp->isp_osinfo.waiting_t; @@ -2234,7 +2261,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) { isp->isp_osinfo.bfreelist = NULL; } - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); /* * Set the local flags to BUSY. @@ -2246,7 +2273,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored"); } cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb); - MEMCPY(tmd->cd_cdb, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen); + memcpy(tmd->cd_cdb, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen); tmd->cd_totlen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) { @@ -2288,9 +2315,9 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) tmd->cd_tgt = FCPARAM(isp, chan)->isp_wwpn; /* channel is valid at this point */ tmd->cd_nphdl = nphdl; /* nphdl is either known or NIL- in either case, we can set it if needed */ - AT2_MAKE_TAGID(tmd->cd_tagval, chan, isp->isp_unit, aep); /* we can construct a tag value at this point */ + tmd->cd_tagval = aep->at_rxid; /* we can construct a tag value at this point */ tmd->cd_iid = iid; /* iid is either INI_NONE or known */ - MEMCPY(tmd->cd_lun, aep->at_cmnd.fcp_cmnd_lun, sizeof (tmd->cd_lun)); + memcpy(tmd->cd_lun, aep->at_cmnd.fcp_cmnd_lun, sizeof (tmd->cd_lun)); tmd->cd_portid = sid; tmd->cd_channel = chan; tmd->cd_hba = isp; @@ -2325,7 +2352,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) isp_prt(isp, ISP_LOGTDEBUG0, "[0x%llx] asking taskthread to find iid of initiator", (ull) tmd->cd_tagval); if (isp_thread_event(isp, ISP_THREAD_FINDIID, tmd, 0, __func__, __LINE__)) { isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0); - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); if (isp->isp_osinfo.tfreelist) { isp->isp_osinfo.bfreelist->cd_next = tmd; } else { @@ -2346,12 +2373,12 @@ isp_terminate_cmd(ispsoftc_t *isp, tmd_cmd_t *tmd) if (IS_24XX(isp)) { isp_prt(isp, ISP_LOGTINFO, "isp_terminate_cmd: [%llx] is being terminated", (ull) tmd->cd_tagval); - MEMZERO(&local, sizeof (local)); + memset(&local, 0, sizeof (local)); cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; cto->ct_header.rqs_entry_count = 1; cto->ct_nphdl = tmd->cd_nphdl; - cto->ct_rxid = AT2_GET_TAG(tmd->cd_tagval); - cto->ct_vpindex = AT2_GET_BUS(tmd->cd_tagval); + cto->ct_rxid = tmd->cd_tagval; + cto->ct_vpidx = tmd->cd_channel; cto->ct_iid_lo = tmd->cd_portid; cto->ct_iid_hi = tmd->cd_portid >> 16; cto->ct_oxid = tmd->cd_oxid; @@ -2428,7 +2455,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) if (ct->ct_status & QLTM_SVALID) { char *sp = (char *)ct; sp += CTIO_SENSE_OFFSET; - MEMCPY(tmd->cd_sense, sp, QLTM_SENSELEN); + memcpy(tmd->cd_sense, sp, QLTM_SENSELEN); tmd->cd_flags |= CDF_SNSVALID; } if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { @@ -2442,6 +2469,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) if (ok && sentstatus && (xact->td_hflags & TDFH_SNSVALID)) { xact->td_lflags |= TDFL_SENTSENSE; } + tmd->cd_req_cnt -= 1; tmd->cd_moved -= resid; @@ -2519,13 +2547,13 @@ isp_target_putback_atio(ispsoftc_t *isp, tmd_cmd_t *tmd) return (-ENOMEM); } isp_prt(isp, ISP_LOGTDEBUG0, "[%llx] resource putback being sent", (ull) tmd->cd_tagval); - MEMZERO(local, sizeof (local)); + memset(local, 0, sizeof (local)); if (IS_FC(isp)) { at2_entry_t *at = (at2_entry_t *) local; at->at_header.rqs_entry_type = RQSTYPE_ATIO2; at->at_header.rqs_entry_count = 1; at->at_status = CT_OK; - at->at_rxid = AT2_GET_TAG(tmd->cd_tagval); + at->at_rxid = tmd->cd_tagval; if (ISP_CAP_2KLOGIN(isp)) { at2e_entry_t *ate = (at2e_entry_t *) local; FLATLUN_TO_L0LUN(tmd->cd_lun, ate->at_scclun); @@ -2563,7 +2591,7 @@ isp_complete_ctio(ispsoftc_t *isp, tmd_xact_t *xact) if (isp->isp_osinfo.hcb || (tmd->cd_lflags & CDFL_LCL)) { if (isp->isp_osinfo.hcb == 0) { isp_prt(isp, ISP_LOGWARN, "nobody to tell about CTIO complete, leaking xact structure"); - MEMZERO(tmd, TMD_SIZE); + memset(tmd, 0, TMD_SIZE); if (isp->isp_osinfo.tfreelist) { isp->isp_osinfo.bfreelist->cd_next = tmd; } else { @@ -2598,7 +2626,7 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) vp_modify_t *vp; uint8_t qe[QENTRY_LEN], *scp; - MEMZERO(qe, QENTRY_LEN); + memset(qe, 0, QENTRY_LEN); /* Acquire Scratch */ if (FC_SCRATCH_ACQUIRE(isp, chan)) { @@ -2630,7 +2658,7 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) /* * Build a EXEC IOCB A64 command that points to the VP MODIFY command */ - MEMZERO(&mbs, sizeof (mbs)); + memset(&mbs, 0, sizeof (mbs)); mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; mbs.param[1] = QENTRY_LEN; mbs.param[2] = DMA_WD1(fcp->isp_scdma); @@ -2752,7 +2780,7 @@ isp_enable_lun(ispsoftc_t *isp, uint16_t bus, uint16_t lun) */ if (tb < isp->isp_nchan) { mbreg_t mbs; - MEMZERO(&mbs, sizeof (mbs)); + memset(&mbs, 0, sizeof (mbs)); mbs.param[0] = MBOX_ENABLE_TARGET_MODE; mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG; mbs.param[2] = bus << 7; @@ -2973,7 +3001,7 @@ out: if (bus == isp->isp_nchan) { int r; mbreg_t mbs; - MEMZERO(&mbs, sizeof (mbs)); + memset(&mbs, 0, sizeof (mbs)); mbs.param[0] = MBOX_ENABLE_TARGET_MODE; mbs.param[2] = bus << 7; mbs.logval = MBLOGNONE; @@ -3112,21 +3140,21 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (i >= FL_ID && i <= SNS_ID) { continue; } - if (fcp->isp_ini_map[i] == 0) { + if (fcp->isp_dev_map[i] == 0) { break; } } if (i < MAX_FC_TARG) { - fcp->isp_ini_map[i] = dbidx + 1; - lp->ini_map_idx = i + 1; + fcp->isp_dev_map[i] = dbidx + 1; + lp->dev_map_idx = i + 1; } else { isp_prt(isp, ISP_LOGWARN, "out of target ids"); isp_dump_portdb(isp, bus); } } - if (lp->ini_map_idx) { + if (lp->dev_map_idx) { unsigned long arg; - tgt = lp->ini_map_idx - 1; + tgt = lp->dev_map_idx - 1; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn); arg = tgt | (bus << 16); isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__); @@ -3142,10 +3170,10 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) fcp = FCPARAM(isp, bus); lp->portid = lp->new_portid; lp->roles = lp->new_roles; - if (lp->ini_map_idx) { - int t = lp->ini_map_idx - 1; - fcp->isp_ini_map[t] = (lp - fcp->portdb) + 1; - tgt = lp->ini_map_idx - 1; + if (lp->dev_map_idx) { + int t = lp->dev_map_idx - 1; + fcp->isp_dev_map[t] = (lp - fcp->portdb) + 1; + tgt = lp->dev_map_idx - 1; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "changed at", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn); } else { isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "changed", (ull) lp->node_wwn, (ull) lp->port_wwn); @@ -3156,8 +3184,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) bus = va_arg(ap, int); lp = va_arg(ap, fcportdb_t *); va_end(ap); - if (lp->ini_map_idx) { - tgt = lp->ini_map_idx - 1; + if (lp->dev_map_idx) { + tgt = lp->dev_map_idx - 1; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "stayed at", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn); } else { isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "stayed", (ull) lp->node_wwn, (ull) lp->port_wwn); @@ -3169,12 +3197,12 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) lp = va_arg(ap, fcportdb_t *); va_end(ap); fcp = FCPARAM(isp, bus); - if (lp->ini_map_idx) { + if (lp->dev_map_idx) { unsigned long arg; - tgt = lp->ini_map_idx - 1; - fcp->isp_ini_map[tgt] = 0; + tgt = lp->dev_map_idx - 1; + fcp->isp_dev_map[tgt] = 0; lp->state = FC_PORTDB_STATE_NIL; - lp->ini_map_idx = 0; + lp->dev_map_idx = 0; isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, (ull) lp->node_wwn, (ull) lp->port_wwn); arg = tgt | (bus << 16) | (1 << 31); isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__); @@ -3218,11 +3246,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) #ifdef ISP_TARGET_MODE case ISPASYNC_TARGET_NOTIFY: { - isp_notify_t *ins; - tmd_notify_t *mp; + notify_t *ins; + isp_notify_t *mp; va_start(ap, cmd); - mp = va_arg(ap, tmd_notify_t *); + mp = va_arg(ap, isp_notify_t *); va_end(ap); if (isp->isp_osinfo.hcb == 0) { @@ -3239,9 +3267,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved; - MEMCPY(&ins->notify, mp, sizeof (tmd_notify_t)); + memcpy(&ins->notify, mp, sizeof (isp_notify_t)); if (mp->nt_lreserved) { - MEMCPY(ins->qentry, mp->nt_lreserved, QENTRY_LEN); + memcpy(ins->qentry, mp->nt_lreserved, QENTRY_LEN); ins->qevalid = 1; } else { ins->qevalid = 0; @@ -3279,7 +3307,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) /* FALLTHROUGH */ default: if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) { - mp->nt_iid = lp->port_wwn; + mp->nt_wwn = lp->port_wwn; } break; } @@ -3291,23 +3319,22 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } else if (IS_FC(isp)) { uint16_t loopid; - FC_TAG_INSERT_INST(mp->nt_tagval, isp->isp_unit); /* - * The outer layer just set the loopid into nt_iid. We try and find the WWPN. + * The outer layer just set the loopid into nt_wwn. We try and find the WWPN. */ - loopid = ins->notify.nt_iid; + loopid = ins->notify.nt_wwn; switch (mp->nt_ncode) { case NT_HBA_RESET: case NT_LINK_UP: case NT_LINK_DOWN: - ins->notify.nt_iid = INI_NONE; + ins->notify.nt_wwn = INI_NONE; break; default: if (isp_find_pdb_by_loopid(isp, mp->nt_channel, loopid, &lp) == 0) { isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for loopid 0x%x for notify action 0x%x", loopid, mp->nt_ncode); - ins->notify.nt_iid = INI_NONE; + ins->notify.nt_wwn = INI_NONE; } else { - ins->notify.nt_iid = lp->port_wwn; + ins->notify.nt_wwn = lp->port_wwn; } break; } @@ -3315,11 +3342,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) * Replace target with our port WWN. */ mp->nt_tgt = FCPARAM(isp, mp->nt_channel)->isp_wwpn; - } else { - TAG_INSERT_INST(mp->nt_tagval, isp->isp_unit); } isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x iid 0x%016llx tgt 0x%016llx lun %u tag %llx", - mp->nt_ncode, (ull) mp->nt_iid, (ull) mp->nt_tgt, mp->nt_lun, mp->nt_tagval); + mp->nt_ncode, (ull) mp->nt_wwn, (ull) mp->nt_tgt, mp->nt_lun, mp->nt_tagval); CALL_PARENT_NOTIFY(isp, ins); break; } @@ -3357,47 +3382,60 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; case RQSTYPE_ABTS_RCVD: { - isp_notify_t *ins = NULL; + notify_t *ins = NULL; + tmd_cmd_t *tmd; abts_t *abts = qe; - abts_rsp_t *rsp = qe; - int chan, i; - uint32_t sid; - - rsp->abts_rsp_header.rqs_entry_type = RQSTYPE_ABTS_RSP; - sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; + int i; + uint16_t chan, lun; + uint32_t sid, did; if (isp->isp_osinfo.hcb == 0) { - isp_prt(isp, ISP_LOGINFO, "RQSTYPE_ABTS_RCVD: with no upstream listener"); - rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; - isp_notify_ack(isp, qe); + isp_prt(isp, ISP_LOGTINFO, "RQSTYPE_ABTS_RCVD: with no upstream listener"); + WARN_ON(isp_acknak_abts(isp, qe, 0)); break; } + + did = (abts->abts_did_hi << 16) | abts->abts_did_lo; + sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; + + /* + * Try to find the original tmd so we can get the lun. + */ + for (i = 0; i < NTGT_CMDS; i++) { + tmd = &isp->isp_osinfo.pool[i]; + if (tmd->cd_lflags & CDFL_BUSY) { + if (tmd->cd_tagval == abts->abts_rx_id && tmd->cd_oxid == abts->abts_ox_id) { + break; + } + } + tmd = NULL; + } + + if (tmd == NULL) { + lun = LUN_ANY; + } else { + lun = L0LUN_TO_FLATLUN(tmd->cd_lun); + } + if (abts->abts_rxid_task == ISP24XX_NO_TASK) { isp_prt(isp, ISP_LOGTINFO, "ABTS from N-Port handle 0x%x Port 0x%06x has no task id (rx_id 0x%04x ox_id 0x%04x)", abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id); - for (i = 0; i < NTGT_CMDS; i++) { - tmd_cmd_t *tmd = &isp->isp_osinfo.pool[i]; - if (tmd->cd_lflags & CDFL_BUSY) { - if (AT2_GET_TAG(tmd->cd_tagval) == abts->abts_rx_id && tmd->cd_oxid == abts->abts_ox_id) { - isp_prt(isp, ISP_LOGTINFO, "... but found tmd to to mark as aborted"); - tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP; - break; - } - } + if (tmd) { + isp_prt(isp, ISP_LOGTINFO, "... but found tmd to to mark as aborted (active xact count %d)", tmd->cd_req_cnt); + tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP; } - rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; - isp_notify_ack(isp, qe); + WARN_ON(isp_acknak_abts(isp, qe, 0)); break; } + ins = isp->isp_osinfo.nfreelist; if (ins == NULL) { - isp_prt(isp, ISP_LOGTINFO, "out of TMD NOTIFY structs for RQSTYPE_ABTS_RCVD"); - rsp->abts_rsp_ctl_flags = ISP24XX_ABTS_RSP_TERMINATE; - isp_notify_ack(isp, qe); + isp_prt(isp, ISP_LOGWARN, "out of TMD NOTIFY structs for RQSTYPE_ABTS_RCVD"); + WARN_ON(isp_acknak_abts(isp, qe, ENOMEM)); break; } isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved; - MEMZERO(&ins->notify, sizeof (tmd_notify_t)); + memset(&ins->notify, 0, sizeof (isp_notify_t)); lp = NULL; for (chan = 0; chan < isp->isp_nchan; chan++) { if (isp_find_pdb_by_loopid(isp, chan, abts->abts_nphdl, &lp)) { @@ -3405,45 +3443,48 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } } if (lp == NULL) { - isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for N-port handle 0x%x for ABTS", abts->abts_nphdl); - ins->notify.nt_iid = INI_ANY; + if (tmd) { + ins->notify.nt_wwn = tmd->cd_iid; + chan = tmd->cd_channel; + } else { + isp_prt(isp, ISP_LOGTINFO, "cannot find WWN for N-port handle 0x%x for ABTS", abts->abts_nphdl); + ins->notify.nt_wwn = INI_ANY; + chan = ISP_GET_VPIDX(isp, ISP_NOCHAN); + } } else { - ins->notify.nt_iid = lp->port_wwn; + ins->notify.nt_wwn = lp->port_wwn; } - MEMCPY(ins->qentry, qe, QENTRY_LEN); + memcpy(ins->qentry, qe, QENTRY_LEN); ins->qevalid = 1; ins->notify.nt_hba = isp; ins->notify.nt_tgt = FCPARAM(isp, chan)->isp_wwpn; - ins->notify.nt_lun = LUN_ANY; + ins->notify.nt_sid = sid; + ins->notify.nt_did = did; + ins->notify.nt_nphdl = abts->abts_nphdl; + ins->notify.nt_lun = lun; ins->notify.nt_tagval = abts->abts_rxid_task; - FC_TAG_INSERT_INST(ins->notify.nt_tagval, isp->isp_unit); ins->notify.nt_ncode = NT_ABORT_TASK; ins->notify.nt_need_ack = 1; ins->notify.nt_channel = chan; ins->notify.nt_tmd = NULL; /* - * Find the command if possible and mark it aborted and needing cleanup + * If we have the command mark it aborted and needing cleanup */ - for (i = 0; i < NTGT_CMDS; i++) { - tmd_cmd_t *tmd = &isp->isp_osinfo.pool[i]; - if (tmd->cd_lflags & CDFL_BUSY) { - if (ins->notify.nt_tagval == tmd->cd_tagval && ins->notify.nt_channel == tmd->cd_channel) { - isp_prt(isp, ISP_LOGTINFO, "[0x%llx] marked as aborted", (ull) tmd->cd_tagval); - tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP; - ins->notify.nt_tmd = tmd; - break; - } - } + if (tmd) { + isp_prt(isp, ISP_LOGTINFO, "[0x%llx] marked as aborted (active xact count %d)", (ull) tmd->cd_tagval, tmd->cd_req_cnt); + tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP; + ins->notify.nt_tmd = tmd; } - isp_prt(isp, ISP_LOGTINFO, "ABTS [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); + isp_prt(isp, ISP_LOGTINFO, "ABTS [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_wwn); CALL_PARENT_NOTIFY(isp, ins); break; } case RQSTYPE_NOTIFY: { - isp_notify_t *ins = NULL; + notify_t *ins = NULL; uint16_t status, nphdl; uint32_t lun, seqid, portid; + uint8_t *ptr = NULL; if (isp->isp_osinfo.hcb == 0) { isp_prt(isp, ISP_LOGWARN, "TARGET_NOTIFY with no upstream listener"); @@ -3468,18 +3509,18 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; } isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved; - MEMZERO(&ins->notify, sizeof (tmd_notify_t)); - MEMCPY(ins->qentry, qe, QENTRY_LEN); + memset(&ins->notify, 0, sizeof (isp_notify_t)); + memcpy(ins->qentry, qe, QENTRY_LEN); ins->qevalid = 1; ins->notify.nt_hba = isp; - ins->notify.nt_iid = GET_IID_VAL(inot->in_iid); + ins->notify.nt_wwn = GET_IID_VAL(inot->in_iid); ins->notify.nt_tgt = inot->in_tgt; ins->notify.nt_lun = inot->in_lun; - IN_MAKE_TAGID(ins->notify.nt_tagval, GET_BUS_VAL(inot->in_iid), isp->isp_unit, inot); + IN_MAKE_TAGID(ins->notify.nt_tagval, inot); ins->notify.nt_ncode = NT_ABORT_TASK; ins->notify.nt_need_ack = 1; - isp_prt(isp, ISP_LOGINFO, "ABORT TASK [%llx] from iid %u to lun %u", (ull) ins->notify.nt_tagval, - (uint32_t) ins->notify.nt_iid, inot->in_lun); + isp_prt(isp, ISP_LOGTINFO, "ABORT TASK [%llx] from iid %u to lun %u", (ull) ins->notify.nt_tagval, + (uint32_t) ins->notify.nt_wwn, inot->in_lun); CALL_PARENT_NOTIFY(isp, ins); break; } else { @@ -3509,7 +3550,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) case LOGO: msg = "LOGO"; if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { - uint8_t *ptr = qe; /* point to unswizzled entry! */ + ptr = qe; /* point to unswizzled entry! */ wwn = (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF]) << 56) | (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) | @@ -3522,7 +3563,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } else { wwn = INI_ANY; } - isp_del_wwn_entry(isp, inot->in_vpindex, wwn, nphdl, portid); + isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), wwn, nphdl, portid); break; case PRLO: msg = "PRLO"; @@ -3543,62 +3584,51 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } else { wwn = INI_NONE; } - isp_add_wwn_entry(isp, inot->in_vpindex, wwn, nphdl, portid); + isp_add_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), wwn, nphdl, portid); break; case PRLI: msg = "PRLI"; break; case PDISC: isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID N-Port Handle 0x%x Port ID 0x%06x PDISC", - __func__, inot->in_vpindex, nphdl, portid); + __func__, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, portid); break; default: isp_prt(isp, ISP_LOGTINFO, "ELS CODE 0x%x Received from 0x%06x", inot->in_status_subcode, portid); break; } if (msg) { - isp_prt(isp, ISP_LOGTINFO, "%s Chan %d ELS N-port handle %x PortID 0x%06x", msg, inot->in_vpindex, nphdl, portid); + isp_prt(isp, ISP_LOGTINFO, "%s Chan %d ELS N-port handle %x PortID 0x%06x", msg, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, portid); } if ((inot->in_flags & IN24XX_FLAG_PUREX_IOCB) == 0) { isp_notify_ack(isp, qe); } break; } - case IN24XX_PORT_CHANGED: case IN24XX_PORT_LOGOUT: + ptr = "PORT LOGOUT"; + /* FALLTHROUGH */ + case IN24XX_PORT_CHANGED: + if (ptr == NULL) { + ptr = "PORT CHANGED"; + } + /* FALLTHROUGH */ + case IN24XX_LIP_RESET: + if (ptr == NULL) { + ptr = "LIP RESET"; + } + isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr, inot->in_status_subcode, nphdl); - ins = isp->isp_osinfo.nfreelist; - if (ins == NULL) { - isp_prt(isp, ISP_LOGERR, "out of TMD NOTIFY structs for RQSTYPE_NOTIFY!"); - isp_notify_ack(isp, qe); - break; - } - isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved; - MEMZERO(ins, sizeof (*ins)); - if (isp_find_pdb_by_loopid(isp, inot->in_vpindex, nphdl, &lp) == 0) { - isp_prt(isp, ISP_LOGWARN, "cannot find WWN for N-port handle 0x%x for ABORT TASK", nphdl); - isp_notify_ack(isp, qe); - ins->notify.nt_lreserved = isp->isp_osinfo.nfreelist; - isp->isp_osinfo.nfreelist = ins; - break; - } - ins->notify.nt_iid = lp->port_wwn; - MEMCPY(ins->qentry, qe, QENTRY_LEN); - ins->qevalid = 1; - ins->notify.nt_hba = isp; - ins->notify.nt_ncode = NT_LOGOUT; - isp_prt(isp, ISP_LOGTINFO, "%s: isp_del_wwn being called on Chan %d because of PC/PL(0x%x) for 0x%016llx loopid 0x%02x", - __func__, inot->in_vpindex, status, (ull) ins->notify.nt_iid, nphdl); - isp_del_wwn_entry(isp, inot->in_vpindex, ins->notify.nt_iid, nphdl, portid); - ins->notify.nt_tagval = seqid; - isp_prt(isp, ISP_LOGINFO, "PORT %s [%llx] from 0x%016llx", status == IN24XX_PORT_CHANGED? "CHANGED" : "LOGOUT", - (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); - CALL_PARENT_NOTIFY(isp, ins); + /* + * All subcodes here are irrelevant. What is relevant + * is that we need to terminate all active commands from + * this initiator (known by N-port handle). + */ + /* XXX IMPLEMENT XXX */ + isp_notify_ack(isp, inot); break; - - case IN24XX_LIP_RESET: /* XXX: SHOULD BE TREATED LIKE BUS RESET */ - case IN24XX_LINK_RESET: /* XXX: EXCEPT THAT WE HAVE TO HAVE THE */ - case IN24XX_LINK_FAILED:/* XXX: ENTRY TO ACK BACK WITH */ + case IN24XX_LINK_RESET: + case IN24XX_LINK_FAILED: case IN24XX_SRR_RCVD: default: isp_notify_ack(isp, qe); @@ -3631,8 +3661,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; } isp->isp_osinfo.nfreelist = ins->notify.nt_lreserved; - MEMZERO(&ins->notify, sizeof (tmd_notify_t)); - MEMCPY(ins->qentry, qe, QENTRY_LEN); + memset(&ins->notify, 0, sizeof (isp_notify_t)); + memcpy(ins->qentry, qe, QENTRY_LEN); ins->qevalid = 1; ins->notify.nt_hba = isp; } else { @@ -3644,18 +3674,18 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (status == IN_ABORT_TASK) { if (isp_find_pdb_by_loopid(isp, 0, nphdl, &lp) == 0) { isp_prt(isp, ISP_LOGINFO, "cannot find WWN for loopid 0x%x for ABORT TASK", nphdl); - ins->notify.nt_iid = INI_NONE; + ins->notify.nt_wwn = INI_NONE; } else { - ins->notify.nt_iid = lp->port_wwn; + ins->notify.nt_wwn = lp->port_wwn; } ins->notify.nt_channel = 0; ins->notify.nt_tgt = FCPARAM(isp, 0)->isp_wwpn; ins->notify.nt_lun = lun; ins->notify.nt_need_ack = 1; - IN_FC_MAKE_TAGID(ins->notify.nt_tagval, 0, isp->isp_unit, seqid); + ins->notify.nt_tagval = seqid; ins->notify.nt_ncode = NT_ABORT_TASK; - isp_prt(isp, ISP_LOGINFO, "ABORT TASK [%llx] from 0x%016llx to lun %u", (ull) ins->notify.nt_tagval, - (ull) ins->notify.nt_iid, lun); + isp_prt(isp, ISP_LOGTINFO, "ABORT TASK [%llx] from 0x%016llx to lun %u", (ull) ins->notify.nt_tagval, + (ull) ins->notify.nt_wwn, lun); CALL_PARENT_NOTIFY(isp, ins); break; } else if (status == IN_PORT_LOGOUT) { @@ -3663,12 +3693,12 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) * The port specified by the loop id listed in nphdl has logged out. We need to tell our upstream listener about it. */ if (isp_find_pdb_by_loopid(isp, 0, nphdl, &lp)) { - ins->notify.nt_iid = lp->port_wwn; + ins->notify.nt_wwn = lp->port_wwn; ins->notify.nt_ncode = NT_LOGOUT; - isp_prt(isp, ISP_LOGTINFO, "%s: isp_del_wwn called for 0x%016llx due to PORT_LOGOUT", __func__, (ull) ins->notify.nt_iid); - isp_del_wwn_entry(isp, 0, ins->notify.nt_iid, nphdl, PORT_ANY); - IN_FC_MAKE_TAGID(ins->notify.nt_tagval, 0, isp->isp_unit, seqid); - isp_prt(isp, ISP_LOGINFO, "PORT LOGOUT [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); + isp_prt(isp, ISP_LOGTINFO, "%s: isp_del_wwn called for 0x%016llx due to PORT_LOGOUT", __func__, (ull) ins->notify.nt_wwn); + isp_del_wwn_entry(isp, 0, ins->notify.nt_wwn, nphdl, PORT_ANY); + ins->notify.nt_tagval = seqid; + isp_prt(isp, ISP_LOGTINFO, "PORT LOGOUT [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_wwn); ins->notify.nt_need_ack = 1; CALL_PARENT_NOTIFY(isp, ins); break; @@ -3697,7 +3727,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) */ isp_prt(isp, ISP_LOGTINFO, "%s: isp_del_wwn called for everyone due to GLOBAL PORT_LOGOUT", __func__); isp_del_wwn_entry(isp, 0, INI_ANY, NIL_HANDLE, PORT_ANY); - ins->notify.nt_iid = INI_ANY; + ins->notify.nt_wwn = INI_ANY; ins->notify.nt_ncode = NT_LOGOUT; ins->notify.nt_need_ack = 1; CALL_PARENT_NOTIFY(isp, ins); @@ -3891,53 +3921,63 @@ isplinux_timer(unsigned long arg) { Scsi_Cmnd *Cmnd; ispsoftc_t *isp = (ispsoftc_t *) arg; - uint32_t isr; - uint16_t sema, mbox; unsigned long flags; int i; -#ifdef ISP_TARGET_MODE - tmd_cmd_t *wt = NULL; - int didintr = 0; -#endif ISP_ILOCK_SOFTC(isp); isp->isp_osinfo.dogcnt++; - if (isp->isp_dead == 0) { - if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { - isp_intr(isp, isr, sema, mbox); - if (isp->intsok) { - ISP_ENABLE_INTS(isp); - } -#ifdef ISP_TARGET_MODE - didintr = 1; -#endif - } - } for (i = 0; i < isp->isp_nchan; i++) { if (ISP_DATA(isp, i)->qfdelay) { ISP_DATA(isp, i)->qfdelay--; } } + + /* + * Check to see whether we need to check for loop state + */ if (IS_FC(isp) && isp->isp_state == ISP_RUNSTATE) { for (i = 0 ; i < isp->isp_nchan; i++) { fcparam *fcp = FCPARAM(isp, i); - if (fcp->role != ISP_ROLE_NONE && ISP_DATA(isp, i)->fcrswdog && ISP_DATA(isp, i)->deadloop == 0) { - ISP_DATA(isp, i)->fcrswdog = 1; + if (fcp->role == ISP_ROLE_NONE || ISP_DATA(isp, i)->deadloop || ISP_DATA(isp, i)->nextscan == 0) { + continue; + } + if (jiffies > ISP_DATA(isp, i)->nextscan) { + ISP_DATA(isp, i)->nextscan = jiffies; isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __func__, __LINE__); } } } + + /* + * Run any commands that were waitinbg. + */ isplinux_runwaitq(isp); + + /* + * Pick up any commands needing completion... + */ + if ((Cmnd = isp->isp_osinfo.dqnext) != NULL) { isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL; } + + /* + * Set up the timer again + */ if (isp->dogactive) { isp->isp_osinfo.timer.expires = jiffies + ISP_WATCH_TIME; add_timer(&isp->isp_osinfo.timer); } + #ifdef ISP_TARGET_MODE + /* + * Fire up any delayed target mode actions based + * upon whether the dog counter has wrapped to + * zero. + */ if (isp->isp_osinfo.dogcnt == 0) { + tmd_cmd_t *wt; while ((wt = isp->isp_osinfo.waiting_t) != NULL) { isp->isp_osinfo.waiting_t = wt->cd_next; wt->cd_next = NULL; @@ -3949,12 +3989,12 @@ isplinux_timer(unsigned long arg) } } #endif + ISP_IUNLK_SOFTC(isp); -#ifdef ISP_TARGET_MODE - if (didintr) { - isp_tgt_tq(isp); - } -#endif + + /* + * Complete any commands that had been on the done queue + */ if (Cmnd) { ISP_LOCK_SCSI_DONE(isp); while (Cmnd) { @@ -3967,19 +4007,6 @@ isplinux_timer(unsigned long arg) } } -void -isplinux_mbtimer(unsigned long arg) -{ - ispsoftc_t *isp = (ispsoftc_t *) arg; - unsigned long flags; - ISP_ILOCK_SOFTC(isp); - if (isp->mbox_waiting) { - isp->mbox_waiting = 0; - up(&isp->mbox_c_sem); - } - ISP_IUNLK_SOFTC(isp); -} - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) #define PTARG , struct pt_regs *pt #else @@ -4259,9 +4286,8 @@ isplinux_common_init(ispsoftc_t *isp) */ ISP_LOCK_INIT(isp); ISP_TLOCK_INIT(isp); - sema_init(&isp->mbox_sem, 1); - sema_init(&isp->mbox_c_sem, 0); - + sema_init(&isp->isp_osinfo.mbox_sem, 1); + init_waitqueue_head(&isp->isp_osinfo.mboxwq); init_waitqueue_head(&isp->isp_osinfo.trq); for (i = 0; i < MAX_THREAD_ACTION; i++) { init_waitqueue_head(&isp->isp_osinfo.t_actions[i].thread_waiter); @@ -4386,7 +4412,7 @@ isplinux_reinit(ispsoftc_t *isp) /* * We seem to need a bit of settle time. */ - USEC_SLEEP(isp, 1 * 1000000); + ISP_SLEEP(isp, 1 * 1000000); } else { int chan; @@ -4560,7 +4586,7 @@ isp_task_thread(void *arg) fcp = FCPARAM(isp, chan); ISP_LOCKU_SOFTC(isp); - ISP_DATA(isp, chan)->fcrswdog = 0; + ISP_DATA(isp, chan)->nextscan = 0; if (isp_fc_runstate(isp, chan, 250000) == 0) { ISP_DATA(isp, chan)->deadloop = 0; ISP_DATA(isp, chan)->downcount = 0; @@ -4580,9 +4606,10 @@ isp_task_thread(void *arg) ISP_DATA(isp, chan)->blocked = 0; isp_prt(isp, ISP_LOGWARN, "Chan %d assuming loop is dead", chan); isplinux_flushwaitq(isp); - } else { - ISP_DATA(isp, chan)->fcrswdog = 1; + ISP_UNLKU_SOFTC(isp); + break; } + ISP_DATA(isp, chan)->nextscan = jiffies + HZ; } ISP_UNLKU_SOFTC(isp); break; @@ -4603,11 +4630,10 @@ isp_task_thread(void *arg) ISP_UNLKU_SOFTC(isp); break; } - MEMZERO(&u, sizeof (u)); + memset(&u, 0, sizeof (u)); u.id = lp->handle; - isp_prt(isp, ISP_LOGTINFO, "Doing Port Logout repair for 0x%016llx@0x%x (loop id) %u", - (ull) lp->port_wwn, lp->portid, lp->handle); - MEMZERO(&mbs, sizeof (mbs)); + isp_prt(isp, ISP_LOGTINFO, "Doing Port Logout repair for 0x%016llx@0x%x (loop id) %u", (ull) lp->port_wwn, lp->portid, lp->handle); + memset(&mbs, 0, sizeof (mbs)); mbs.param[0] = MBOX_FABRIC_LOGOUT; if (ISP_CAP_2KLOGIN(isp)) { mbs.param[1] = lp->handle; @@ -4623,7 +4649,7 @@ isp_task_thread(void *arg) ISP_UNLKU_SOFTC(isp); break; } - MEMZERO(&mbs, sizeof (mbs)); + memset(&mbs, 0, sizeof (mbs)); mbs.param[0] = MBOX_FABRIC_LOGIN; if (ISP_CAP_2KLOGIN(isp)) { mbs.param[1] = lp->handle; @@ -4767,7 +4793,7 @@ isp_task_thread(void *arg) CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START); ISP_UNLKU_SOFTC(isp); isp_tgt_tq(isp); - isp_prt(isp, ISP_LOGINFO, "Chan %d [%llx] reprieved", (int) AT2_GET_BUS(tmd->cd_tagval), (ull) tmd->cd_tagval); + isp_prt(isp, ISP_LOGINFO, "Chan %d [%llx] reprieved", tmd->cd_channel, (ull) tmd->cd_tagval); break; } @@ -4791,9 +4817,9 @@ isp_task_thread(void *arg) { at7_entry_t at; tmd_cmd_t *tmd = tap->arg; - MEMCPY(&at, tmd, sizeof (at7_entry_t)); + memcpy(&at, tmd, sizeof (at7_entry_t)); ISP_LOCKU_SOFTC(isp); - MEMZERO(tmd, sizeof (tmd_cmd_t)); + memset(tmd, 0, sizeof (tmd_cmd_t)); if (isp->isp_osinfo.tfreelist) { isp->isp_osinfo.bfreelist->cd_next = tmd; } else { @@ -4819,7 +4845,7 @@ isp_task_thread(void *arg) isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (ull) tmd->cd_tagval); (void) isp_terminate_cmd(isp, tmd); } - MEMZERO(tmd, sizeof (tmd_cmd_t)); + memset(tmd, 0, sizeof (tmd_cmd_t)); if (isp->isp_osinfo.tfreelist) { isp->isp_osinfo.bfreelist->cd_next = tmd; } else { @@ -4860,14 +4886,16 @@ isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...) if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { return; } - if (level & ISP_LOGERR) { - prefl = KERN_ERR "%s: "; + if (level & (ISP_LOGTINFO|ISP_LOGINFO|ISP_LOGCONFIG|ISP_LOGSANCFG)) { + prefl = KERN_INFO "%s: "; } else if (level & ISP_LOGWARN) { prefl = KERN_WARNING "%s: "; - } else if (level & ISP_LOGINFO) { - prefl = KERN_INFO "%s: "; - } else if (level & ISP_LOGCONFIG) { - prefl = KERN_INFO "%s: "; + } else if (level & ISP_LOGERR) { + prefl = KERN_ERR "%s: "; + } else if (level & (ISP_LOGTDEBUG0|ISP_LOGTDEBUG1|ISP_LOGTDEBUG2)) { + prefl = KERN_DEBUG "%s: "; + } else if (level & (ISP_LOGDEBUG0|ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3)) { + prefl = KERN_DEBUG "%s: "; } else { prefl = "%s: "; } diff --git a/qla_isp/linux/isp_linux.h b/qla_isp/linux/isp_linux.h index 0dfc35d25..4dd1a10bc 100644 --- a/qla_isp/linux/isp_linux.h +++ b/qla_isp/linux/isp_linux.h @@ -1,4 +1,4 @@ -/* $Id: isp_linux.h,v 1.164 2008/08/20 15:50:56 mjacob Exp $ */ +/* $Id: isp_linux.h,v 1.168 2009/01/24 17:55:55 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -245,7 +245,7 @@ typedef uint8_t isp_bmap_t; #define N_NOTIFIES 256 #define DEFAULT_INQSIZE 32 -typedef struct isp_notify isp_notify_t; +typedef struct notify notify_t; #define cd_action cd_lreserved[0].shorts[0] #define cd_oxid cd_lreserved[0].shorts[1] @@ -327,8 +327,8 @@ struct isposinfo { u16 wqhiwater; u16 hiwater; struct timer_list timer; - struct timer_list mbtimer; struct semaphore mbox_sem; + wait_queue_head_t mboxwq; struct semaphore mbox_c_sem; spinlock_t slock; unsigned volatile int @@ -338,7 +338,6 @@ struct isposinfo { : 1, dogactive : 1, mboxcmd_done : 1, - mbox_waiting : 1, mbintsok : 1, intsok : 1; u16 frame_size; @@ -362,9 +361,9 @@ struct isposinfo { struct tmd_cmd * tfreelist; /* freelist head */ struct tmd_cmd * bfreelist; /* freelist tail */ struct tmd_cmd * pool; /* pool itself */ - isp_notify_t * pending_n; /* pending list of notifies going upstream */ - isp_notify_t * nfreelist; /* freelist */ - isp_notify_t * npool; /* pool itself */ + notify_t * pending_n; /* pending list of notifies going upstream */ + notify_t * nfreelist; /* freelist */ + notify_t * npool; /* pool itself */ struct tmd_xact * pending_x; /* pending list of xacts going upstream */ /* * When we have inquiry commands that we have to xfer data with @@ -382,8 +381,6 @@ struct isposinfo { }; #define mbtimer isp_osinfo.mbtimer #define dogactive isp_osinfo.dogactive -#define mbox_sem isp_osinfo.mbox_sem -#define mbox_c_sem isp_osinfo.mbox_c_sem #define mbintsok isp_osinfo.mbintsok #define intsok isp_osinfo.intsok #define mbox_waiting isp_osinfo.mbox_waiting @@ -410,9 +407,7 @@ struct isposinfo { #define ISP_DRIVER_CTL_ENTRY_LOCK(isp) do { } while (0) #define ISP_DRIVER_CTL_EXIT_LOCK(isp) do { } while (0) -#define ISP_ATOMIC in_atomic - -#define ISP_MUST_POLL(isp) (ISP_ATOMIC() || isp->mbintsok == 0) +#define ISP_MUST_POLL(isp) (in_interrupt() || isp->mbintsok == 0) /* * Required Macros/Defines @@ -424,11 +419,11 @@ struct isposinfo { #define ISP_FC_SCRLEN 0x1000 -#define MEMZERO(b, a) memset(b, 0, a) -#define MEMCPY memcpy -#define SNPRINTF snprintf -#define USEC_DELAY _isp_usec_delay -#define USEC_SLEEP(isp, x) \ +#define ISP_MEMZERO(b, a) memset(b, 0, a) +#define ISP_MEMCPY memcpy +#define ISP_SNPRINTF snprintf +#define ISP_DELAY _isp_usec_delay +#define ISP_SLEEP(isp, x) \ ISP_DROP_LK_SOFTC(isp); \ __set_current_state(TASK_UNINTERRUPTIBLE); \ (void) schedule_timeout(_usec_to_jiffies(x)); \ @@ -452,15 +447,12 @@ struct isposinfo { # endif #endif -#define MBOX_ACQUIRE(isp) down_trylock(&isp->mbox_sem) +#define MBOX_ACQUIRE(isp) down_trylock(&isp->isp_osinfo.mbox_sem) #define MBOX_WAIT_COMPLETE mbox_wait_complete -#define MBOX_NOTIFY_COMPLETE(isp) \ - if (isp->mbox_waiting) { \ - isp->mbox_waiting = 0; \ - up(&isp->mbox_c_sem); \ - } \ +#define MBOX_NOTIFY_COMPLETE(isp) \ + wake_up(&isp->isp_osinfo.mboxwq); \ isp->mboxcmd_done = 1 -#define MBOX_RELEASE(isp) up(&isp->mbox_sem) +#define MBOX_RELEASE(isp) up(&isp->isp_osinfo.mbox_sem) #define FC_SCRATCH_ACQUIRE fc_scratch_acquire #define FC_SCRATCH_RELEASE(isp, chan) ISP_DATA(isp, chan)->scratch_busy = 0 @@ -540,7 +532,7 @@ struct isposinfo { #define XS_INITERR(xs) (xs)->result = 0, (xs)->SCp.Status = 0 -#define XS_SAVE_SENSE(Cmnd, s, l) MEMCPY(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l)) +#define XS_SAVE_SENSE(Cmnd, s, l) memcpy(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l)) #define XS_SET_STATE_STAT(a, b, c) @@ -617,14 +609,12 @@ typedef struct { uint64_t def_wwpn; uint32_t tgts_tested : 16, - : 10, - fcrswdog : 1, - : 1, + : 11, scratch_busy : 1, blocked : 1, deadloop : 1, role : 2; - unsigned long downcount; + unsigned long downcount, nextscan; unsigned int qfdelay; } isp_data; @@ -818,7 +808,7 @@ static inline void mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) { uint32_t lim = mbp->timeout; - unsigned long long tt = jiffies; + unsigned long long et, tt = jiffies; if (lim == 0) { lim = MBCMD_DEFAULT_TIMEOUT; @@ -843,7 +833,13 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) break; } } + ISP_ENABLE_INTS(isp); + ISP_DROP_LK_SOFTC(isp); udelay(100); + ISP_IGET_LK_SOFTC(isp); + if (isp->mboxcmd_done) { + break; + } } if (isp->mboxcmd_done == 0) { isp_prt(isp, ISP_LOGWARN, "Polled Mailbox Command (0x%x) Timeout (%llu elapsed jiffies)", isp->isp_lastmbxcmd, ((unsigned long long) jiffies) - tt); @@ -851,26 +847,16 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) } } else { isp_prt(isp, ISP_LOGDEBUG1, "Start Interrupting Mailbox Command (%x)", isp->isp_lastmbxcmd); - init_timer(&isp->mbtimer); - isp->mbtimer.data = (unsigned long) isp; - isp->mbtimer.function = isplinux_mbtimer; - isp->mbtimer.expires = tt; - isp->mbtimer.expires += ((lim/1000000) * HZ); - isp->mbtimer.expires += ((lim%1000000) / HZ); - add_timer(&isp->mbtimer); - isp->mbox_waiting = 1; ISP_ENABLE_INTS(isp); ISP_DROP_LK_SOFTC(isp); - down(&isp->mbox_c_sem); + et = wait_event_timeout(isp->isp_osinfo.mboxwq, isp->mboxcmd_done, usecs_to_jiffies(lim)); ISP_IGET_LK_SOFTC(isp); - isp->mbox_waiting = 0; - del_timer(&isp->mbtimer); - if (isp->mboxcmd_done == 0) { + if (et == 0) { isp_prt(isp, ISP_LOGWARN, "Interrupting Mailbox Command (0x%x) Timeout (elapsed time %llu jiffies)", isp->isp_lastmbxcmd, ((unsigned long long) jiffies) - tt); mbp->param[0] = MBOX_TIMEOUT; } else { - isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%llu jiffies)", isp->isp_lastmbxcmd, ((unsigned long long) jiffies) - tt); + isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%llu jiffies)", isp->isp_lastmbxcmd, et); } } } @@ -919,7 +905,7 @@ isp_kzalloc(size_t size, int flags) { void *ptr = isp_kalloc(size, flags); if (ptr != NULL){ - MEMZERO(ptr, size); + memset(ptr, 0, size); } return (ptr); } @@ -945,8 +931,8 @@ int isp_target_notify(ispsoftc_t *, void *, uint32_t *); int isp_enable_lun(ispsoftc_t *, uint16_t, uint16_t); int isp_disable_lun(ispsoftc_t *, uint16_t, uint16_t); -struct isp_notify { - tmd_notify_t notify; +struct notify { + isp_notify_t notify; uint8_t qentry[QENTRY_LEN]; /* original immediate notify entry */ uint8_t qevalid; }; diff --git a/qla_isp/linux/isp_pci.c b/qla_isp/linux/isp_pci.c index 0342ff2ba..06d99f632 100644 --- a/qla_isp/linux/isp_pci.c +++ b/qla_isp/linux/isp_pci.c @@ -1,4 +1,4 @@ -/* $Id: isp_pci.c,v 1.172 2008/08/20 15:50:56 mjacob Exp $ */ +/* $Id: isp_pci.c,v 1.175 2009/01/24 17:55:55 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -549,6 +549,9 @@ isplinux_pci_init_one(struct Scsi_Host *host) isp->isp_dblev = isp_debug; } else { isp->isp_dblev = ISP_LOGCONFIG|ISP_LOGINFO|ISP_LOGWARN|ISP_LOGERR; +#ifdef ISP_TARGET_MODE + isp->isp_dblev |= ISP_LOGTINFO; +#endif } pci_read_config_word(pdev, PCI_COMMAND, &cmd); @@ -1484,7 +1487,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, "ATIO Queue not on 64 byte boundary"); goto bad; } - MEMZERO(isp->isp_atioq, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp))); + memset(isp->isp_atioq, 0, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp))); } #endif if (isp->isp_rquest == NULL) { @@ -1499,7 +1502,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, "Request Queue not on 64 byte boundary"); goto bad; } - MEMZERO(isp->isp_rquest, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); + memset(isp->isp_rquest, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp))); } if (isp->isp_result == NULL) { @@ -1514,7 +1517,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) isp_prt(isp, ISP_LOGERR, "Result Queue not on 64 byte boundary"); goto bad; } - MEMZERO(isp->isp_result, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp))); + memset(isp->isp_result, 0, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp))); } if (IS_FC(isp)) { @@ -1528,7 +1531,7 @@ isp_pci_mbxdma(ispsoftc_t *isp) goto bad; } fcp->isp_scdma = busaddr; - MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN); + memset(fcp->isp_scratch, 0, ISP_FC_SCRLEN); if (fcp->isp_scdma & 0x7) { isp_prt(isp, ISP_LOGERR, "scratch space not 8 byte aligned"); goto bad; @@ -1583,11 +1586,6 @@ bad: static int tdma_mk(ispsoftc_t *, tmd_xact_t *, ct_entry_t *, uint32_t *, uint32_t); static int tdma_mkfc(ispsoftc_t *, tmd_xact_t *, ct2_entry_t *, uint32_t *, uint32_t); -#define ALLOW_SYNTHETIC_CTIO 1 -#ifndef ALLOW_SYNTHETIC_CTIO -#define cto2 0 -#endif - #define STATUS_WITH_DATA 1 /* @@ -1642,7 +1640,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin cto->ct_xfrlen = 0; cto->ct_seg_count = 0; cto->ct_header.rqs_entry_count = 1; - MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg)); + memset(cto->ct_dataseg, 0, sizeof (cto->ct_dataseg)); if (xact->td_xfrlen == 0) { ISP_TDQE(isp, "tdma_mk[no data]", curi, cto); @@ -1859,7 +1857,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin cto->ct_xfrlen = 0; cto->ct_resid = 0; cto->ct_seg_count = 0; - MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg)); + memset(cto->ct_dataseg, 0, sizeof (cto->ct_dataseg)); } } *nxtip = nxti; @@ -1913,8 +1911,16 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti uint32_t bc, last_synthetic_count; long xfcnt; /* must be signed */ int nseg, seg, ovseg, seglim, new_seg_cnt; -#ifdef ALLOW_SYNTHETIC_CTIO ct7_entry_t *cto2 = NULL, ct2; +#if 0 +{ + static int fred = 0; + if (fred++ == 100) { + fred = 0; + printk("YAGGA!\n"); + return (CMD_EAGAIN); + } +} #endif nxti = *nxtip; @@ -1991,7 +1997,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (new_seg_cnt == 0) { isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); - cto->ct_resid = -ENOMEM; + cto->ct_resid = -EFAULT; return (CMD_COMPLETE); } tmd->cd_nseg = new_seg_cnt; @@ -2011,12 +2017,11 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti swd = cto->ct_scsi_status; if ((cto->ct_flags & CT7_SENDSTATUS) && ((swd & 0xff) || cto->ct_resid)) { -#ifdef ALLOW_SYNTHETIC_CTIO cto2 = &ct2; /* * Copy over CTIO2 */ - MEMCPY(cto2, cto, sizeof (ct7_entry_t)); + memcpy(cto2, cto, sizeof (ct7_entry_t)); /* * Clear fields from first CTIO7 that now need to be cleared @@ -2032,18 +2037,13 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti cto2->ct_flags &= ~(CT7_FLAG_MMASK|CT7_DATAMASK); cto2->ct_flags |= CT7_NO_DATA|CT7_NO_DATA|CT7_FLAG_MODE1; cto2->ct_seg_count = 0; - MEMZERO(&cto2->rsp, sizeof (cto2->rsp)); + memset(&cto2->rsp, 0, sizeof (cto2->rsp)); cto2->ct_scsi_status = swd; if ((swd & 0xff) == SCSI_CHECK && (xact->td_hflags & TDFH_SNSVALID)) { cto2->rsp.m1.ct_resplen = min(TMD_SENSELEN, MAXRESPLEN_24XX); - MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_resplen); + memcpy(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_resplen); cto2->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); } -#else - cto->ct_flags &= ~CT7_SENDSTATUS; - cto->ct_resid = 0; - cto->ct_scsi_status = 0; -#endif } /* @@ -2074,8 +2074,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti last_synthetic_addr = addr; } else { cto->rsp.m0.ds.ds_count = bc; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __func__, seg, - (unsigned long)cto->rsp.m0.ds.ds_basehi, (unsigned long)cto->rsp.m0.ds.ds_base, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __func__, 0, 0, (unsigned long long) addr, bc); } cto->rsp.m0.ct_xfrlen += bc; xfcnt -= bc; @@ -2092,10 +2091,10 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti do { int lim; uint32_t curip; - ispcontreq_t local, *crq = &local, *qep; + ispcontreq64_t local, *crq = &local, *qep; curip = nxti; - qep = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip); + qep = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip); nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp)); if (nxti == optr) { pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); @@ -2103,13 +2102,13 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti return (CMD_EAGAIN); } cto->ct_header.rqs_entry_count++; - MEMZERO((void *)crq, sizeof (*crq)); + BUG_ON(cto->ct_header.rqs_entry_count == 0); + memset((void *)crq, 0, sizeof (*crq)); crq->req_header.rqs_entry_count = 1; crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; lim = ISP_CDSEG64; for (ovseg = 0; (seg < nseg || last_synthetic_count) && ovseg < lim; seg++, ovseg++, sg++) { - ispcontreq64_t *xrq; if (last_synthetic_count) { addr = last_synthetic_addr; bc = last_synthetic_count; @@ -2125,19 +2124,18 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti cto->ct_seg_count++; cto->rsp.m0.ct_xfrlen += bc; - xrq = (ispcontreq64_t *) crq; - xrq->req_dataseg[ovseg].ds_count = bc; - xrq->req_dataseg[ovseg].ds_base = LOWD(addr); - xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr); + crq->req_dataseg[ovseg].ds_count = bc; + crq->req_dataseg[ovseg].ds_base = LOWD(addr); + crq->req_dataseg[ovseg].ds_basehi = HIWD(addr); /* * Make sure we don't cross a 4GB boundary. */ if (!SAME_4G(addr, bc)) { isp_prt(isp, ISP_LOGTDEBUG1, "seg%d[%d]%llx:%u (TRUNC'd)", cto->ct_header.rqs_entry_count-1, ovseg, (long long)addr, bc); - xrq->req_dataseg[ovseg].ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr); - addr += xrq->req_dataseg[ovseg].ds_count; - bc -= xrq->req_dataseg[ovseg].ds_count; - xfcnt -= xrq->req_dataseg[ovseg].ds_count; + crq->req_dataseg[ovseg].ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr); + addr += crq->req_dataseg[ovseg].ds_count; + bc -= crq->req_dataseg[ovseg].ds_count; + xfcnt -= crq->req_dataseg[ovseg].ds_count; /* * Do we have space to split it here? */ @@ -2147,26 +2145,21 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti cto->ct_seg_count++; } else { ovseg++; - xrq->req_dataseg[ovseg].ds_count = bc; - xrq->req_dataseg[ovseg].ds_base = LOWD(addr); - xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr); + crq->req_dataseg[ovseg].ds_count = bc; + crq->req_dataseg[ovseg].ds_base = LOWD(addr); + crq->req_dataseg[ovseg].ds_basehi = HIWD(addr); } } } ISP_TDQE(isp, "tdma_mk_2400 cont", curip, crq); MEMORYBARRIER(isp, SYNC_REQUEST, curip, QENTRY_LEN); - if (crq->req_header.rqs_entry_type == RQSTYPE_A64_CONT) { - isp_put_cont64_req(isp, (ispcontreq64_t *)crq, (ispcontreq64_t *)qep); - } else { - isp_put_cont_req(isp, crq, qep); - } + isp_put_cont64_req(isp, (ispcontreq64_t *)crq, (ispcontreq64_t *)qep); } while (seg < nseg || last_synthetic_count); isp_prt(isp, ISP_LOGTDEBUG2, "[%llx]: map %d segments at %p for handle 0x%x", tmd->cd_tagval, new_seg_cnt, xact->td_data, cto->ct_syshandle); mbxsync: -#ifdef ALLOW_SYNTHETIC_CTIO /* * If we have a final CTIO2, allocate and push *that* * onto the request queue. @@ -2178,14 +2171,12 @@ mbxsync: if (nxti == optr) { pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT7_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__); - cto->ct_resid = -EAGAIN; - return (CMD_COMPLETE); + return (CMD_EAGAIN); } MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN); isp_put_ctio7(isp, cto2, (ct7_entry_t *)qe); ISP_TDQE(isp, "tdma_mk_2400:final", curi, cto2); } -#endif qe = ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); isp_put_ctio7(isp, cto, qe); if (cto->ct_flags & CT2_FASTPOST) { @@ -2212,9 +2203,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, uint32_t bc, last_synthetic_count; long xfcnt; /* must be signed */ int nseg, seg, ovseg, seglim, new_seg_cnt; -#ifdef ALLOW_SYNTHETIC_CTIO ct2_entry_t *cto2 = NULL, ct2; -#endif nxti = *nxtip; curi = isp->isp_reqidx; @@ -2257,7 +2246,11 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, /* ct_syshandle contains the synchronization handle set by caller */ cto->ct_seg_count = 0; cto->ct_reloff = 0; - isp_put_ctio2(isp, cto, qe); + if (ISP_CAP_2KLOGIN(isp)) { + isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe); + } else { + isp_put_ctio2(isp, cto, qe); + } if (cto->ct_flags & CT2_FASTPOST) { isp_prt(isp, ISP_LOGTDEBUG1, "[%x] faspost (0x%x)", cto->ct_rxid, tmd->cd_cdb[0]); } @@ -2312,7 +2305,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (new_seg_cnt == 0) { isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); - cto->ct_resid = -ENOMEM; + cto->ct_resid = -EFAULT; return (CMD_COMPLETE); } tmd->cd_nseg = new_seg_cnt; @@ -2322,12 +2315,11 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, */ if ((cto->ct_flags & CT2_SENDSTATUS) && ((swd & 0xff) || cto->ct_resid)) { -#ifdef ALLOW_SYNTHETIC_CTIO cto2 = &ct2; /* * Copy over CTIO2 */ - MEMCPY(cto2, cto, sizeof (ct2_entry_t)); + memcpy(cto2, cto, sizeof (ct2_entry_t)); /* * Clear fields from first CTIO2 that now need to be cleared @@ -2344,10 +2336,10 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, cto2->ct_flags |= CT2_NO_DATA|CT2_FLAG_MODE1; cto2->ct_seg_count = 0; cto2->ct_reloff = 0; - MEMZERO(&cto2->rsp, sizeof (cto2->rsp)); + memset(&cto2->rsp, 0, sizeof (cto2->rsp)); if ((swd & 0xff) == SCSI_CHECK && (swd & CT2_SNSLEN_VALID)) { cto2->rsp.m1.ct_senselen = min(TMD_SENSELEN, MAXRESPLEN); - MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_senselen); + memcpy(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_senselen); swd |= CT2_SNSLEN_VALID; } if (cto2->ct_resid > 0) { @@ -2359,11 +2351,6 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, if (cto2->ct_flags & CT2_CCINCR) { tmd->cd_lflags &= ~CDFL_RESRC_FILL; } -#else - cto->ct_flags &= ~(CT2_SENDSTATUS|CT2_CCINCR|CT2_FASTPOST); - cto->ct_resid = 0; - cto->rsp.m0.ct_scsi_status = 0; -#endif } else if ((cto->ct_flags & (CT2_SENDSTATUS|CT2_CCINCR)) == (CT2_SENDSTATUS|CT2_CCINCR)) { tmd->cd_lflags &= ~CDFL_RESRC_FILL; } @@ -2487,7 +2474,7 @@ again: return (CMD_EAGAIN); } cto->ct_header.rqs_entry_count++; - MEMZERO((void *)crq, sizeof (*crq)); + memset((void *)crq, 0, sizeof (*crq)); crq->req_header.rqs_entry_count = 1; if (cto->ct_header.rqs_entry_type == RQSTYPE_CTIO3) { crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; @@ -2582,7 +2569,6 @@ again: mbxsync: -#ifdef ALLOW_SYNTHETIC_CTIO /* * If we have a final CTIO2, allocate and push *that* * onto the request queue. @@ -2594,16 +2580,18 @@ mbxsync: if (nxti == optr) { pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__); - cto->ct_resid = -EAGAIN; - return (CMD_COMPLETE); + return (CMD_EAGAIN); } MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN); isp_put_ctio2(isp, cto2, (ct2_entry_t *)qe); ISP_TDQE(isp, "tdma_mkfc:final", curi, cto2); } -#endif qe = ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); - isp_put_ctio2(isp, cto, qe); + if (ISP_CAP_2KLOGIN(isp)) { + isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe); + } else { + isp_put_ctio2(isp, cto, qe); + } if (cto->ct_flags & CT2_FASTPOST) { isp_prt(isp, ISP_LOGTDEBUG1, "[%x] fastpost (0x%x) with entry count %d", cto->ct_rxid, tmd->cd_cdb[0], cto->ct_header.rqs_entry_count); } @@ -2871,7 +2859,7 @@ again: return (CMD_EAGAIN); } rq->req_header.rqs_entry_count++; - MEMZERO((void *)crq, sizeof (*crq)); + memset((void *)crq, 0, sizeof (*crq)); crq->req_header.rqs_entry_count = 1; if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS || rq->req_header.rqs_entry_type == RQSTYPE_A64) { crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; @@ -3135,7 +3123,7 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 return (CMD_EAGAIN); } rq->req_header.rqs_entry_count++; - MEMZERO((void *)xrq, sizeof (*xrq)); + memset((void *)xrq, 0, sizeof (*xrq)); xrq->req_header.rqs_entry_count = 1; xrq->req_header.rqs_entry_type = RQSTYPE_A64_CONT; lim = ISP_CDSEG64; diff --git a/qla_isp/linux/isp_scst.c b/qla_isp/linux/isp_scst.c index 2fbac619b..23d3d5b65 100644 --- a/qla_isp/linux/isp_scst.c +++ b/qla_isp/linux/isp_scst.c @@ -243,7 +243,7 @@ bus_from_name(const char *name) } static __inline bus_t * -bus_from_notify(tmd_notify_t *np) +bus_from_notify(isp_notify_t *np) { bus_t *bp; for (bp = busses; bp < &busses[MAX_BUS]; bp++) { @@ -430,8 +430,8 @@ rx_loop: spin_unlock_irq(&bc->tmds_lock); tmd->cd_scsi_status = SCSI_BUSY; xact = &tmd->cd_xact; - xact->td_hflags |= TDFH_STSVALID; - xact->td_hflags &= ~TDFH_DATA_MASK; + xact->td_hflags = TDFH_STSVALID; + xact->td_lflags = 0; xact->td_xfrlen = 0; (*bp->h.r_action)(QIN_TMD_CONT, xact); goto rx_loop; @@ -578,8 +578,8 @@ bus_chan_add_initiators(bus_t *bp, int chan) tmd->cd_scsi_status = SCSI_BUSY; xact = &tmd->cd_xact; - xact->td_hflags |= TDFH_STSVALID; - xact->td_hflags &= ~TDFH_DATA_MASK; + xact->td_hflags = TDFH_STSVALID; + xact->td_lflags = 0; xact->td_xfrlen = 0; (*bp->h.r_action)(QIN_TMD_CONT, xact); @@ -714,7 +714,7 @@ abort_all_tasks(bus_chan_t *bc, uint64_t iid) } static void -scsi_target_notify(tmd_notify_t *np) +scsi_target_notify(isp_notify_t *np) { bus_t *bp; bus_chan_t *bc; @@ -725,14 +725,6 @@ scsi_target_notify(tmd_notify_t *np) uint8_t lunbuf[8]; unsigned long flags; - /* - * XXX If task management fail we can't give info to isp driver via tpublic - * XXX notifies interface. FC stuff is capable to handle errors in TM. - * XXX But TM is rare and TM errors are even more rare, so we can ignore errors - * XXX now. Maybe tpublic API change, than we could uncomment passing errors to - * XXX low level driver. - */ - spin_lock_irqsave(&scsi_target_lock, flags); bp = bus_from_notify(np); if (unlikely(bp == NULL || bp->bchan == NULL)) { @@ -742,13 +734,12 @@ scsi_target_notify(tmd_notify_t *np) } spin_unlock_irqrestore(&scsi_target_lock, flags); - SDprintk("scsi_target: MGT code %x from %s%d iid 0x%016llx tag %llx\n", - np->nt_ncode, bp->h.r_name, bp->h.r_inst, np->nt_iid, np->nt_tagval); + SDprintk("scsi_target: MGT code %x from %s%d iid 0x%016llx tag %llx\n", np->nt_ncode, bp->h.r_name, bp->h.r_inst, np->nt_wwn, np->nt_tagval); bc = &bp->bchan[np->nt_channel]; spin_lock_irqsave(&bc->tmds_lock, flags); - ini = ini_from_iid(bc, np->nt_iid); + ini = ini_from_iid(bc, np->nt_wwn); np->nt_ini = ini; __ini_get(np->nt_ini); spin_unlock_irqrestore(&bc->tmds_lock, flags); @@ -759,12 +750,12 @@ scsi_target_notify(tmd_notify_t *np) if (ini == NULL) { goto err_no_ini; } - if (abort_task(bc, np->nt_iid, np->nt_tagval)) { + if (abort_task(bc, np->nt_wwn, np->nt_tagval)) { SDprintk("TMD_NOTIFY abort task [%llx]\n", np->nt_tagval); goto notify_ack; } if (scst_rx_mgmt_fn_tag(ini->ini_scst_sess, SCST_ABORT_TASK, np->nt_tagval, 1, np) < 0) { - //np->nt_error = NT_FAILED; + np->nt_failed = 1; goto notify_ack; } /* wait for SCST now */ @@ -774,7 +765,7 @@ scsi_target_notify(tmd_notify_t *np) if (ini == NULL) { goto err_no_ini; } - abort_all_tasks(bc, np->nt_iid); + abort_all_tasks(bc, np->nt_wwn); fn = SCST_ABORT_TASK_SET; break; case NT_CLEAR_TASK_SET: @@ -782,7 +773,7 @@ scsi_target_notify(tmd_notify_t *np) if (ini == NULL) { goto err_no_ini; } - abort_all_tasks(bc, np->nt_iid); + abort_all_tasks(bc, np->nt_wwn); fn = SCST_CLEAR_TASK_SET; break; case NT_CLEAR_ACA: @@ -792,7 +783,7 @@ scsi_target_notify(tmd_notify_t *np) case NT_LUN_RESET: tmf = "LUN RESET"; if (np->nt_lun == LUN_ANY) { - //np->nt_error = NT_REJECT; + np->nt_failed = 1; goto notify_ack; } fn = SCST_LUN_RESET; @@ -813,14 +804,16 @@ scsi_target_notify(tmd_notify_t *np) goto notify_ack; case NT_LOGOUT: spin_lock_irqsave(&bc->tmds_lock, flags); - /* If someone disable target during this notify, reference to initiator + /* + * If someone disables the target during this notify, reference to initiator * is currently dropped, so we need to check if IID is still in initiators - * table to avoid double free */ - if (del_ini(bc, np->nt_iid)) { - SDprintk("droping reference to initiator 0x%016llx\n", np->nt_iid); + * table to avoid double free + */ + if (del_ini(bc, np->nt_wwn)) { + SDprintk("droping reference to initiator 0x%016llx\n", np->nt_wwn); __ini_put(bc, ini); } else { - Eprintk("cannot logout initiator 0x%016llx\n", np->nt_iid); + Eprintk("cannot logout initiator 0x%016llx\n", np->nt_wwn); } spin_unlock_irqrestore(&bc->tmds_lock, flags); goto notify_ack; @@ -841,15 +834,15 @@ scsi_target_notify(tmd_notify_t *np) } FLATLUN_TO_L0LUN(lunbuf, lun); if (scst_rx_mgmt_fn_lun(ini->ini_scst_sess, fn, lunbuf, sizeof(lunbuf), 1, np) < 0) { - //np->nt_error = NT_FAILED; + np->nt_failed = 1; goto notify_ack; } } return; err_no_ini: - Eprintk("cannot find initiator 0x%016llx for %s\n", np->nt_iid, tmf); - //np->nt_error = NT_REJECT; + Eprintk("cannot find initiator 0x%016llx for %s\n", np->nt_wwn, tmf); + np->nt_failed = 1; notify_ack: ini_put(bc, ini); (*bp->h.r_action) (QIN_NOTIFY_ACK, np); @@ -922,7 +915,7 @@ scsi_target_handler(qact_e action, void *arg) } case QOUT_NOTIFY: { - tmd_notify_t *np = arg; + isp_notify_t *np = arg; SDprintk("scsi_target: TMD_NOTIFY %p code=0x%x\n", np, np->nt_ncode); scsi_target_notify(np); break; @@ -1089,7 +1082,8 @@ isp_rdy_to_xfer(struct scst_cmd *scst_cmd) bus_chan_t *bc = &bp->bchan[tmd->cd_channel]; int len = scst_cmd_get_bufflen(scst_cmd); - xact->td_hflags |= TDFH_DATA_OUT; + xact->td_hflags = TDFH_DATA_OUT; + xact->td_lflags = 0; xact->td_data = scst_cmd_get_sg(scst_cmd); xact->td_xfrlen = len; if (bp->h.r_type == R_SPI) { @@ -1109,15 +1103,24 @@ isp_rdy_to_xfer(struct scst_cmd *scst_cmd) SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel); up_read(&bc->disable_sem); scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_SAME); - return (0); + return (SCST_TGT_RES_SUCCESS); } SDprintk2("%s: TMD[%llx] write nbytes %u\n", __FUNCTION__, tmd->cd_tagval, scst_cmd_get_bufflen(scst_cmd)); - (*bp->h.r_action)(QIN_TMD_CONT, xact); up_read(&bc->disable_sem); + (*bp->h.r_action)(QIN_TMD_CONT, xact); + /* + * Did we have an error starting this particular transaction? + */ + if (unlikely(xact->td_lflags & (TDFL_ERROR|TDFL_SYNCERROR)) == (TDFL_ERROR|TDFL_SYNCERROR)) { + if (xact->td_error == -ENOMEM) { + return (SCST_TGT_RES_QUEUE_FULL); + } else { + return (SCST_TGT_RES_FATAL_ERROR); + } + } } - - return (0); + return (SCST_TGT_RES_SUCCESS); } static int @@ -1131,7 +1134,7 @@ isp_xmit_response(struct scst_cmd *scst_cmd) if (unlikely(scst_cmd_aborted(scst_cmd))) { scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED); scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME); - return (0); + return (SCST_TGT_RES_SUCCESS); } if (scst_cmd_get_data_direction(scst_cmd) == SCST_DATA_READ) { @@ -1147,11 +1150,11 @@ isp_xmit_response(struct scst_cmd *scst_cmd) Eprintk("data size too big (totlen %u len %u)\n", tmd->cd_totlen, len); memcpy(tmd->cd_sense, ifailure, TMD_SENSELEN); - xact->td_hflags |= TDFH_STSVALID; + xact->td_hflags = TDFH_STSVALID; tmd->cd_scsi_status = SCSI_CHECK; goto out; } else { - xact->td_hflags |= TDFH_DATA_IN; + xact->td_hflags = TDFH_DATA_IN; xact->td_xfrlen = len; xact->td_data = scst_cmd_get_sg(scst_cmd); } @@ -1161,6 +1164,8 @@ isp_xmit_response(struct scst_cmd *scst_cmd) xact->td_hflags &= ~TDFH_DATA_MASK; } + xact->td_lflags = 0; + if (scst_cmd_get_is_send_status(scst_cmd)) { xact->td_hflags |= TDFH_STSVALID; tmd->cd_scsi_status = scst_cmd_get_status(scst_cmd); @@ -1208,14 +1213,24 @@ out: SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel); up_read(&bc->disable_sem); scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME); - return (0); + return (SCST_TGT_RES_SUCCESS); } SDprintk2("%s: TMD[%llx] %p hf %x lf %x xfrlen %d totlen %d moved %d\n", __FUNCTION__, tmd->cd_tagval, tmd, xact->td_hflags, xact->td_lflags, xact->td_xfrlen, tmd->cd_totlen, tmd->cd_moved); - (*bp->h.r_action)(QIN_TMD_CONT, xact); up_read(&bc->disable_sem); - return (0); + (*bp->h.r_action)(QIN_TMD_CONT, xact); + /* + * Did we have an error starting this particular transaction? + */ + if (unlikely(xact->td_lflags & (TDFL_ERROR|TDFL_SYNCERROR)) == (TDFL_ERROR|TDFL_SYNCERROR)) { + if (xact->td_error == -ENOMEM) { + return (SCST_TGT_RES_QUEUE_FULL); + } else { + return (SCST_TGT_RES_FATAL_ERROR); + } + } + return (SCST_TGT_RES_SUCCESS); } static void @@ -1234,7 +1249,7 @@ isp_on_free_cmd(struct scst_cmd *scst_cmd) static void isp_task_mgmt_fn_done(struct scst_mgmt_cmd *mgmt_cmd) { - tmd_notify_t *np = mgmt_cmd->tgt_priv; + isp_notify_t *np = mgmt_cmd->tgt_priv; bus_t *bp = bus_from_notify(np); ini_put(&bp->bchan[np->nt_channel], np->nt_ini);