diff --git a/qla_isp/common/isp.c b/qla_isp/common/isp.c index fbde209cd..55b7552a8 100644 --- a/qla_isp/common/isp.c +++ b/qla_isp/common/isp.c @@ -1,4 +1,4 @@ -/* $Id: isp.c,v 1.204 2008/04/15 22:40:52 mjacob Exp $ */ +/* $Id: isp.c,v 1.209 2008/09/12 16:01:52 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -116,7 +116,7 @@ static const char pskip[] = static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'"; static const char finmsg[] = - "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; + "%d.%d.%d: FIN dl%d resid %ld STS 0x%x SKEY %c XS_ERR=0x%x"; static const char sc4[] = "NVRAM"; static const char bun[] = "bad underrun for %d.%d (count %d, resid %d, status %s)"; @@ -500,7 +500,7 @@ isp_reset(ispsoftc_t *isp) /* * Hit the chip over the head with hammer, - * and give the ISP a chance to recover. + * and give it a chance to recover. */ if (IS_SCSI(isp)) { @@ -624,7 +624,6 @@ isp_reset(ispsoftc_t *isp) ISP_WRITE(isp, BIU_SEMA, 0); } - /* * Post-RISC Reset stuff. */ @@ -723,17 +722,24 @@ isp_reset(ispsoftc_t *isp) */ /* - * Do some sanity checking. + * Do some sanity checking by running a NOP command. + * If it succeeds, the ROM firmware is now running. */ MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_NO_OP; mbs.logval = MBLOGALL; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, "NOP ommand failed (%x)", + mbs.param[0]); ISP_RESET0(isp); return; } + /* + * Do some operational tests + */ + if (IS_SCSI(isp) || IS_24XX(isp)) { MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_MAILBOX_REG_TEST; @@ -788,13 +794,6 @@ isp_reset(ispsoftc_t *isp) if (dodnld && IS_24XX(isp)) { const uint32_t *ptr = isp->isp_mdvec->dv_ispfw; - /* - * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE - * NB: command to the 2400 while loading new firmware. This - * NB: causes the new f/w to start and immediately crash back - * NB: to the ROM. - */ - /* * Keep loading until we run out of f/w. */ @@ -909,23 +908,6 @@ isp_reset(ispsoftc_t *isp) la += nw; } - if (!IS_2322(isp)) { - /* - * Verify that it downloaded correctly. - */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_VERIFY_CHECKSUM; - mbs.param[1] = code_org; - mbs.logval = MBLOGNONE; - isp_mboxcmd(isp, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - isp_prt(isp, ISP_LOGERR, dcrc); - ISP_RESET0(isp); - return; - } - break; - } - if (++segno == 3) { break; } @@ -965,23 +947,29 @@ isp_reset(ispsoftc_t *isp) ISP_RESET0(isp); return; } - /* - * Verify that it downloaded correctly. - */ + } else { + isp->isp_loaded_fw = 0; + isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); + } + + /* + * If we loaded firmware, verify its checksum + */ + if (isp->isp_loaded_fw) { MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_VERIFY_CHECKSUM; - mbs.param[1] = code_org; - mbs.logval = MBLOGNONE; + if (IS_24XX(isp)) { + mbs.param[1] = code_org >> 16; + mbs.param[2] = code_org; + } else { + mbs.param[1] = code_org; + } isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGERR, dcrc); ISP_RESET0(isp); return; } - isp->isp_loaded_fw = 1; - } else { - isp->isp_loaded_fw = 0; - isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download"); } /* @@ -1025,22 +1013,38 @@ isp_reset(ispsoftc_t *isp) /* * Give it a chance to finish starting up. + * Give the 24XX more time. */ - USEC_DELAY(250000); - - if (IS_SCSI(isp)) { + if (IS_24XX(isp)) { + USEC_DELAY(500000); /* - * Set CLOCK RATE, but only if asked to. + * Check to see if the 24XX firmware really started. */ - if (isp->isp_clock) { - mbs.param[0] = MBOX_SET_CLOCK_RATE; - mbs.param[1] = isp->isp_clock; - mbs.logval = MBLOGNONE; - isp_mboxcmd(isp, &mbs); - /* we will try not to care if this fails */ + if (mbs.param[1] == 0xdead) { + isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start"); + ISP_RESET0(isp); + return; + } + } else { + USEC_DELAY(250000); + if (IS_SCSI(isp)) { + /* + * Set CLOCK RATE, but only if asked to. + */ + if (isp->isp_clock) { + mbs.param[0] = MBOX_SET_CLOCK_RATE; + mbs.param[1] = isp->isp_clock; + mbs.logval = MBLOGNONE; + isp_mboxcmd(isp, &mbs); + /* we will try not to care if this fails */ + } } } + /* + * 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; @@ -1050,12 +1054,6 @@ isp_reset(ispsoftc_t *isp) return; } - if (IS_24XX(isp) && mbs.param[1] == 0xdead) { - isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start"); - ISP_RESET0(isp); - return; - } - /* * The SBus firmware that we are using apparently does not return * major, minor, micro revisions in the mailbox registers, which @@ -2390,13 +2388,13 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid) switch (mbs.param[0]) { case MBOX_PORT_ID_USED: isp_prt(isp, ISP_LOGDEBUG0, - "isp_plogi_old: portid 0x%06x already logged in as %u", + "isp_port_login: portid 0x%06x already logged in as %u", portid, mbs.param[1]); return (MBOX_PORT_ID_USED | (mbs.param[1] << 16)); case MBOX_LOOP_ID_USED: isp_prt(isp, ISP_LOGDEBUG0, - "isp_plogi_old: handle %u in use for port id 0x%02xXXXX", + "isp_port_login: handle %u in use for port id 0x%02xXXXX", handle, mbs.param[1] & 0xff); return (MBOX_LOOP_ID_USED); @@ -2405,18 +2403,18 @@ isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid) case MBOX_COMMAND_ERROR: isp_prt(isp, ISP_LOGINFO, - "isp_plogi_old: error 0x%x in PLOGI to port 0x%06x", + "isp_port_login: error 0x%x in PLOGI to port 0x%06x", mbs.param[1], portid); return (MBOX_COMMAND_ERROR); case MBOX_ALL_IDS_USED: isp_prt(isp, ISP_LOGINFO, - "isp_plogi_old: all IDs used for fabric login"); + "isp_port_login: all IDs used for fabric login"); return (MBOX_ALL_IDS_USED); default: isp_prt(isp, ISP_LOGINFO, - "isp_plogi_old: error 0x%x on port login of 0x%06x@0x%0x", + "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x", mbs.param[0], portid, handle); return (mbs.param[0]); } @@ -4137,6 +4135,8 @@ isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, } else if (r != MBOX_LOOP_ID_USED) { i = lim; break; + } else if (r == MBOX_TIMEOUT) { + return (-1); } else { *ohp = handle; handle = isp_nxt_handle(isp, chan, *ohp); @@ -4326,7 +4326,7 @@ isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan) } else if (ct->ct_cmd_resp == LS_ACC) { isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d Register FC4 Type accepted", chan); - return(0); + return (0); } else { isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", @@ -4546,7 +4546,7 @@ isp_start(XS_T *xs) /* * See comment in isp_intr */ - /* XS_RESID(xs) = 0; */ + /* XS_SET_RESID(xs, 0); */ /* * Fibre Channel always requires some kind of tag. @@ -5010,7 +5010,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, ...) mbr = va_arg(ap, mbreg_t *); va_end(ap); isp_mboxcmd(isp, mbr); - return(0); + return (0); } case ISPCTL_PLOGX: { @@ -5489,7 +5489,7 @@ again: XS_SETERR(xs, HBA_TGTBSY); } if (IS_SCSI(isp)) { - XS_RESID(xs) = resid; + XS_SET_RESID(xs, resid); /* * A new synchronous rate was negotiated for * this target. Mark state such that we'll go @@ -5504,11 +5504,11 @@ again: } } else { if (req_status_flags & RQSF_XFER_COMPLETE) { - XS_RESID(xs) = 0; + XS_SET_RESID(xs, 0); } else if (scsi_status & RQCS_RESID) { - XS_RESID(xs) = resid; + XS_SET_RESID(xs, resid); } else { - XS_RESID(xs) = 0; + XS_SET_RESID(xs, 0); } } if (snsp && slen) { @@ -5516,7 +5516,7 @@ again: } isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", - (long) XS_XFRLEN(xs), resid, (long) XS_RESID(xs)); + (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs)); break; case RQSTYPE_REQUEST: case RQSTYPE_A64: @@ -5541,7 +5541,7 @@ again: QENTRY_LEN, qe); } } - XS_RESID(xs) = XS_XFRLEN(xs); + XS_SET_RESID(xs, XS_XFRLEN(xs)); break; default: isp_print_bytes(isp, "Unhandled Response Type", @@ -5576,7 +5576,7 @@ again: skey = '.'; } isp_prt(isp, ISP_LOGALL, finmsg, XS_CHANNEL(xs), - XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), XS_RESID(xs), + XS_TGT(xs), XS_LUN(xs), XS_XFRLEN(xs), (long) XS_GET_RESID(xs), *XS_STSP(xs), skey, XS_ERR(xs)); } @@ -6392,9 +6392,9 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; case RQCS_DATA_OVERRUN: - XS_RESID(xs) = sp->req_resid; - isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", - XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); + XS_SET_RESID(xs, sp->req_resid); + isp_prt(isp, ISP_LOGERR, "data overrun (%ld) for command on %d.%d.%d", + (long) XS_GET_RESID(xs), XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_DATAOVR); } @@ -6486,7 +6486,7 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp) return; } } - XS_RESID(xs) = sp->req_resid; + XS_SET_RESID(xs, sp->req_resid); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_NOERROR); } @@ -6706,7 +6706,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, return; case RQCS_DATA_OVERRUN: - XS_RESID(xs) = sp->req_resid; + XS_SET_RESID(xs, sp->req_resid); isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)); @@ -6750,7 +6750,7 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, } return; } - XS_RESID(xs) = sp->req_resid; + XS_SET_RESID(xs, sp->req_resid); isp_prt(isp, ISP_LOGDEBUG0, "%d.%d.%d data underrun (%d) for command 0x%x", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), @@ -6850,7 +6850,7 @@ isp_fastpost_complete(ispsoftc_t *isp, uint16_t fph) * we must believe that SCSI status is zero and * that all data transferred. */ - XS_RESID(xs) = 0; + XS_SET_RESID(xs, 0); *XS_STSP(xs) = SCSI_GOOD; if (XS_XFRLEN(xs)) { ISP_DMAFREE(isp, xs, fph); @@ -7141,7 +7141,7 @@ static const uint32_t mbpfc[] = { ISPOPMAP(0x07, 0x07), /* 0x04: MBOX_WRITE_RAM_WORD */ ISPOPMAP(0x03, 0x07), /* 0x05: MBOX_READ_RAM_WORD */ ISPOPMAP(0xff, 0xff), /* 0x06: MBOX_MAILBOX_REG_TEST */ - ISPOPMAP(0x03, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */ + ISPOPMAP(0x07, 0x07), /* 0x07: MBOX_VERIFY_CHECKSUM */ ISPOPMAP(0x01, 0x4f), /* 0x08: MBOX_ABOUT_FIRMWARE */ ISPOPMAP(0xdf, 0x01), /* 0x09: MBOX_LOAD_RISC_RAM_2100 */ ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */ @@ -7866,7 +7866,6 @@ isp_setdfltsdparm(ispsoftc_t *isp) return; } } - } MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_GET_ACT_NEG_STATE; @@ -8033,9 +8032,9 @@ isp_reinit(ispsoftc_t *isp) isp_destroy_handle(isp, handle); if (XS_XFRLEN(xs)) { ISP_DMAFREE(isp, xs, handle); - XS_RESID(xs) = XS_XFRLEN(xs); + XS_SET_RESID(xs, XS_XFRLEN(xs)); } else { - XS_RESID(xs) = 0; + XS_SET_RESID(xs, 0); } XS_SETERR(xs, HBA_BUSRESET); isp_done(xs); diff --git a/qla_isp/common/ispvar.h b/qla_isp/common/ispvar.h index 514f86240..1892754f3 100644 --- a/qla_isp/common/ispvar.h +++ b/qla_isp/common/ispvar.h @@ -1,4 +1,4 @@ -/* $Id: ispvar.h,v 1.97 2008/03/23 04:56:30 mjacob Exp $ */ +/* $Id: ispvar.h,v 1.99 2008/06/16 23:53:18 mjacob Exp $ */ /*- * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -104,7 +104,9 @@ struct ispmdvec { * Overall parameters */ #define MAX_TARGETS 16 +#ifndef MAX_FC_TARG #define MAX_FC_TARG 512 +#endif #define ISP_MAX_TARGETS(isp) (IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS) #define ISP_MAX_LUNS(isp) (isp)->isp_maxluns @@ -983,7 +985,8 @@ void isp_async(ispsoftc_t *, ispasync_t, ...); * XS_CDBLEN(xs) gets the CDB's length "" * XS_XFRLEN(xs) gets the associated data transfer length "" * XS_TIME(xs) gets the time (in milliseconds) for this command - * XS_RESID(xs) gets the current residual count + * XS_GET_RESID(xs) gets the current residual count + * XS_GET_RESID(xs, resid) sets the current residual count * XS_STSP(xs) gets a pointer to the SCSI status byte "" * XS_SNSP(xs) gets a pointer to the associate sense data * XS_SNSLEN(xs) gets the length of sense data storage diff --git a/qla_isp/linux/exioct.h b/qla_isp/linux/exioct.h deleted file mode 100644 index 44c494812..000000000 --- a/qla_isp/linux/exioct.h +++ /dev/null @@ -1,1113 +0,0 @@ -/****************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP2x00 device driver for Linux 2.4.x - * Copyright (C) 2005 QLogic Corporation - * (www.qlogic.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * 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. - * - ******************************************************************************/ - -/* - * File Name: exioct.h - * - * San/Device Management Ioctl Header - * File is created to adhere to Solaris requirement using 8-space tabs. - * - * !!!!! PLEASE DO NOT REMOVE THE TABS !!!!! - * !!!!! PLEASE NO SINGLE LINE COMMENTS: // !!!!! - * !!!!! PLEASE NO MORE THAN 80 CHARS PER LINE !!!!! - * - * Revision History: - * - * Rev. 0 March 1, 2000 - * YPL - Created. - * - * Rev. 1 March 2, 2000 - * RLU - Updated with latest definitions. Added more comments. - * - * Rev. 2 May 16, 2000 - * SP - Updated definitions and changed structures (March 27, 2000) - * SP - Addded structures - * - * Rev. 3 June 1, 2000 - * THL - Made major changes to include all changes talked in our meeting. - * - * Rev. 4 June 5, 2000 - * RLU - Added new definitions/structures for SDM_GET_AEN and SDM_REG_AEN - * functions. - * - Major definition/structure name changes as discussed in meetings. - * - Deleted duplicated command code and structure definitions. - * - * Rev. 4.1 June 14, 2000 - * WTR - Moved Solaris specific defines to exioctso.h. This makes it - * possible for application developers to include only exioct.h - * in their Solaris application development. - * - * Rev. 4.2 June 15, 2000 - * THL - Changed UINT16 and UINT32 back to WORD and DWORD for NT; otherwise, - * NT will get a compilation error for redefining UINT16 and UINT32. - * Added RISC_CODE/FLASH_RAM macros. - * - * Rev. 4.3 June 22, 2000 - * THL - Changed SDM_FC_ADDR according to External Ioctls document. - * Added SDM_DEF_TYPE macros. - * - * Rev. 4.4 June 22, 2000 - * THL - Moved NT specific defines to exioctnt.h. - * - * Rev. 4.5 August 15, 2000 - * SP - Rolled back some changes made by Todd R. - * Kept new status code SDM_STATUS_NO_MEMORY - * Port types fabric and tape device - * - * Rev. 4.7 Sep 6, 2000 - * YPL - Replace SDM_ with EXT_, _ISP with _CHIP. - * Add vendor specific statuses, device update, config defines. - * - * Rev. 5.0 Sep 13, 2000 - * YPL - Update version to 5, remove max defines, make port type bit. - * Change HBA_PORT_PROPERTY to have bus/target/lun defined as UINT16 - * - * Rev. 5.1 Sep 22, 2000 - * THL - Add destination address for specify scsi address or FC address. - * Remove "not support" comment and add more macros. - * - * Rev. 5.2 Sep 27, 2000 - * THL - Add new macros and structure for add and swap target device. - * Create new data structure for get port database. - * TLE - Merge changes needed for FailOver - * - * Rev. 5.3 Sep 29, 2000 - * THL - Add access mode for NVRAM. - * - * Rev. 5.4 Oct 03, 2000 - * THL - Add EXT_SC_GET_FC_STATISTICS. - * - * Rev. 5.5 Oct 18, 2000 - * THL - Remove duplicated EXT_DEF_ADDR_MODE_32 and EXT_DEF_ADDR_MODE_16. - * Reformat new data structures and defines. - * - * Rev. 5.6 Oct 19, 2000 - * RLU - Changed file name from ExIoct.h to exioct.h. - * - Added definition of EXT_RNID_DATA for API implementation. - * - Reformat some lines to conform to the format agreed - * upon in IOCTL meeting (and mentioned at beginning of - * this file). - * - * Rev. 5.7 Oct 25, 2000 - * BN - Added LUN bitmask structure and macros - * - * Rev. 5.8 Oct 25, 2000 - * BN - Added EXT_CC_DRIVER_PROP define - * - * Rev. 5.9 Oct 26, 2000 - * BN - Sync with UnixApi project - * - * Rev. 5.10 Oct 30, 2000 - * BN - Remove not needed #define for EXT_CC_DRIVER_PROP - * - Add EXT_ to IS_LUN_BIT_SET, SET_LUN_BIT, CLR_LUN_BIT - * - * Rev. 5.11 Nov 1, 2000 - * BN - Increased [1] of EXT_DEVICEDATA to [EXT_MAX_TARGET] - * TLE - Decreased [EXT_MAX_TARGET] of EXT_DEVICEDATA to [1] - * - * Rev. 5.12 Nov 7, 2000 - * RLU - Deleted EXT_DEF_MAX_LUNS define and changed all references - * to it to use EXT_MAX_LUN. - * - Changed the revision numbers for the last 2 revisions down - * to use 5.x. - * - * Rev. 5.13 Nov 14, 2000 - * WTR - Fixed pointer referencing problem in the LUN_BIT_MASK macros. - * Updated comment at bit mask definition. - * - * Rev. 5.14 Dec 6, 2000 - * THL - Added Local and LoopID to discovered port/target property. - * - * Rev. 5.15 Dec 24, 2000 - * YPL - Enhance port connection modes and driver attrib - * - * Rev. 5.16 Dec 27, 2000 - * TLE - Add BufferHandle member to _EXT_ASYNC_EVENT data structure for - * SCTP support - * - * Rev. 5.17 Jan 10, 2001 - * YPL - Add edtov, ratov & fabric name in port property - * - * Rev. 5.18 Feb 28, 2001 - * YPL - Remove SCTP fields and add fabric parameter flags in port property - * - * Rev. 5.19 Mar 08, 2001 - * YPL - Remove SCTP fields from hba port prop - * - * Rev. 5.20 June 11, 2001 - * YPL - Change to reserved fields and add fabric name field in port property - * - * Rev. 5.21 June 29, 2001 - * YPL - Merge in changes decided long time ago (use _DEF_ for defines) & - * reserved some EXT_CC for legacy ioctls, plus add RNID dataformat - * values definition - * - * Rev. 5.21 Sep 18, 2001 - * SP - Added New return status codes - * - * Rev. 5.22 Oct 23, 2001 - * SP - Change reserve fields to add fields to EXT_HBA_PORT - * Added port speeds and FC4Types fields and related definitions - * - * Rev. 5.23 Dec 04, 2001 - * RL - Added port speed value definition. - * - * Rev. 5.24 Jan 20, 2002 - * JJ - Added PCI device function bits field in EXT_CHIP structure. - * - * Rev. 5.25 Feb 04, 2002 - * JJ - Added 16 bytes CDB support. Also added SenseLength field - * in SCSI_PASSTHRU structure. - * - * Rev. 5.26 Feb 12, 2002 - * AV - Changed type size used in SCSI_PASSTHRU structure definitions - * to re-enable gcc's automatic structure padding for backward - * compatibility. - * - * Rev. 5.27 Mar 01, 2002 - * RL - Added new SC value for SCSI3 command passthru. - * - * Rev. 5.28 Dec 09, 2002 - * Sync up with NT version of exioct.h: - * TLE - Modify EXT_RNID_REQ data structure for IBM SendRNID workaround - * YPL - Add firmware state (online diagnostics) - * YPL - Add ELS PS - * YPL - Add els event, # of els buffers & size - * - * Rev. 5.29 April 21, 2003 - * RA - Defined the structure EXT_BEACON_CONTROL and subcommand code: - * EXT_SC_GET_BEACON_STATE,EXT_SC_SET_BEACON_STATE for the - * led blinking feature. - * - * Rev. 5.30 July 21, 2003 - * RL - Added new statistics fields in HBA_PORT_STAT struct. - * - * Rev. 5.31 September 19, 2003 - * RL - Added new command subcode EXT_SC_GET_FC4_STATISTICS. - * - * Rev. 5.32 September 29, 2003 - * RL - Define new command subcodes for both EXT_CC_REG_AEN & EXT_CC_GET_AEN: - * EXT_SC_REG_AEN_DEFAULT, EXT_SC_REG_AEN_HBA_PORT, EXT_SC_REG_AEN_TGTS, - * EXT_SC_GET_AEN_DEFAULT, EXT_SC_GET_AEN_HBA_PORT, EXT_SC_GET_AEN_TGTS. - * - Modified EXT_REG_AEN structure to return the buffer length allocated - * for the given type of event queue registered. - * - * Rev. 5.33 August 20, 2004 - * RL - Changed references to UINT64 to UINT64_O so that UINT64 can be - * changed to true 64bit uint64_t. - * - Added new EXT_IOCTL structure definition and renamed old structure. - * - * Rev. 5.34 September 29, 2004 - * RL - Packing the EXT_IOCTL structure. - * - * Rev. 5.35 February 18, 2005 - * RL - Added DomainNr field in the EXT_CHIP structure to return PCI - * domain number used in Linux 2.6 kernel. - * - Added new PORTSPEED definitions. - * - * Rev. 5.36 October 11, 2005 - * RL - Added EXT_SC_GET_LUN_BY_Q subcode. - */ - -#ifndef _EXIOCT_H -#define _EXIOCT_H - -/* - * NOTE: the following version defines must be updated each time the - * changes made may affect the backward compatibility of the - * input/output relations of the SDM IOCTL functions. - */ -#define EXT_VERSION 7 -#define EXT_VERSION_O 5 - - -/* - * OS independent General definitions - */ -#define EXT_DEF_SIGNATURE_SIZE 8 -#define EXT_DEF_WWN_NAME_SIZE 8 -#define EXT_DEF_WWP_NAME_SIZE 8 -#define EXT_DEF_SERIAL_NUM_SIZE 4 -#define EXT_DEF_PORTID_SIZE 4 -#define EXT_DEF_PORTID_SIZE_ACTUAL 3 -#define EXT_DEF_MAX_STR_SIZE 128 -#define EXT_DEF_SCSI_PASSTHRU_CDB_LENGTH 16 - -#define EXT_DEF_ADDR_MODE_32 1 -#define EXT_DEF_ADDR_MODE_64 2 - -/* - * *********************************************************************** - * X OS type definitions - * *********************************************************************** - */ -#ifdef _MSC_VER /* NT */ - -#pragma pack(1) -#include "ExIoctNT.h" - -#elif defined(linux) /* Linux */ - -#include "exioctln.h" - -#elif defined(sun) || defined(__sun) /* Solaris */ - -#include "exioctso.h" - -#endif - -/* - * *********************************************************************** - * OS dependent General configuration defines - * *********************************************************************** - */ -#define EXT_DEF_MAX_HBA EXT_DEF_MAX_HBA_OS -#define EXT_DEF_MAX_BUS EXT_DEF_MAX_BUS_OS -#define EXT_DEF_MAX_TARGET EXT_DEF_MAX_TARGET_OS -#define EXT_DEF_MAX_LUN EXT_DEF_MAX_LUN_OS - -/* - * *********************************************************************** - * Common header struct definitions for San/Device Mgmt - * *********************************************************************** - */ -typedef struct { - UINT64_O Signature; /* 8 or 4 */ - UINT16 AddrMode; /* 2 */ - UINT16 Version; /* 2 */ - UINT16 SubCode; /* 2 */ - UINT16 Instance; /* 2 */ - UINT32 Status; /* 4 */ - UINT32 DetailStatus; /* 4 */ - UINT32 Reserved1; /* 4 */ - UINT32 RequestLen; /* 4 */ - UINT32 ResponseLen; /* 4 */ - UINT64_O RequestAdr; /* 8 or 4 */ - UINT64_O ResponseAdr; /* 8 or 4 */ - UINT16 HbaSelect; /* 2 */ - UINT16 VendorSpecificStatus[11]; /* 22 */ - UINT64_O VendorSpecificData; /* 8 or 4 */ -} EXT_IOCTL_O, *PEXT_IOCTL_O; /* 84 or 68 / 0x54 or 0x44 */ - -typedef struct { - UINT64 Signature; /* 8 chars string */ - UINT16 AddrMode; /* 2 */ - UINT16 Version; /* 2 */ - UINT16 SubCode; /* 2 */ - UINT16 Instance; /* 2 */ - UINT32 Status; /* 4 */ - UINT32 DetailStatus; /* 4 */ - UINT32 Reserved1; /* 4 */ - UINT32 RequestLen; /* 4 */ - UINT32 ResponseLen; /* 4 */ - UINT64 RequestAdr; /* 8 */ - UINT64 ResponseAdr; /* 8 */ - UINT16 HbaSelect; /* 2 */ - UINT16 VendorSpecificStatus[11]; /* 22 */ - UINT64 VendorSpecificData; /* 8 chars string */ - UINT16 Reserved2[16]; /* 32 */ -} __attribute__((packed)) EXT_IOCTL, *PEXT_IOCTL; /* 116 / 0x74 */ - - -/* - * Addressing mode used by the user application - */ -#define EXT_ADDR_MODE EXT_ADDR_MODE_OS - -/* - * Status. These macros are being used for setting Status field in - * EXT_IOCTL structure. - */ -#define EXT_STATUS_OK 0 -#define EXT_STATUS_ERR 1 -#define EXT_STATUS_BUSY 2 -#define EXT_STATUS_PENDING 3 -#define EXT_STATUS_SUSPENDED 4 -#define EXT_STATUS_RETRY_PENDING 5 -#define EXT_STATUS_INVALID_PARAM 6 -#define EXT_STATUS_DATA_OVERRUN 7 -#define EXT_STATUS_DATA_UNDERRUN 8 -#define EXT_STATUS_DEV_NOT_FOUND 9 -#define EXT_STATUS_COPY_ERR 10 -#define EXT_STATUS_MAILBOX 11 -#define EXT_STATUS_UNSUPPORTED_SUBCODE 12 -#define EXT_STATUS_UNSUPPORTED_VERSION 13 -#define EXT_STATUS_MS_NO_RESPONSE 14 -#define EXT_STATUS_SCSI_STATUS 15 -#define EXT_STATUS_BUFFER_TOO_SMALL 16 -#define EXT_STATUS_NO_MEMORY 17 -#define EXT_STATUS_UNKNOWN 18 -#define EXT_STATUS_UNKNOWN_DSTATUS 19 -#define EXT_STATUS_INVALID_REQUEST 20 - -#define EXT_STATUS_DEVICE_NOT_READY 21 -#define EXT_STATUS_DEVICE_OFFLINE 22 -#define EXT_STATUS_HBA_NOT_READY 23 -#define EXT_STATUS_HBA_QUEUE_FULL 24 - -/* - * Detail Status contains the SCSI bus status codes. - */ - -#define EXT_DSTATUS_GOOD 0x00 -#define EXT_DSTATUS_CHECK_CONDITION 0x02 -#define EXT_DSTATUS_CONDITION_MET 0x04 -#define EXT_DSTATUS_BUSY 0x08 -#define EXT_DSTATUS_INTERMEDIATE 0x10 -#define EXT_DSTATUS_INTERMEDIATE_COND_MET 0x14 -#define EXT_DSTATUS_RESERVATION_CONFLICT 0x18 -#define EXT_DSTATUS_COMMAND_TERMINATED 0x22 -#define EXT_DSTATUS_QUEUE_FULL 0x28 - -/* - * Detail Status contains the needed Response buffer space(bytes) - * when Status = EXT_STATUS_BUFFER_TOO_SMALL - */ - - -/* - * Detail Status contains one of the following codes - * when Status = EXT_STATUS_INVALID_PARAM or - * = EXT_STATUS_DEV_NOT_FOUND - */ -#define EXT_DSTATUS_NOADNL_INFO 0x00 -#define EXT_DSTATUS_HBA_INST 0x01 -#define EXT_DSTATUS_TARGET 0x02 -#define EXT_DSTATUS_LUN 0x03 -#define EXT_DSTATUS_REQUEST_LEN 0x04 -#define EXT_DSTATUS_PATH_INDEX 0x05 - -/* - * Currently supported DeviceControl / ioctl command codes - */ -#define EXT_CC_QUERY EXT_CC_QUERY_OS -#define EXT_CC_SEND_FCCT_PASSTHRU EXT_CC_SEND_FCCT_PASSTHRU_OS -#define EXT_CC_REG_AEN EXT_CC_REG_AEN_OS -#define EXT_CC_GET_AEN EXT_CC_GET_AEN_OS -#define EXT_CC_SEND_ELS_RNID EXT_CC_SEND_ELS_RNID_OS -#define EXT_CC_SEND_SCSI_PASSTHRU EXT_CC_SCSI_PASSTHRU_OS -#define EXT_CC_SEND_ELS_PASSTHRU EXT_CC_SEND_ELS_PASSTHRU_OS - -/* - * HBA port operations - */ -#define EXT_CC_GET_DATA EXT_CC_GET_DATA_OS -#define EXT_CC_SET_DATA EXT_CC_SET_DATA_OS - - -/* Reserved command codes. */ -#define EXT_CC_RESERVED0A EXT_CC_RESERVED0A_OS -#define EXT_CC_RESERVED0B EXT_CC_RESERVED0B_OS -#define EXT_CC_RESERVED0C EXT_CC_RESERVED0C_OS -#define EXT_CC_RESERVED0D EXT_CC_RESERVED0D_OS -#define EXT_CC_RESERVED0E EXT_CC_RESERVED0E_OS -#define EXT_CC_RESERVED0F EXT_CC_RESERVED0F_OS -#define EXT_CC_RESERVED0G EXT_CC_RESERVED0G_OS -#define EXT_CC_RESERVED0H EXT_CC_RESERVED0H_OS -#define EXT_CC_RESERVED0I EXT_CC_RESERVED0I_OS -#define EXT_CC_RESERVED0J EXT_CC_RESERVED0J_OS -#define EXT_CC_RESERVED0Z EXT_CC_RESERVED0Z_OS - - -/* - * *********************************************************************** - * EXT_IOCTL SubCode definition. - * These macros are being used for setting SubCode field in EXT_IOCTL - * structure. - * *********************************************************************** - */ - -/* - * Query. - * Uses with EXT_QUERY as the ioctl code. - */ -#define EXT_SC_QUERY_HBA_NODE 1 -#define EXT_SC_QUERY_HBA_PORT 2 -#define EXT_SC_QUERY_DISC_PORT 3 -#define EXT_SC_QUERY_DISC_TGT 4 -#define EXT_SC_QUERY_DISC_LUN 5 /* Currently Not Supported */ -#define EXT_SC_QUERY_DRIVER 6 -#define EXT_SC_QUERY_FW 7 -#define EXT_SC_QUERY_CHIP 8 - -/* - * Sub codes for Reg AEN. - * Use in combination with EXT_CC_REG_AEN - */ -#define EXT_SC_REG_AEN_DEFAULT 0 /* default events to record.*/ -#define EXT_SC_REG_AEN_HBA_PORT 1 /* enable hba port events */ -#define EXT_SC_REG_AEN_TGTS 2 /* enable target events */ - -/* - * Sub codes for Get AEN. - * Use in combination with EXT_CC_GET_AEN - */ -#define EXT_SC_GET_AEN_DEFAULT 0 /* default events to record.*/ -#define EXT_SC_GET_AEN_HBA_PORT 1 /* get hba port events */ -#define EXT_SC_GET_AEN_TGTS 2 /* get target events */ - -/* - * Sub codes for Get Data. - * Use in combination with EXT_GET_DATA as the ioctl code - */ -/* 1 - 99 Common */ -#define EXT_SC_GET_SCSI_ADDR 1 /* Currently Not Supported */ -#define EXT_SC_GET_ERR_DETECTIONS 2 /* Currently Not Supported */ -#define EXT_SC_GET_STATISTICS 3 -#define EXT_SC_GET_BUS_MODE 4 /* Currently Not Supported */ -#define EXT_SC_GET_DR_DUMP_BUF 5 /* Currently Not Supported */ -#define EXT_SC_GET_RISC_CODE 6 /* Currently Not Supported */ -#define EXT_SC_GET_FLASH_RAM 7 /* for backward compatible */ -#define EXT_SC_GET_BEACON_STATE 8 -#define EXT_SC_GET_FC4_STATISTICS 9 -#define EXT_SC_GET_LUN_BY_Q 10 - -/* 100 - 199 FC_INTF_TYPE */ -#define EXT_SC_GET_LINK_STATUS 101 /* Currently Not Supported */ -#define EXT_SC_GET_LOOP_ID 102 /* Currently Not Supported */ -#define EXT_SC_GET_LUN_BITMASK 103 -#define EXT_SC_GET_PORT_DATABASE 104 /* Currently Not Supported */ -#define EXT_SC_GET_PORT_DATABASE_MEM 105 /* Currently Not Supported */ -#define EXT_SC_GET_PORT_SUMMARY 106 -#define EXT_SC_GET_POSITION_MAP 107 -#define EXT_SC_GET_RETRY_CNT 108 /* Currently Not Supported */ -#define EXT_SC_GET_RNID 109 -#define EXT_SC_GET_RTIN 110 /* Currently Not Supported */ -#define EXT_SC_GET_FC_LUN_BITMASK 111 -#define EXT_SC_GET_FC_STATISTICS 112 /* for backward compatible */ - -/* 200 - 299 SCSI_INTF_TYPE */ -#define EXT_SC_GET_SEL_TIMEOUT 201 /* Currently Not Supported */ - - -/* - * Sub codes for Set Data. - * Use in combination with EXT_SET_DATA as the ioctl code - */ -/* 1 - 99 Common */ -#define EXT_SC_RST_STATISTICS 3 -#define EXT_SC_RESERVED_BC7 7 -#define EXT_SC_SET_BEACON_STATE 8 - -/* 100 - 199 FC_INTF_TYPE */ -#define EXT_SC_SET_LUN_BITMASK 103 -#define EXT_SC_SET_RNID 109 -#define EXT_SC_SET_FC_LUN_BITMASK 111 -#define EXT_SC_RESERVED_BC112 112 -#define EXT_SC_RESERVED_BC113 113 - -/* 200 - 299 SCSI_INTF_TYPE */ - -/* SCSI passthrough */ -#define EXT_SC_SEND_SCSI_PASSTHRU 0 -#define EXT_SC_SEND_FC_SCSI_PASSTHRU 1 -#define EXT_SC_SCSI3_PASSTHRU 2 - -/* Read */ - -/* Write */ - -/* Reset */ - -/* Request struct */ - -#define EXT_HN_BI_FW_VALID 1 -#define EXT_HN_BI_EFI_VALID 2 -#define EXT_HN_BI_FCODE_VALID 4 - -/* - * Response struct - */ -typedef struct _EXT_HBA_NODE { - UINT8 WWNN [EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Manufacturer [EXT_DEF_MAX_STR_SIZE]; /* 128; "QLOGIC" */ - UINT8 Model [EXT_DEF_MAX_STR_SIZE]; /* 128; "QLA2200" */ - UINT8 SerialNum [EXT_DEF_SERIAL_NUM_SIZE];/* 4; 123 */ - UINT8 DriverVersion[EXT_DEF_MAX_STR_SIZE]; /* 128; "7.4.3" */ - UINT8 FWVersion [EXT_DEF_MAX_STR_SIZE]; /* 128; "2.1.6" */ - - /* The following field is currently not supported */ - UINT8 OptRomVersion[EXT_DEF_MAX_STR_SIZE]; /* 128; "1.44" */ - - UINT16 PortCount; /* 2; 1 */ - UINT16 InterfaceType; /* 2; FC/SCSI */ - - /* The following two fields are not yet supported */ - UINT32 DriverAttr; /* 4 */ - UINT32 FWAttr; /* 4 */ - - UINT32 BIValid; /* 4 */ - UINT8 BIFwVersion[4]; /* 4 */ - UINT8 BIEfiVersion[4]; /* 4 */ - UINT8 BIFCodeVersion[4]; /* 4 */ - UINT32 Reserved[4]; /* 16 */ -} EXT_HBA_NODE, *PEXT_HBA_NODE; /* 696 */ - -/* HBA node query interface type */ -#define EXT_DEF_FC_INTF_TYPE 1 -#define EXT_DEF_SCSI_INTF_TYPE 2 - -typedef struct _EXT_HBA_PORT { - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id [EXT_DEF_PORTID_SIZE]; /* 4; 3 bytes valid Port Id. */ - UINT16 Type; /* 2; Port Type */ - UINT16 State; /* 2; Port State */ - UINT16 Mode; /* 2 */ - UINT16 DiscPortCount; /* 2 */ - UINT16 DiscPortNameType; /* 2; USE_NODE_NAME or */ - /* USE_PORT_NAME */ - UINT16 DiscTargetCount; /* 2 */ - UINT16 Bus; /* 2 */ - UINT16 Target; /* 2 */ - UINT16 Lun; /* 2 */ - /* 2 */ - UINT8 PortSupportedFC4Types; - UINT8 PortActiveFC4Types; - UINT8 FabricName[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - - /* 2*/ - UINT8 PortSupportedSpeed; - UINT8 PortSpeed; - UINT16 Unused; /* 2 */ - UINT32 Reserved[3]; /* 12 */ -} EXT_HBA_PORT, *PEXT_HBA_PORT; /* 56 */ - -/* port type */ -#define EXT_DEF_INITIATOR_DEV 1 -#define EXT_DEF_TARGET_DEV 2 -#define EXT_DEF_TAPE_DEV 4 -#define EXT_DEF_FABRIC_DEV 8 - - -/* HBA port state */ -#define EXT_DEF_HBA_OK 0 -#define EXT_DEF_HBA_SUSPENDED 1 -#define EXT_DEF_HBA_LOOP_DOWN 2 - -/* Connection mode */ -#define EXT_DEF_UNKNOWN_MODE 0 -#define EXT_DEF_P2P_MODE 1 -#define EXT_DEF_LOOP_MODE 2 -#define EXT_DEF_FL_MODE 3 -#define EXT_DEF_N_MODE 4 - -/* Valid name type for Disc. port/target */ -#define EXT_DEF_USE_NODE_NAME 1 -#define EXT_DEF_USE_PORT_NAME 2 - -/* FC4 type values */ -#define EXT_DEF_FC4_TYPE_SCSI 0x1 -#define EXT_DEF_FC4_TYPE_IP 0x2 -#define EXT_DEF_FC4_TYPE_SCTP 0x4 -#define EXT_DEF_FC4_TYPE_VI 0x8 - -/* Port Speed values */ -#define EXT_DEF_PORTSPEED_1GBIT 1 -#define EXT_DEF_PORTSPEED_2GBIT 2 -#define EXT_DEF_PORTSPEED_4GBIT 4 -#define EXT_DEF_PORTSPEED_8GBIT 8 -#define EXT_DEF_PORTSPEED_10GBIT 0x10 - -typedef struct _EXT_DISC_PORT { - UINT8 WWNN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id [EXT_DEF_PORTID_SIZE]; - /* 4; last 3 bytes used. big endian */ - - /* The following fields currently are not supported */ - UINT16 Type; /* 2; Port Type */ - UINT16 Status; /* 2; Port Status */ - UINT16 Bus; /* 2; n/a for Solaris */ - - UINT16 TargetId; /* 2 */ - UINT8 Local; /* 1; Local or Remote */ - UINT8 ReservedByte[1]; /* 1 */ - - UINT16 LoopID; /* 2; Loop ID */ - - UINT32 Reserved[7]; /* 28 */ -} EXT_DISC_PORT, *PEXT_DISC_PORT; /* 60 */ - -typedef struct _EXT_DISC_TARGET { - UINT8 WWNN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id [EXT_DEF_PORTID_SIZE]; - /* 4; last 3 bytes used. big endian */ - - /* The following fields currently are not supported */ - UINT16 Type; /* 2; Target Type */ - UINT16 Status; /* 2; Target Status*/ - UINT16 Bus; /* 2; n/a for Solaris */ - - UINT16 TargetId; /* 2 */ - - /* The following field is currently not supported */ - UINT16 LunCount; /* 2; n/a for nt */ - - UINT8 Local; /* 1; Local or Remote */ - UINT8 ReservedByte[1]; /* 1 */ - - UINT16 LoopID; /* 2; Loop ID */ - - UINT16 Reserved[13]; /* 26 */ -} EXT_DISC_TARGET, *PEXT_DISC_TARGET; /* 60 */ - -/* The following command is not supported */ -typedef struct _EXT_DISC_LUN { /* n/a for nt */ - UINT16 Id; /* 2 */ - UINT16 State; /* 2 */ - UINT16 IoCount; /* 2 */ - UINT16 Reserved[15]; /* 30 */ -} EXT_DISC_LUN, *PEXT_DISC_LUN; /* 36 */ - - -/* SCSI address */ -typedef struct _EXT_SCSI_ADDR { - UINT16 Bus; /* 2 */ - UINT16 Target; /* 2 */ - UINT16 Lun; /* 2 */ - UINT16 Padding[5]; /* 10 */ -} EXT_SCSI_ADDR, *PEXT_SCSI_ADDR; /* 16 */ - - -/* Fibre Channel address */ -typedef struct _EXT_FC_ADDR { - union { - UINT8 WWNN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id[EXT_DEF_PORTID_SIZE]; /* 4 */ - } FcAddr; - UINT16 Type; /* 2 */ - UINT16 Padding[2]; /* 2 */ -} EXT_FC_ADDR, *PEXT_FC_ADDR; /* 24 */ - -#define EXT_DEF_TYPE_WWNN 1 -#define EXT_DEF_TYPE_WWPN 2 -#define EXT_DEF_TYPE_PORTID 3 -#define EXT_DEF_TYPE_FABRIC 4 - - -/* Destination address */ -typedef struct _EXT_DEST_ADDR { - union { - UINT8 WWNN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id[EXT_DEF_PORTID_SIZE]; /* 4 */ - struct { - UINT16 Bus; /* 2 */ - UINT16 Target; /* 2 */ - } ScsiAddr; - } DestAddr; - UINT16 DestType; /* 2 */ - UINT16 Lun; /* 2 */ - UINT16 Padding[2]; /* 4 */ -} EXT_DEST_ADDR, *PEXT_DEST_ADDR; /* 16 */ - - -#define EXT_DEF_DESTTYPE_WWNN 1 -#define EXT_DEF_DESTTYPE_WWPN 2 -#define EXT_DEF_DESTTYPE_PORTID 3 -#define EXT_DEF_DESTTYPE_FABRIC 4 -#define EXT_DEF_DESTTYPE_SCSI 5 - - -/* Statistic */ -typedef struct _EXT_HBA_PORT_STAT { - UINT32 ControllerErrorCount; /* 4 */ - UINT32 DeviceErrorCount; /* 4 */ - UINT32 TotalIoCount; /* 4 */ - UINT32 TotalMBytes; /* 4; MB of data processed */ - UINT32 TotalLipResets; /* 4; Total no. of LIP Reset */ - UINT32 Reserved2; /* 4 */ - UINT32 TotalLinkFailures; /* 4 */ - UINT32 TotalLossOfSync; /* 4 */ - UINT32 TotalLossOfSignals; /* 4 */ - UINT32 PrimitiveSeqProtocolErrorCount;/* 4 */ - UINT32 InvalidTransmissionWordCount; /* 4 */ - UINT32 InvalidCRCCount; /* 4 */ - uint64_t InputRequestCount; /* 8 */ - uint64_t OutputRequestCount; /* 8 */ - uint64_t ControlRequestCount; /* 8 */ - uint64_t InputMBytes; /* 8 */ - uint64_t OutputMBytes; /* 8 */ - UINT32 Reserved[6]; /* 24 */ -} EXT_HBA_PORT_STAT, *PEXT_HBA_PORT_STAT; /* 112 */ - - -/* Driver property */ -typedef struct _EXT_DRIVER { - UINT8 Version[EXT_DEF_MAX_STR_SIZE];/* 128 */ - UINT16 NumOfBus; /* 2; Port Type */ - UINT16 TargetsPerBus; /* 2; Port Status */ - UINT16 LunsPerTarget; /* 2 */ - UINT32 MaxTransferLen; /* 4 */ - UINT32 MaxDataSegments; /* 4 */ - UINT16 DmaBitAddresses; /* 2 */ - UINT16 IoMapType; /* 2 */ - UINT32 Attrib; /* 4 */ - UINT32 InternalFlags[4]; /* 16 */ - UINT32 Reserved[8]; /* 32 */ -} EXT_DRIVER, *PEXT_DRIVER; /* 198 */ - - -/* Firmware property */ -typedef struct _EXT_FW { - UINT8 Version[EXT_DEF_MAX_STR_SIZE];/* 128 */ - UINT32 Attrib; /* 4 */ - UINT16 Reserved[33]; /* 66 */ -} EXT_FW, *PEXT_FW; /* 198 */ - - -/* ISP/Chip property */ -typedef struct _EXT_CHIP { - UINT16 VendorId; /* 2 */ - UINT16 DeviceId; /* 2 */ - UINT16 SubVendorId; /* 2 */ - UINT16 SubSystemId; /* 2 */ - UINT16 PciBusNumber; /* 2 */ - UINT16 PciSlotNumber; /* 2 */ - UINT32 IoAddr; /* 4 */ - UINT32 IoAddrLen; /* 4 */ - UINT32 MemAddr; /* 4 */ - UINT32 MemAddrLen; /* 4 */ - UINT16 ChipType; /* 2 */ - UINT16 InterruptLevel; /* 2 */ - UINT16 OutMbx[8]; /* 16 */ - UINT16 PciDevFunc; /* 2 */ - UINT16 DomainNr; /* 2 */ - UINT16 Reserved[14]; /* 28 */ -} EXT_CHIP, *PEXT_CHIP; /* 80 */ - - -/* Request Buffer for RNID */ -typedef struct _EXT_RNID_REQ { - EXT_FC_ADDR Addr; /* 14 */ - UINT8 DataFormat; /* 1 */ - UINT8 Pad; /* 1 */ - UINT8 OptWWN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 OptPortId[EXT_DEF_PORTID_SIZE]; /* 4 */ - UINT32 Reserved[12]; /* 48 */ - UINT8 Pad1[3]; /* 3 */ -} EXT_RNID_REQ, *PEXT_RNID_REQ; /* 79 */ - -#define EXT_DEF_RNID_DFORMAT_NONE 0 -#define EXT_DEF_RNID_DFORMAT_TOPO_DISC 0xDF - -/* Request Buffer for Set RNID */ -typedef struct _EXT_SET_RNID_REQ { - UINT8 IPVersion[2]; - UINT8 UDPPortNumber[2]; - UINT8 IPAddress[16]; - UINT32 Reserved[16]; -} EXT_SET_RNID_REQ, *PEXT_SET_RNID_REQ; - -/* RNID definition and data struct */ -#define SEND_RNID_RSP_SIZE 72 - -typedef struct _RNID_DATA -{ - UINT8 WWN[16]; /* 16 */ - UINT32 UnitType; /* 4 */ - UINT8 PortId[4]; /* 4 */ - UINT32 NumOfAttachedNodes; /* 4 */ - UINT8 IPVersion[2]; /* 2 */ - UINT8 UDPPortNumber[2]; /* 2 */ - UINT8 IPAddress[16]; /* 16 */ - UINT16 Reserved; /* 2 */ - UINT16 TopoDiscFlags; /* 2 */ -} EXT_RNID_DATA, *PEXT_RNID_DATA; /* 52 */ - - -/* SCSI pass-through */ -typedef struct _EXT_SCSI_PASSTHRU { - EXT_SCSI_ADDR TargetAddr; - UINT8 Direction; - UINT8 CdbLength; - UINT8 Cdb[EXT_DEF_SCSI_PASSTHRU_CDB_LENGTH]; - UINT32 Timeout; - UINT32 Reserved[13]; - UINT16 Reserved2; - UINT16 SenseLength; - UINT8 SenseData[256]; -} EXT_SCSI_PASSTHRU, *PEXT_SCSI_PASSTHRU; - -/* FC SCSI pass-through */ -typedef struct _EXT_FC_SCSI_PASSTHRU { - EXT_DEST_ADDR FCScsiAddr; - UINT8 Direction; - UINT8 CdbLength; - UINT8 Cdb[EXT_DEF_SCSI_PASSTHRU_CDB_LENGTH]; - UINT32 Timeout; - UINT32 Reserved[13]; - UINT16 Reserved2; - UINT16 SenseLength; - UINT8 SenseData[256]; -} EXT_FC_SCSI_PASSTHRU, *PEXT_FC_SCSI_PASSTHRU; - -/* SCSI pass-through direction */ -#define EXT_DEF_SCSI_PASSTHRU_DATA_IN 1 -#define EXT_DEF_SCSI_PASSTHRU_DATA_OUT 2 - - -/* EXT_REG_AEN_xxx Request struct */ -typedef struct _EXT_REG_AEN { - UINT32 Enable; /* 4; non-0 to enable, 0 to disable. */ - UINT16 BufLength; /* 2; to RECEIVE buf len expected by driver. */ - UINT16 Reserved; /* 2 */ -} EXT_REG_AEN, *PEXT_REG_AEN; /* 8 */ - -/* EXT_SC_GET_AEN_DEFAULT and EXT_SC_GET_AEN_HBA_PORT Response struct */ -typedef struct _EXT_ASYNC_EVENT { - UINT32 AsyncEventCode; /* 4 */ - union { - struct { - UINT8 RSCNInfo[EXT_DEF_PORTID_SIZE_ACTUAL];/* 3, BE */ - UINT8 AddrFormat; /* 1 */ - UINT32 Rsvd_1[2]; /* 8 */ - } RSCN; - - UINT32 Reserved[3]; /* 12 */ - } Payload; -} EXT_ASYNC_EVENT, *PEXT_ASYNC_EVENT; /* 16 */ - -/* Asynchronous Event Codes */ -#define EXT_DEF_LIP_OCCURRED 0x8010 -#define EXT_DEF_LINK_UP 0x8011 -#define EXT_DEF_LINK_DOWN 0x8012 -#define EXT_DEF_LIP_RESET 0x8013 -#define EXT_DEF_RSCN 0x8015 -#define EXT_DEF_DEVICE_UPDATE 0x8014 -#define EXT_DEF_ELS 0x8200 -/* Driver Defined Event Codes; only valid as hba port event. */ -#define EXT_DEF_EV_TGT_ADD 0xA000 /* New target added */ - -/* EXT_SC_REG_AEN_TGTS Request struct */ -typedef struct _EXT_REG_TGTEV { - UINT32 Enable; /* 4; non-0 to enable, 0 to disable. */ - UINT32 BufLength; /* 4; to RECEIVE buf len expected by driver. */ - UINT32 AllTargets; /* 4 */ - UINT8 TgtPortName[EXT_DEF_WWP_NAME_SIZE];/* 8, BE */ - UINT32 Reserved; /* 4 */ -} EXT_REG_TGTEV, *PEXT_REG_TGTEV; /* 24 */ - -/* EXT_SC_GET_AEN_TGTS Response struct */ -typedef struct _EXT_AEN_TARGETS { - UINT8 TgtEventCode; /* 1 */ - struct { - UINT8 TgtPortName[EXT_DEF_WWP_NAME_SIZE];/* 8, BE */ - UINT8 Rsvd_1[11]; /* 11 */ - } TgtInfo; - -} EXT_AEN_TARGETS, *PEXT_AEN_TARGETS; /* 20 */ - -/* Target Event Codes */ -#define EXT_DEF_EV_TGT_OFFLINE 1 -#define EXT_DEF_EV_TGT_ONLINE 2 -#define EXT_DEF_EV_TGT_REMOVED 3 - -/* Required # of entries in the queue buffer allocated. */ -#define EXT_DEF_MAX_AEN_QUEUE EXT_DEF_MAX_AEN_QUEUE_OS -#define EXT_DEF_MAX_TGTEV_QUEUE EXT_DEF_MAX_TGTEV_QUEUE_OS -#define EXT_DEF_MAX_ELS_BUFS EXT_DEF_MAX_ELS_BUFS_OS -#define EXT_DEF_SIZE_ELS_BUF EXT_DEF_SIZE_ELS_BUF_OS - -/* Device type to get for EXT_SC_GET_PORT_SUMMARY */ -#define EXT_DEF_GET_KNOWN_DEVICE 0x1 -#define EXT_DEF_GET_VISIBLE_DEVICE 0x2 -#define EXT_DEF_GET_HIDDEN_DEVICE 0x4 -#define EXT_DEF_GET_FABRIC_DEVICE 0x8 -#define EXT_DEF_GET_LOOP_DEVICE 0x10 -#define EXT_DEF_GET_TRUE_NN_DEVICE 0x1000 - -/* Each entry in device database */ -typedef struct _EXT_DEVICEDATAENTRY -{ - UINT8 NodeWWN[8]; /* Node World Wide Name for device */ - UINT8 PortWWN[8]; /* Port World Wide Name for device */ - UINT8 PortID[3]; /* Current PortId for device */ - UINT8 ControlFlags; /* Control flag */ - EXT_SCSI_ADDR TargetAddress; /* scsi address */ - UINT32 DeviceFlags; /* Flags for device */ - UINT16 LoopID; /* Loop ID */ - UINT16 BaseLunNumber; - UINT32 Reserved[32]; -} EXT_DEVICEDATAENTRY, *PEXT_DEVICEDATAENTRY; - -/* Device database information */ -typedef struct _EXT_DEVICEDATA -{ - UINT32 TotalDevices; /* Set to total number of device. */ - UINT32 ReturnListEntryCount; /* Set to number of device entries */ - /* returned in list. */ - - EXT_DEVICEDATAENTRY EntryList[1]; /* Variable length */ -} EXT_DEVICEDATA, *PEXT_DEVICEDATA; - - -/* Swap Target Device Data structure */ -typedef struct _EXT_SWAPTARGETDEVICE -{ - EXT_DEVICEDATAENTRY CurrentExistDevice; - EXT_DEVICEDATAENTRY NewDevice; -} EXT_SWAPTARGETDEVICE, *PEXT_SWAPTARGETDEVICE; - -/* LUN BitMask structure definition, array of 8bit bytes, - * 1 bit per lun. When bit == 1, the lun is masked. - * Most significant bit of mask[0] is lun 0. - * Least significant bit of mask[0] is lun 7. - */ -typedef struct _EXT_LUN_BIT_MASK { -#if ((EXT_DEF_MAX_LUN & 0x7) == 0) - UINT8 mask[EXT_DEF_MAX_LUN >> 3]; -#else - UINT8 mask[(EXT_DEF_MAX_LUN + 8) >> 3 ]; -#endif -} EXT_LUN_BIT_MASK, *PEXT_LUN_BIT_MASK; - -/* - * LUN mask bit manipulation macros - * - * P = Pointer to an EXT_LUN_BIT_MASK union. - * L = LUN number. - */ -#define EXT_IS_LUN_BIT_SET(P,L) \ - (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0) - -#define EXT_SET_LUN_BIT(P,L) \ - ((P)->mask[L/8] |= (0x80 >> (L%8))) - -#define EXT_CLR_LUN_BIT(P,L) \ - ((P)->mask[L/8] &= ~(0x80 >> (L%8))) - -#define EXT_DEF_LUN_BITMASK_LIST_MIN_ENTRIES 1 -#define EXT_DEF_LUN_BITMASK_LIST_MAX_ENTRIES 256 - -#ifdef _WIN64 -#define EXT_DEF_LUN_BITMASK_LIST_HEADER_SIZE 32 -#else -#define EXT_DEF_LUN_BITMASK_LIST_HEADER_SIZE \ - offsetof(LUN_BITMASK_LIST_BUFFER, asBitmaskEntry) -#endif - -#define EXT_DEF_LUN_COUNT 2048 -#define EXT_DEF_LUN_BITMASK_BYTES (EXT_DEF_LUN_COUNT / 8) - -typedef struct _EXT_LUN_BITMASK_ENTRY -{ - UINT8 NodeName[EXT_DEF_WWN_NAME_SIZE]; - UINT8 PortName[EXT_DEF_WWN_NAME_SIZE]; - - UINT32 Reserved2; - UINT32 Reserved3; - UINT32 Reserved4; - UINT32 Reserved5; /* Pad to 32-byte header.*/ - - UINT8 Bitmask[EXT_DEF_LUN_BITMASK_BYTES]; -} EXT_LUN_BITMASK_ENTRY, *PEXT_LUN_BITMASK_ENTRY; - -/* Structure as it is stored in the config file.*/ -typedef struct _LUN_BITMASK_LIST -{ - UINT16 Version; /* Should be LUN_BITMASK_REGISTRY_VERSION */ - UINT16 EntryCount; /* Count of variable entries following.*/ - UINT32 Reserved1; - UINT32 Reserved2; - UINT32 Reserved3; - UINT32 Reserved4; - UINT32 Reserved5; - UINT32 Reserved6; - UINT32 Reserved7; /* Pad to 32-byte header.*/ - - EXT_LUN_BITMASK_ENTRY BitmaskEntry[1]; /* Variable-length data.*/ - -} EXT_LUN_BITMASK_LIST, *PEXT_LUN_BITMASK_LIST; - - -#define EXT_DEF_LUN_BITMASK_LIST_MIN_SIZE \ - (EXT_DEF_LUN_BITMASK_LIST_HEADER_SIZE + \ - (sizeof(EXT_DEF_LUN_BITMASK_ENTRY) * EXT_DEF_LUN_BITMASK_LIST_MIN_ENTRIES)) -#define EXT_DEF_LUN_BITMASK_LIST_MAX_SIZE \ - (EXT_DEF_LUN_BITMASK_LIST_HEADER_SIZE + \ - (sizeof(EXT_DEF_LUN_BITMASK_ENTRY) * EXT_DEF_LUN_BITMASK_LIST_MAX_ENTRIES)) - -/* Request Buffer for ELS PT*/ -#define EXT_DEF_WWPN_VALID 1 -#define EXT_DEF_WWNN_VALID 2 -#define EXT_DEF_PID_VALID 4 -typedef struct _EXT_ELS_PT_REQ { - UINT8 WWNN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 WWPN[EXT_DEF_WWN_NAME_SIZE]; /* 8 */ - UINT8 Id[EXT_DEF_PORTID_SIZE]; /* 4 */ - UINT16 ValidMask; /* 2 */ - UINT16 Lid; /* 2 */ - UINT16 Rxid; /* 2 */ - UINT16 AccRjt; /* 2 */ - UINT32 Reserved; /* 4 */ -} EXT_ELS_PT_REQ, *PEXT_ELS_PT_REQ; /* 32 */ - -/* LED state information */ - -#define EXT_DEF_GRN_BLINK_ON 0x01ED0017 -#define EXT_DEF_GRN_BLINK_OFF 0x01ED00FF - -typedef struct _EXT_BEACON_CONTROL { - UINT32 State; /* 4 */ - UINT32 Reserved[3]; /* 12 */ -} EXT_BEACON_CONTROL , *PEXT_BEACON_CONTROL ; /* 16 */ - -#ifndef EXTERNAL_LUN_COUNT -#define EXTERNAL_LUN_COUNT 2048 -#endif - -typedef struct _TGT_LUN_DATA_ENTRY { - UINT8 NodeName[EXT_DEF_WWN_NAME_SIZE]; - UINT8 PortName[EXT_DEF_WWP_NAME_SIZE]; - - UINT16 LunCount; /* Valid entries in Data array. */ - UINT8 BusNumber; - UINT8 TargetId; - UINT8 DevType; /* Discovered target type */ - UINT8 LoopId; - UINT16 Reserved3; - UINT8 PortId[4]; - UINT32 Reserved5; /* Pad to 32-byte header.*/ - - UINT8 Data[EXTERNAL_LUN_COUNT]; -} TGT_LUN_DATA_ENTRY, *PTGT_LUN_DATA_ENTRY; - -typedef struct _TGT_LUN_DATA_LIST { - UINT16 Version; /* Should be LUN_DATA_REGISTRY_VERSION.*/ - UINT16 EntryCount; /* Number of DataEntry entries.*/ - UINT32 Reserved1; - UINT32 Reserved2; - UINT32 Reserved3; - UINT32 Reserved4; - UINT32 Reserved5; - UINT32 Reserved6; - UINT32 Reserved7; /* Pad to 32-byte header.*/ - - TGT_LUN_DATA_ENTRY DataEntry[1]; /* Variable-length data.*/ - -} TGT_LUN_DATA_LIST, *PTGT_LUN_DATA_LIST; - -#ifdef _MSC_VER -#pragma pack() -#endif - -#endif /* _EXIOCT_H */ diff --git a/qla_isp/linux/exioctln.h b/qla_isp/linux/exioctln.h deleted file mode 100644 index f0b3dc3ec..000000000 --- a/qla_isp/linux/exioctln.h +++ /dev/null @@ -1,373 +0,0 @@ -/***************************************************************************** -* QLOGIC LINUX SOFTWARE -* -* QLogic ISP2x00 device driver ioctl definition file -* Copyright (C) 2005 QLogic Corporation -* (www.qlogic.com) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2, or (at your option) any -* later version. -* -* 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. -****************************************************************************/ - -/* - * File Name: exioctln.h - - Rev 24 October 06, 2005 RL - - Added reserve internal ioctl command code for future use. - - Rev 23 June 22, 2005 RL - - Corrected assignment condition of EXT_ADDR_MODE_OS value. - - Rev 22 February 25, 2005 RL - - Added reserve internal ioctl command codes. - - Rev 21 February 1, 2005 RL - - Deleted AdapterModel field and bit definition for - EXT_LN_DRIVER_DATA. - - Rev 20 December 20, 2004 RL - - Decreased MAX_HBA_OS value again. - - Rev 19 September 9, 2004 RL - - Added AdapterModel field and bit definition for - EXT_LN_DRIVER_DATA. - - Rev 18 August 6, 2004 RL - - Added 'Flags' field and bit defines for EXT_LN_DRIVER_DATA. - - Corrected UINT64 define to real 64 bit. - - Corrected ioctl command value definition so it is - the same value in both 32bit and 64bit environments. - - Added NFO command values. - - Changed EXT_CC_STARTIOCTL to EXT_CC_GET_HBA_CNT. - - Rev 17 August 08, 2003 RL - - Decreased MAX_HBA_OS value to both decrease wasted space - in shared mem so it can be used to store other data, and - to decrease unnecesary loops checking through all adapters. - - Rev 16 July 31, 2003 RL - - Added definitions for Status field in discovered target - structure. - - Updated ioctl command value assignment on PPC64 so this - file can be shared with API lib. - - Rev 15 June 03, 2003 RL - - Modified ioctl command code value assignment so it also - works on PPC64. - - Rev 14 February 25, 2003 RL - - Added EXT_CC_DRIVER_SPECIFIC ioctl command to return - some driver specific data that can be used by API library - to determine how to maintain backward compatibility - of certain features. - - Rev 13 January 31, 2003 RL - - Changed the value of EXT_DEF_USE_HBASELECT to avoid - conflicting with older implementation of FO API lib. - - Rev 12 January 20, 2003 RL - - Added EXT_DEF_USE_HBASELECT definition for use by - the SETINSTANCE command. - - Rev 11 December 10, 2002 RL - - Added EXT_CC_SEND_ELS_PASSTHRU_OS definition. - - Rev 10 October 26, 2001 RL - - Corrected MAX_HBA, MAX_TARGET and MAX_LUN values to 255. - - Rev 9 July 26, 2001 RL - - Added definition of signed types. - - Rev 8 July 05, 2001 RL - - Redefined ioctl command values. - - Rev 7 Nov 06, 2000 BN - - Added EXT_DEF_MAX_AEN_QUEUE_OS define - - Added define for handle_hba_t - - Rev 6 Oct 25, 2000 BN - - Added EXT_CC_DRIVER_PROP_OS define - - Rev 5 Oct 25, 2000 BN - - Redo the copyright header and add AEN details - - Rev 4 Oct 23, 2000 BN - - Added definition for BOOLEAN - - Rev 3 Oct 23, 2000 BN - - Added definitions for EXT_ADDR_MODE_OS - and also include of - - Rev 2 Oct 18, 2000 BN - - Enable API Exention support - - Rev 1 Original version Sep 7, 2000 BN - -*/ - - -#ifndef _EXIOCT_LN_H_ -#define _EXIOCT_LN_H_ - -#include - -#ifdef APILIB -#include -#include -#include -#endif - - -#ifndef INT8 -#define INT8 int8_t -#endif - -#ifndef INT16 -#define INT16 int16_t -#endif - -#ifndef INT32 -#define INT32 int32_t -#endif - -#ifndef UINT8 -#define UINT8 uint8_t -#endif - -#ifndef UINT16 -#define UINT16 uint16_t -#endif - -#ifndef UINT32 -#define UINT32 uint32_t -#endif - -#ifndef UINT64 -#define UINT64 uint64_t -#endif - -#ifndef UINT64_O -#define UINT64_O void * /* old define for FC drivers */ -#endif - -#ifndef BOOLEAN -#define BOOLEAN uint8_t -#endif - -#ifndef HANDLE -#define HANDLE int -#endif - - - -#if __WORDSIZE == 64 -#define EXT_ADDR_MODE_OS EXT_DEF_ADDR_MODE_64 -#else -#define EXT_ADDR_MODE_OS EXT_DEF_ADDR_MODE_32 -#endif - - -#define QLMULTIPATH_MAGIC 'y' - -#define _QLBUILD /* for exioct.h to enable include of qinsdmgt.h */ - - -#define EXT_DEF_MAX_HBA_OS 31 /* 0x1F */ -#define EXT_DEF_MAX_HBAS 32 /* 0 - 0x1F */ - -#define EXT_DEF_MAX_BUS_OS 1 - -#define EXT_DEF_MAX_TARGET_OS 255 /* 0xFE */ -#define EXT_DEF_MAX_TARGETS 256 /* 0 - 0xFE */ - -#define EXT_DEF_MAX_LUN_OS 255 /* 0xFE */ -#define EXT_DEF_MAX_LUNS 256 /* 0 - 0xFE */ - -#define EXT_DEF_MAX_AEN_QUEUE_OS 64 -#define EXT_DEF_MAX_TGTEV_QUEUE_OS 256 /* max tgts in driver */ -#define EXT_DEF_MAX_NFOEV_QUEUE_OS 256 - -#define EXT_DEF_FC_HEADER_LEN 24 -#define EXT_DEF_ELS_RJT_LENGTH 0x08 /* 8 */ -#define EXT_DEF_ELS_RPS_ACC_LENGTH 0x40 /* 64 */ -#define EXT_DEF_ELS_RLS_ACC_LENGTH 0x1C /* 28 */ - -#define EXT_DEF_USE_HBASELECT 0x02 /* bit 1: HbaSelect field now - * used to specify destination - * HBA of each command. - * SetInstance cmd is now - * issued only once during - * API initialization. - */ - -/* target status flags */ -#define EXT_DEF_TGTSTAT_OFFLINE 0x01 -#define EXT_DEF_TGTSTAT_IN_CFG 0x02 - -#define EXT_DEF_REGULAR_SIGNATURE "QLOGIC" - - -/*****************/ -/* Command codes */ -/*****************/ -#define QL_IOCTL_BASE(idx) \ - _IOWR(QLMULTIPATH_MAGIC, idx, EXT_IOCTL) - -#define QL_IOCTL_CMD(idx) QL_IOCTL_BASE(idx) - -/*************************************************************** - * These are regular/external command codes, starting from 0. - * The regular command code end index must be updated whenever - * adding new commands. - ***************************************************************/ -#define EXT_DEF_LN_REG_CC_START_IDX 0x00 /* reg cmd start index */ - -#define EXT_CC_QUERY_OS /* QUERY */ \ - QL_IOCTL_CMD(0x00) -#define EXT_CC_SEND_FCCT_PASSTHRU_OS /* FCCT_PASSTHRU */ \ - QL_IOCTL_CMD(0x01) -#define EXT_CC_REG_AEN_OS /* REG_AEN */ \ - QL_IOCTL_CMD(0x02) -#define EXT_CC_GET_AEN_OS /* GET_AEN */ \ - QL_IOCTL_CMD(0x03) -#define EXT_CC_SEND_ELS_RNID_OS /* SEND_ELS_RNID */ \ - QL_IOCTL_CMD(0x04) -#define EXT_CC_SCSI_PASSTHRU_OS /* SCSI_PASSTHRU */ \ - QL_IOCTL_CMD(0x05) - -#define EXT_CC_GET_DATA_OS /* GET_DATA */ \ - QL_IOCTL_CMD(0x06) -#define EXT_CC_SET_DATA_OS /* SET_DATA */ \ - QL_IOCTL_CMD(0x07) - -#define EXT_DEF_LN_REG_CC_END_IDX 0x07 /* reg cmd end index */ - -/***************************************** - * Following are internal command codes. - * See inioct.h. - *****************************************/ -#define EXT_DEF_LN_INT_CC_START_IDX 0x08 /* int cmd start index */ -#define EXT_CC_RESERVED0A_OS \ - QL_IOCTL_CMD(0x08) -#define EXT_CC_RESERVED0B_OS \ - QL_IOCTL_CMD(0x09) - -#define EXT_CC_RESERVED0C_OS \ - QL_IOCTL_CMD(0x0a) -#define EXT_CC_RESERVED0D_OS \ - QL_IOCTL_CMD(0x0b) - -#define EXT_CC_RESERVED0E_OS \ - QL_IOCTL_CMD(0x0c) -#define EXT_CC_RESERVED0F_OS \ - QL_IOCTL_CMD(0x0d) - -#define EXT_CC_RESERVED0G_OS \ - QL_IOCTL_CMD(0x0e) -#define EXT_CC_RESERVED0H_OS \ - QL_IOCTL_CMD(0x0f) - -#define EXT_CC_RESERVED0I_OS \ - QL_IOCTL_CMD(0x10) -#define EXT_CC_RESERVED0J_OS \ - QL_IOCTL_CMD(0x11) -#define EXT_CC_RESERVED0K_OS \ - QL_IOCTL_CMD(0x12) -#define EXT_CC_RESERVED0L_OS \ - QL_IOCTL_CMD(0x13) - -#define EXT_CC_RESERVED0Z_OS \ - QL_IOCTL_CMD(0x21) - -#define EXT_DEF_LN_INT_CC_END_IDX 0x21 /* supported int cmd end idx */ - -/********************************************************/ -/* These are additional regular/external command codes. */ -/********************************************************/ -#define EXT_DEF_LN_ADD_CC_START_IDX 0x30 /* additional cmd start index */ -#define EXT_CC_SEND_ELS_PASSTHRU_OS \ - QL_IOCTL_CMD(0x30) -#define EXT_DEF_LN_ADD_CC_END_IDX 0x30 /* additional cmd end index */ - - -/******************************************************** - * NextGen Failover (NFO) ioctl command codes range from - * 0x37 to 0x4f. See qlnfoln.h - ********************************************************/ - - -/******************************************************** - * Failover ioctl command codes range from 0xc0 to 0xdf. - * See definition in qlfoln.h. - ********************************************************/ - - -/*******************************************************************/ -/* These are Linux driver implementation specific commands. Values */ -/* start from highest possible value and in decreasing order. */ -/*******************************************************************/ -#define EXT_DEF_LN_SPC_CC_START_IDX 0xff /* LN specific cmd start idx */ - -#define EXT_CC_GET_HBA_CNT /* GET_HBA_CNT */ \ - QL_IOCTL_CMD(0xff) -#define EXT_CC_SETINSTANCE /* SETINSTANCE */ \ - QL_IOCTL_CMD(0xfe) -#define EXT_CC_WWPN_TO_SCSIADDR /* WWPN_TO_SCSIADDR */ \ - QL_IOCTL_CMD(0xfd) -#define EXT_CC_DRIVER_SPECIFIC /* DRIVER_SPECIFIC */ \ - QL_IOCTL_CMD(0xfc) - -#define EXT_DEF_LN_SPC_CC_END_IDX 0xfc /* LN specific cmd end idx */ - - -/* - * Response struct definition - */ -typedef struct _EXT_LN_DRV_VERSION { - UINT8 Major; - UINT8 Minor; - UINT8 Patch; - UINT8 Beta; - UINT8 Reserved[4]; -} EXT_LN_DRV_VERSION; /* 8 */ - -typedef struct _EXT_LN_DRIVER_DATA { - EXT_LN_DRV_VERSION DrvVer; /* 8 */ - UINT32 Flags; /* 4 */ - UINT32 Reserved[13]; /* 52 */ -} EXT_LN_DRIVER_DATA, *PEXT_LN_DRIVER_DATA; /* 64 */ - -/* Bit defines for the Flags field */ -#define EXT_DEF_NGFO_CAPABLE 0x0001 /* bit 0: failover capable */ -#define EXT_DEF_NGFO_ENABLED 0x0002 /* bit 1: failover enabled */ - - - -/* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 2 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -2 - * c-argdecl-indent: 2 - * c-label-offset: -2 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ - -#endif /* _EXIOCT_LN_H_ */ - diff --git a/qla_isp/linux/isp_cb_ops.c b/qla_isp/linux/isp_cb_ops.c index 3fcaee4fd..005f4e55a 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.89 2008/04/15 22:41:03 mjacob Exp $ */ +/* $Id: isp_cb_ops.c,v 1.95 2008/09/12 20:53:44 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -59,10 +59,8 @@ #include "isp_linux.h" #include "isp_ioctl.h" -#include "exioct.h" #ifdef CONFIG_PROC_FS - /* * 'safe' proc pretty print code */ @@ -159,7 +157,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l } else if (strncmp(buf, "rescan", 6) == 0) { if (IS_FC(isp)) { for (io = 0; io < isp->isp_nchan; io++) { - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __func__, __LINE__); } io = len; } @@ -227,8 +225,8 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l " MboxC=0x%016llx async=0x%016llx\n" " CRslt=0x%016llx CPost=0x%016llx\n" " RspnsCHiWater=0x%04x FastPostC_Hiwater=0x%04x\n", - (unsigned long long) isp->isp_intcnt, (unsigned long long) isp->isp_intbogus, (unsigned long long) isp->isp_intmboxc, - (unsigned long long) isp->isp_intoasync, (unsigned long long) isp->isp_rsltccmplt, (unsigned long long) isp->isp_fphccmplt, + (ull) isp->isp_intcnt, (ull) isp->isp_intbogus, (ull) isp->isp_intmboxc, + (ull) isp->isp_intoasync, (ull) isp->isp_rsltccmplt, (ull) isp->isp_fphccmplt, isp->isp_rscchiwater, isp->isp_fpcchiwater); copy_info(&info, " Request In %d Request Out %d Result %d Nactv %d" @@ -251,20 +249,20 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l #endif copy_info(&info, "\n"); if (isp->isp_osinfo.wqnext) { - Scsi_Cmnd *f = isp->isp_osinfo.wqnext; + struct scsi_cmnd *f = isp->isp_osinfo.wqnext; copy_info(&info, "WaitQ(%d)", isp->isp_osinfo.wqcnt); while (f) { copy_info(&info, "->%p", f); - f = (Scsi_Cmnd *) f->host_scribble; + f = (struct scsi_cmnd *) f->host_scribble; } copy_info(&info, "\n"); } if (isp->isp_osinfo.dqnext) { - Scsi_Cmnd *f = isp->isp_osinfo.dqnext; + struct scsi_cmnd *f = isp->isp_osinfo.dqnext; copy_info(&info, "DoneQ"); while (f) { copy_info(&info, "->%p", f); - f = (Scsi_Cmnd *) f->host_scribble; + f = (struct scsi_cmnd *) f->host_scribble; } copy_info(&info, "\n"); } @@ -292,7 +290,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l copy_info(&info, "Self Channel %d:\nHandle ID 0x%x PortID 0x%06x FW State 0x%x Loop State 0x%x\n", chan, fcp->isp_loopid, fcp->isp_portid, fcp->isp_fwstate, fcp->isp_loopstate); - copy_info(&info, "Port WWN 0x%016llx Node WWN 0x%016llx\n\n", fcp->isp_wwpn, fcp->isp_wwnn); + copy_info(&info, "Port WWN 0x%016llx Node WWN 0x%016llx\n\n", (ull) fcp->isp_wwpn, (ull)fcp->isp_wwnn); copy_info(&info, "FC devices in port database:\n"); for (i = 0; i < MAX_FC_TARG; i++) { if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) { @@ -301,11 +299,11 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l if (fcp->portdb[i].ini_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, fcp->portdb[i].port_wwn, fcp->portdb[i].node_wwn); + fcp->portdb[i].ini_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], - fcp->portdb[i].port_wwn, fcp->portdb[i].node_wwn); + (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn); } } } @@ -332,15 +330,17 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l ISP_UNLKU_SOFTC(isp); return (info.pos > info.offset ? info.pos - info.offset : 0); } +#endif /* CONFIG_PROC_FS */ static int isp_open(struct inode *, struct file *); static int isp_close(struct inode *, struct file *); static int isp_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static int isp_qlogic_ext_ioctl(struct inode *, struct file *, unsigned int, unsigned long); dev_t isp_dev; struct cdev isp_cdev = { - .kobj = { .k_name = ISP_NAME, } , +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + .kobj = { .k_name = ISP_NAME, }, +#endif .owner = THIS_MODULE }; ISP_CLASS *isp_class; @@ -384,8 +384,6 @@ isp_close(struct inode *ip, struct file *fp) return (0); } -static int isp_perf_test(ispsoftc_t *, isp_perftst_t *); - static int isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) { @@ -400,10 +398,6 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) return -ENXIO; } - if (((c & _IOC_TYPEMASK) >> _IOC_TYPESHIFT) == QLMULTIPATH_MAGIC) { - return (isp_qlogic_ext_ioctl(ip, fp, c, arg)); - } - if (IS_SCSI(isp)) { switch (c) { case ISP_SDBLEV: @@ -477,7 +471,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) if (IS_FC(isp)) { for (i = 0; i < isp->isp_nchan; i++) { FCPARAM(isp, i)->isp_loopstate = LOOP_PDB_RCVD; - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __func__, __LINE__); } } break; @@ -752,17 +746,6 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) } break; } - case ISP_FC_PERFTST: - { - isp_perftst_t local, *tt = &local; - - if (COPYIN((void *)arg, tt, sizeof (*tt))) { - rv = -EFAULT; - break; - } - rv = isp_perf_test(isp, tt); - break; - } default: rv = -EINVAL; break; @@ -770,875 +753,11 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg) return (rv); } -/* - * SDMI Routines - */ - -static int isp_exti_query(EXT_IOCTL *); -static int isp_exti_setinstance(EXT_IOCTL *); -static int isp_exti_fcct_passthru(EXT_IOCTL *); -static int isp_exti_discover_luns(ispsoftc_t *, int, UINT64, UINT64, UINT16 *); -static void *isp_exti_usrptr(UINT64, UINT16); -static int isp_exti_passthru(EXT_IOCTL *); -static int isp_run_cmd(ispsoftc_t *, isp_xcmd_t *); - -static int -isp_qlogic_ext_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) -{ - EXT_IOCTL ext; - EXT_IOCTL *uext = (EXT_IOCTL *) arg; - int rval; - - rval = 0; - - if (COPYIN(uext, &ext, sizeof (ext))) { - ext.Status = EXT_STATUS_COPY_ERR; - ext.DetailStatus = 0; - goto out; - } - - ext.DetailStatus = EXT_STATUS_OK; - ext.Status = EXT_STATUS_OK; - - /* - * Make sure this is a supported command. - */ - switch (cmd) { - case EXT_CC_GET_HBA_CNT: - case EXT_CC_SETINSTANCE: - case EXT_CC_QUERY: - case EXT_SC_QUERY_CHIP: - case EXT_CC_SEND_FCCT_PASSTHRU: - case EXT_CC_SEND_SCSI_PASSTHRU: - break; - default: - ext.Status = EXT_STATUS_INVALID_REQUEST; - ext.DetailStatus = 0; - break; - } - if (ext.Status != EXT_STATUS_OK) { - goto out; - } - - if (memcmp(&ext.Signature, EXT_DEF_REGULAR_SIGNATURE, strlen(EXT_DEF_REGULAR_SIGNATURE)) != 0) { - printk("%s: bad signature\n", __FUNCTION__); - ext.Status = EXT_STATUS_INVALID_PARAM; - goto out; - } - - if (ext.Version != EXT_VERSION) { - printk("%s: bad version %d\n", __FUNCTION__, ext.Version); - ext.Status = EXT_STATUS_UNSUPPORTED_VERSION; - goto out; - } - /* - * We only count FC adapters. - */ - if (cmd == EXT_CC_GET_HBA_CNT) { - unsigned int i; - - ext.Instance = 0; - for (i = 0; i < MAX_ISP; i++) { - if (isplist[i] && IS_FC(isplist[i])) { - ext.Instance++; - } - } - if (COPYOUT(&ext.Instance, &uext->Instance, sizeof (uext->Instance))) { - ext.Status = EXT_STATUS_COPY_ERR; - } else { - ext.Status = EXT_STATUS_OK; - } - } else if (cmd == EXT_CC_SETINSTANCE) { - rval = isp_exti_setinstance(&ext); - if (rval) { - goto out; - } - if (COPYOUT(&ext.HbaSelect, &uext->HbaSelect, sizeof (uext->HbaSelect))) { - ext.Status = EXT_STATUS_COPY_ERR; - } else { - ext.Status = EXT_STATUS_OK; - } - } else if (cmd == EXT_CC_QUERY) { - rval = isp_exti_query(&ext); - } else if (cmd == EXT_CC_SEND_FCCT_PASSTHRU) { - rval = isp_exti_fcct_passthru(&ext); - } else if (cmd == EXT_CC_SEND_SCSI_PASSTHRU) { - rval = isp_exti_passthru(&ext); - } else { - ext.Status = EXT_STATUS_INVALID_REQUEST; - } - -out: - if (COPYOUT(&ext.Status, &uext->Status, sizeof (ext.Status))) { - rval = -EFAULT; - } else if (COPYOUT(&ext.DetailStatus, &uext->DetailStatus, sizeof (ext.Status))) { - rval = -EFAULT; - } - return (rval); -} - -static int -isp_exti_setinstance(EXT_IOCTL *ext) -{ - unsigned int inst, index; - - for (inst = index = 0; index < MAX_ISP; index++) { - if (isplist[index] && IS_FC(isplist[index])) { - if (inst++ == ext->Instance) { - break; - } - } - } - if (index >= MAX_ISP) { - ext->Status = EXT_STATUS_DEV_NOT_FOUND; - return (-ENXIO); - } - api_isp = isplist[index]; - ext->HbaSelect = api_isp->isp_unit; - api_channel = 0; /* XXXXXXXXXXXXXXXXXXXXXXX */ - return (0); -} - -static int -isp_exti_query(EXT_IOCTL *pext) -{ - ispsoftc_t *isp = api_isp; - int cl, i, rval = 0; - void *outaddr; - fcparam *fcp; - fcportdb_t *lp; - unsigned long flags; - - if (isp == NULL) { - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - return (0); - } - ISP_LOCKU_SOFTC(isp); - fcp = FCPARAM(isp, api_channel); - if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_LSCAN_DONE) { - if (isp_fc_runstate(isp, api_channel, 1000000) < 0) { - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_PENDING; - return (0); - } - } - - outaddr = isp_exti_usrptr(pext->ResponseAdr, pext->AddrMode); - - switch (pext->SubCode) { - case EXT_SC_QUERY_HBA_NODE: - { - EXT_HBA_NODE hba; - - MEMZERO(&hba, sizeof (hba)); - MAKE_NODE_NAME_FROM_WWN(hba.WWNN, fcp->isp_wwnn_nvram); - MEMCPY(hba.SerialNum, &hba.WWNN[5], 3); - SNPRINTF((char *)hba.DriverVersion, EXT_DEF_MAX_STR_SIZE, "Linux Version %d.%d; Common Core Code Version %d.%d", - ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, - ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); - SNPRINTF((char *)hba.FWVersion, EXT_DEF_MAX_STR_SIZE, "%02d.%02d.%02d", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]); - hba.OptRomVersion[0] = '0'; - hba.PortCount = 1; - hba.InterfaceType = EXT_DEF_FC_INTF_TYPE; - ISP_UNLKU_SOFTC(isp); - cl = min(pext->ResponseLen, sizeof (hba)); - if (COPYOUT(&hba, outaddr, cl)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - break; - } - case EXT_SC_QUERY_HBA_PORT: - { - EXT_HBA_PORT hbp; - - MEMZERO(&hbp, sizeof (hbp)); - MAKE_NODE_NAME_FROM_WWN(hbp.WWPN, FCPARAM(isp, 0)->isp_wwpn); - hbp.Id[1] = (fcp->isp_portid >> 16) & 0xff; - hbp.Id[2] = (fcp->isp_portid >> 8) & 0xff; - hbp.Id[3] = fcp->isp_portid & 0xff; - - if (FCPARAM(isp, 0)->role & ISP_ROLE_TARGET) { - hbp.Type |= EXT_DEF_TARGET_DEV; - } - - if (FCPARAM(isp, 0)->role & ISP_ROLE_INITIATOR) { - hbp.Type |= EXT_DEF_INITIATOR_DEV; - } - - hbp.State = EXT_DEF_HBA_OK; - - if (fcp->isp_topo == TOPO_NL_PORT || fcp->isp_topo == TOPO_FL_PORT) { - hbp.Mode = EXT_DEF_LOOP_MODE; - } else { - hbp.Mode = EXT_DEF_P2P_MODE; - } - hbp.Type |= EXT_DEF_FABRIC_DEV; - - /* - * Count devices in our port database. - */ - for (i = 0; i < MAX_FC_TARG; i++) { - lp = &fcp->portdb[i]; - if (lp->state != FC_PORTDB_STATE_VALID) { - continue; - } - if (lp->portid == fcp->isp_portid) { - continue; - } - hbp.DiscPortCount++; - if (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) { - hbp.DiscTargetCount++; - } - } - ISP_UNLKU_SOFTC(isp); - hbp.DiscPortNameType = EXT_DEF_USE_PORT_NAME; - hbp.PortSupportedFC4Types = EXT_DEF_FC4_TYPE_SCSI; - hbp.PortActiveFC4Types = EXT_DEF_FC4_TYPE_SCSI; - hbp.PortSupportedSpeed = EXT_DEF_PORTSPEED_1GBIT; - if (IS_23XX(isp)) { - hbp.PortSupportedSpeed |= EXT_DEF_PORTSPEED_2GBIT; - } else if (IS_24XX(isp)) { - hbp.PortSupportedSpeed |= EXT_DEF_PORTSPEED_2GBIT|EXT_DEF_PORTSPEED_4GBIT; - } - cl = min(pext->ResponseLen, sizeof (hbp)); - if (COPYOUT(&hbp, outaddr, cl)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - break; - } - case EXT_SC_QUERY_DISC_PORT: - { - EXT_DISC_PORT port; - fcportdb_t *rlp; - int inst; - - MEMZERO(&port, sizeof (port)); - rlp = NULL; - for (inst = i = 0; rlp == NULL && i < MAX_FC_TARG; i++) { - lp = &fcp->portdb[i]; - if (lp->state != FC_PORTDB_STATE_VALID) { - continue; - } - if (lp->portid == fcp->isp_portid) { - continue; - } - if (inst != pext->Instance) { - inst++; - continue; - } - rlp = lp; - } - if (rlp == NULL) { - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - break; - } - MAKE_NODE_NAME_FROM_WWN(port.WWPN, rlp->port_wwn); - MAKE_NODE_NAME_FROM_WWN(port.WWNN, rlp->node_wwn); - port.Id[1] = (rlp->portid >> 16) & 0xff; - port.Id[2] = (rlp->portid >> 8) & 0xff; - port.Id[3] = rlp->portid & 0xff; - if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { - port.Type = EXT_DEF_FABRIC_DEV; - } else { - port.Type = 0; - } - if (rlp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) { - port.Type |= EXT_DEF_TARGET_DEV; - } - if (rlp->roles & (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT)) { - port.Type |= EXT_DEF_INITIATOR_DEV; - } - port.Status = EXT_DEF_HBA_OK; - port.Bus = isp->isp_host->host_no; - if (rlp->ini_map_idx) { - port.TargetId = rlp->ini_map_idx - 1; - } else { - port.TargetId = 0; - } - ISP_UNLKU_SOFTC(isp); - cl = min(pext->ResponseLen, sizeof (port)); - if (COPYOUT(&port, outaddr, cl)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - break; - } - case EXT_SC_QUERY_DISC_TGT: - { - EXT_DISC_TARGET tgt; - fcportdb_t *rlp; - UINT64 wwpn, wwnn; - int inst; - - MEMZERO(&tgt, sizeof (tgt)); - rlp = NULL; - for (inst = i = 0; rlp == NULL && i < MAX_FC_TARG; i++) { - lp = &fcp->portdb[i]; - if (lp->state != FC_PORTDB_STATE_VALID) { - continue; - } - if (lp->portid == fcp->isp_portid) { - continue; - } - if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) { - continue; - } - if (inst != pext->Instance) { - inst++; - continue; - } - rlp = lp; - } - if (rlp == NULL) { - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - break; - } - MAKE_NODE_NAME_FROM_WWN(tgt.WWPN, rlp->port_wwn); - MAKE_NODE_NAME_FROM_WWN(tgt.WWNN, rlp->node_wwn); - tgt.Id[1] = (rlp->portid >> 16) & 0xff; - tgt.Id[2] = (rlp->portid >> 8) & 0xff; - tgt.Id[3] = rlp->portid & 0xff; - if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) { - tgt.Type = EXT_DEF_FABRIC_DEV; - } else { - tgt.Type = 0; - } - if (rlp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) { - tgt.Type |= EXT_DEF_TARGET_DEV; - } - if (rlp->roles & (SVC3_INI_ROLE >> SVC3_ROLE_SHIFT)) { - tgt.Type |= EXT_DEF_INITIATOR_DEV; - } - tgt.Status = EXT_DEF_HBA_OK; - tgt.Bus = isp->isp_host->host_no; - if (rlp->ini_map_idx) { - tgt.TargetId = rlp->ini_map_idx - 1; - } else { - tgt.TargetId = 0; - } - wwpn = rlp->port_wwn; - wwnn = rlp->node_wwn; - ISP_UNLKU_SOFTC(isp); - rval = isp_exti_discover_luns(isp, api_channel, wwpn, wwnn, &tgt.LunCount); - if (rval) { - break; - } - cl = min(pext->ResponseLen, sizeof (tgt)); - if (COPYOUT(&tgt, outaddr, cl)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - break; - } - case EXT_SC_QUERY_CHIP: - { - EXT_CHIP xc; - struct pci_dev *pdev = isp->isp_osinfo.device; - - MEMZERO(&xc, sizeof (xc)); - xc.VendorId = pdev->vendor; - xc.DeviceId = pdev->device; - xc.SubVendorId = pdev->subsystem_vendor; - xc.SubSystemId = pdev->subsystem_device; - xc.PciBusNumber = pdev->bus->number; - xc.PciDevFunc = pdev->devfn; - xc.PciSlotNumber = PCI_SLOT(pdev->devfn); - xc.DomainNr = pci_domain_nr(pdev->bus); - xc.InterruptLevel = pdev->irq; - cl = min(pext->ResponseLen, sizeof (xc)); - if (COPYOUT(&xc, outaddr, cl)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - break; - } - case EXT_SC_QUERY_DISC_LUN: - default: - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_UNSUPPORTED_SUBCODE; - break; - } - return (rval); -} - - -#define IGPOFF 0 /* place CT Request itself is put */ -#define OGPOFF (ISP_FC_SCRLEN >> 1) /* place CT Response itself is put */ -#define ZTXOFF (ISP_FC_SCRLEN - (1 * QENTRY_LEN)) /* place where status entry for CT passthru request ends up */ -#define CTXOFF (ISP_FC_SCRLEN - (2 * QENTRY_LEN)) /* place where CT passthru request is put */ - -static int -isp_exti_fcct_passthru(EXT_IOCTL *pext) -{ - ispsoftc_t *isp = api_isp; - isp_plcmd_t p; - fcparam *fcp = FCPARAM(isp, 0); - mbreg_t mbs; - uint8_t qe[QENTRY_LEN], *scp; - uint16_t handle; - unsigned long flags; - void *localmem = NULL; - size_t localamt; - int r; - int rval = 0; - - if (isp == NULL) { - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - return (0); - } - - if (pext->RequestLen > (ISP_FC_SCRLEN >> 1)) { - pext->Status = EXT_STATUS_NO_MEMORY; - return (0); - } - if (pext->ResponseLen > ((ISP_FC_SCRLEN >> 1) - (2 * QENTRY_LEN))) { - pext->Status = EXT_STATUS_NO_MEMORY; - return (0); - } - - localamt = pext->RequestLen; - if (pext->ResponseLen > localamt) { - localamt = pext->ResponseLen; - } - localmem = isp_kalloc(localamt, GFP_KERNEL); - if (localmem == NULL) { - pext->Status = EXT_STATUS_NO_MEMORY; - return (0); - } - pext->Status = EXT_STATUS_OK; - if (COPYIN(isp_exti_usrptr(pext->RequestAdr, pext->AddrMode), localmem, pext->RequestLen)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - goto out; - } - - /* - * First- check to see if topology is right and things are right otherwise. - */ - ISP_LOCKU_SOFTC(isp); - if (fcp->isp_topo != TOPO_F_PORT && fcp->isp_topo != TOPO_FL_PORT) { - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_UNSUPPORTED_SUBCODE; - goto out; - } - - /* - * Login into the Management Server - */ - p.channel = api_channel; - p.handle = NIL_HANDLE; - p.portid = MANAGEMENT_PORT_ID; - p.flags = PLOGX_FLG_CMD_PLOGI; - r = isp_control(isp, ISPCTL_PLOGX, &p); - if (r) { - ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGWARN, "failed to log into management server (0x%x)", r); - pext->Status = EXT_STATUS_MS_NO_RESPONSE; - goto out; - } - handle = p.handle; - - /* - * Acquire Scratch - */ - MEMZERO(qe, QENTRY_LEN); - if (FC_SCRATCH_ACQUIRE(isp, 0)) { - ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGWARN, "failed to get FC scratch area"); - pext->Status = EXT_STATUS_BUSY; - goto out; - } - scp = fcp->isp_scratch; - - MEMCPY(&scp[IGPOFF], localmem, pext->RequestLen); - MEMORYBARRIER(isp, SYNC_SFORDEV, IGPOFF, pext->RequestLen); - - /* - * Build command we're going to use - */ - if (IS_24XX(isp)) { - isp_ct_pt_t *pt; - - /* - * Build a Passthrough IOCB in memory. - */ - pt = (isp_ct_pt_t *)qe; - pt->ctp_header.rqs_entry_count = 1; - pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; - pt->ctp_handle = 0xffffffff; - pt->ctp_nphdl = handle; - pt->ctp_cmd_cnt = 1; - pt->ctp_time = 5; - pt->ctp_rsp_cnt = 1; - pt->ctp_rsp_bcnt = pext->ResponseLen; - pt->ctp_cmd_bcnt = pext->RequestLen; - pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF); - pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF); - pt->ctp_dataseg[0].ds_count = pext->RequestLen; - pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+OGPOFF); - pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+OGPOFF); - pt->ctp_dataseg[1].ds_count = pext->ResponseLen; - isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]); - - /* - * Build a EXEC IOCB A64 command that points to the CT passthru command - */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; - 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.logval = MBLOGALL; - MEMORYBARRIER(isp, SYNC_SFORDEV, CTXOFF, 2 * QENTRY_LEN); - isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - pext->Status = EXT_STATUS_ERR; - goto out1; - } - MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN); - pt = (isp_ct_pt_t *)qe; - isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt); - /* - * Let the user application parse any errors - */ - } else { - isp_ms_t *ms; - /* - * Build a Passthrough IOCB in memory. - */ - ms = (isp_ms_t *)qe; - ms->ms_header.rqs_entry_count = 1; - ms->ms_header.rqs_entry_type = RQSTYPE_MS_PASSTHRU; - ms->ms_handle = 0xffffffff; - if (ISP_CAP_2KLOGIN(isp)) { - ms->ms_nphdl = handle; - } else { - ms->ms_nphdl = handle << 8; - } - ms->ms_cmd_cnt = 1; - ms->ms_time = 5; - ms->ms_tot_cnt = 2; - ms->ms_rsp_bcnt = pext->ResponseLen; - ms->ms_cmd_bcnt = pext->RequestLen; - ms->ms_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF); - ms->ms_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF); - ms->ms_dataseg[0].ds_count = pext->RequestLen; - ms->ms_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+OGPOFF); - ms->ms_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+OGPOFF); - ms->ms_dataseg[1].ds_count = pext->ResponseLen; - isp_put_ms(isp, ms, (isp_ms_t *) &scp[CTXOFF]); - - /* - * Build a EXEC IOCB A64 command that points to the MS passthru command - */ - MEMZERO(&mbs, sizeof (mbs)); - mbs.param[0] = MBOX_EXEC_COMMAND_IOCB_A64; - 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.logval = MBLOGALL; - MEMORYBARRIER(isp, SYNC_SFORDEV, CTXOFF, 2 * QENTRY_LEN); - isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { - pext->Status = EXT_STATUS_ERR; - goto out1; - } - MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN); - ms = (isp_ms_t *)qe; - isp_get_ms(isp, (isp_ms_t *) &scp[ZTXOFF], ms); - } - - MEMORYBARRIER(isp, SYNC_SFORCPU, OGPOFF, pext->ResponseLen); - MEMCPY(localmem, &scp[OGPOFF], pext->ResponseLen); - -out1: - - /* - * Release Scratch - */ - FC_SCRATCH_RELEASE(isp, 0); - - /* - * Log out of the Management Server - */ - p.channel = api_channel; - p.handle = handle; - p.portid = MANAGEMENT_PORT_ID; - p.flags = PLOGX_FLG_CMD_LOGO|PLOGX_FLG_EXPLICIT_LOGO; - r = isp_control(isp, ISPCTL_PLOGX, &p); - if (r) { - isp_prt(isp, ISP_LOGWARN, "failed to log out of management server (0x%x)", r); - } - ISP_UNLKU_SOFTC(isp); - - /* - * Copy data - */ -out: - if (rval == 0) { - if (COPYOUT(localmem, isp_exti_usrptr(pext->ResponseAdr, pext->AddrMode), pext->ResponseLen)) { - pext->Status = EXT_STATUS_COPY_ERR; - rval = -EFAULT; - } - } - if (localmem) { - isp_kfree(localmem, localamt); - } - return (rval); -} - -static void * -isp_exti_usrptr(UINT64 uaddr, UINT16 mode) -{ - void *ptr = NULL; - -#if BITS_PER_LONG == 32 - if (mode == EXT_DEF_ADDR_MODE_32) { - UINT32 xaddr = uaddr & 0xffffffff; - ptr = (void *) xaddr; - } -#elif BITS_PER_LONG == 64 - ptr = (void *) uaddr; -#endif - return (ptr); -} - -static int -isp_exti_passthru(EXT_IOCTL *pext) -{ - ispsoftc_t *isp = api_isp; - char *bufp; - fcportdb_t *lp; - EXT_FC_SCSI_PASSTHRU fcx; - uint64_t wwnn = 0LL; - uint64_t wwpn = 0LL; - uint32_t portid = (uint32_t) -1; - isp_xcmd_t cmd; - int status; - size_t cpyamt; - unsigned long flags; - - if (isp == NULL) { - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - return (0); - } - if (COPYIN(isp_exti_usrptr(pext->RequestAdr, pext->AddrMode), &fcx, sizeof (fcx))) { - pext->Status = EXT_STATUS_COPY_ERR; - return (0); - } - - if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_SCSI || fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_FABRIC) { - pext->Status = EXT_STATUS_INVALID_REQUEST; - return (0); - } - - if (isp == NULL) { - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - return (0); - } - - switch (pext->SubCode) { - case EXT_SC_SEND_FC_SCSI_PASSTHRU: - break; - case EXT_SC_SEND_SCSI_PASSTHRU: - case EXT_SC_SCSI3_PASSTHRU: - default: - pext->Status = EXT_STATUS_UNSUPPORTED_SUBCODE; - return (0); - } - - MEMZERO(&cmd, sizeof (cmd)); - - if (pext->ResponseLen) { - bufp = isp_kalloc(pext->ResponseLen, GFP_KERNEL); - if (bufp == NULL) { - pext->Status = EXT_STATUS_NO_MEMORY; - return (0); - } - if (fcx.Direction == EXT_DEF_SCSI_PASSTHRU_DATA_OUT) { - if (COPYIN(isp_exti_usrptr(pext->ResponseAdr, pext->AddrMode), bufp, pext->ResponseLen)) { - isp_kfree(bufp, pext->ResponseLen); - pext->Status = EXT_STATUS_COPY_ERR; - return (0); - } - } else { - cmd.fcd.beg.do_read = 1; - } - cmd.fcd.beg.data_length = pext->ResponseLen; - cmd.fcd.beg.data_ptr = bufp; - } else { - bufp = NULL; - } - - if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWNN) { - MAKE_WWN_FROM_NODE_NAME(wwnn, fcx.FCScsiAddr.DestAddr.WWNN); - } else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWPN) { - MAKE_WWN_FROM_NODE_NAME(wwpn, fcx.FCScsiAddr.DestAddr.WWPN); - } else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_PORTID) { - portid = (fcx.FCScsiAddr.DestAddr.Id[1] << 16) | (fcx.FCScsiAddr.DestAddr.Id[2] << 8) | (fcx.FCScsiAddr.DestAddr.Id[3]); - } - /* - * Make sure we have an entry for this device (handle, portid) - * so we know how to send the command. - */ - ISP_LOCKU_SOFTC(isp); - for (lp = &FCPARAM(isp, api_channel)->portdb[0]; lp < &FCPARAM(isp, api_channel)->portdb[MAX_FC_TARG]; lp++) { - if (lp->state != FC_PORTDB_STATE_VALID) { - continue; - } - if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWNN) { - if (lp->node_wwn == wwnn) { - break; - } - } else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWPN) { - if (lp->port_wwn == wwpn) { - break; - } - } else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_PORTID) { - if (lp->portid == portid) { - break; - } - } - } - if (lp == &FCPARAM(isp, api_channel)->portdb[MAX_FC_TARG]) { - ISP_UNLKU_SOFTC(isp); - pext->Status = EXT_STATUS_DEV_NOT_FOUND; - if (bufp) { - isp_kfree(bufp, pext->ResponseLen); - } - return (0); - } - wwnn = lp->node_wwn; - wwpn = lp->port_wwn; - cmd.handle = lp->handle; - cmd.portid = lp->portid; - cmd.channel = api_channel; - ISP_UNLKU_SOFTC(isp); - - MEMCPY(cmd.fcd.beg.cdb, fcx.Cdb, min(EXT_DEF_SCSI_PASSTHRU_CDB_LENGTH, sizeof (cmd.fcd.beg.cdb))); - cmd.lun = fcx.FCScsiAddr.Lun; - cmd.timeout = fcx.Timeout; - cpyamt = 0; - pext->Status = EXT_STATUS_OK; - - status = isp_run_cmd(isp, &cmd); - if (status == 0) { - cpyamt = pext->ResponseLen - cmd.fcd.end.data_residual; - if (cmd.fcd.end.status == SCSI_CHECK && cmd.fcd.end.sense_length) { - fcx.SenseLength = min(cmd.fcd.end.sense_length, sizeof (fcx.SenseData)); - MEMCPY(fcx.SenseData, cmd.fcd.end.sense_data, fcx.SenseLength); - } - if ((pext->DetailStatus = cmd.fcd.end.status) != SCSI_GOOD) { - pext->Status = EXT_STATUS_SCSI_STATUS; - } else if (cpyamt != pext->ResponseLen) { - pext->Status = EXT_STATUS_DATA_UNDERRUN; - } - } else { - cpyamt = 0; - pext->Status = EXT_STATUS_ERR; - } - - if (bufp && fcx.Direction == EXT_DEF_SCSI_PASSTHRU_DATA_IN && cpyamt) { - if (cpyamt) { - if (COPYOUT(bufp, isp_exti_usrptr(pext->ResponseAdr, pext->AddrMode), cpyamt)) { - pext->Status = EXT_STATUS_COPY_ERR; - } - } - } - if (bufp) { - isp_kfree(bufp, pext->ResponseLen); - } - return (0); -} - -#define RPT_LUN_SIZE 1024 - -static int -isp_exti_discover_luns(ispsoftc_t *isp, int chan, UINT64 wwpn, UINT64 wwnn, UINT16 *nluns) -{ - isp_xcmd_t cmd; - int status, nent, i, hilun; - unsigned long flags; - fcparam *fcp = FCPARAM(isp, chan); - fcportdb_t *lp; - uint8_t *bufp; - - MEMZERO(&cmd, sizeof (isp_xcmd_t)); - ISP_LOCKU_SOFTC(isp); - for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) { - if (lp->state != FC_PORTDB_STATE_VALID) { - continue; - } - if (lp->port_wwn == wwpn && lp->node_wwn == wwnn) { - break; - } - } - if (lp == &fcp->portdb[MAX_FC_TARG]) { - ISP_UNLKU_SOFTC(isp); - return (-ENODEV); - } - if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) { - ISP_UNLKU_SOFTC(isp); - *nluns = 0; - return (0); - } - cmd.handle = lp->handle; - cmd.portid = lp->portid; - ISP_UNLKU_SOFTC(isp); - bufp = isp_kzalloc(RPT_LUN_SIZE, GFP_KERNEL); - if (bufp == NULL) { - return (-ENOMEM); - } - cmd.fcd.beg.data_ptr = bufp; - cmd.fcd.beg.data_length = RPT_LUN_SIZE; - cmd.fcd.beg.do_read = 1; - cmd.fcd.beg.cdb[0] = REPORT_LUNS; - cmd.fcd.beg.cdb[4] = (RPT_LUN_SIZE >> 24) & 0xff; - cmd.fcd.beg.cdb[5] = (RPT_LUN_SIZE >> 16) & 0xff; - cmd.fcd.beg.cdb[6] = (RPT_LUN_SIZE >> 8) & 0xff; - cmd.fcd.beg.cdb[7] = (RPT_LUN_SIZE) & 0xff; - cmd.timeout = 30; - status = isp_run_cmd(isp, &cmd); - if (status) { - isp_prt(isp, ISP_LOGWARN, "isp_exti_discover_luns: isp_run_cmd returned %d", status); - isp_kfree(bufp, RPT_LUN_SIZE); - return (-EIO); - } - nent = (bufp[2] << 8) | bufp[3]; - - - hilun = 0; - /* - * This is not *quite* the right way to do this. - */ - for (i = 0; i < nent; i++) { - uint8_t *lunptr = bufp + 8 + (8 * i); - uint16_t lun; - lun = lunptr[1]; - if (lunptr[0] & 0x40) { - lun |= ((lunptr[1] & 0x1f) << 8); - } - if (hilun < lun) { - hilun = lun; - } - } - isp_kfree(bufp, RPT_LUN_SIZE); - *nluns = hilun + 1; - return (0); -} - +#if 0 static void isp_run_cmd_done(struct scsi_cmnd *Cmnd) { - struct semaphore *semap = (struct semaphore *) Cmnd->request_buffer; + struct semaphore *semap = (struct semaphore *) Cmnd->SCp.ptr; up(semap); } @@ -1646,7 +765,7 @@ static int isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) { struct scsi_device *dev = NULL; - Scsi_Cmnd *Cmnd = NULL; + struct scsi_cmnd *Cmnd = NULL; struct Scsi_Host *host = NULL; uint32_t nxti, optr, handle; uint8_t local[QENTRY_LEN]; @@ -1663,7 +782,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) time = 0x1999; } MEMZERO(local, sizeof (local)); - Cmnd = isp_kzalloc(sizeof (Scsi_Cmnd), GFP_KERNEL); + Cmnd = isp_kzalloc(sizeof (struct scsi_cmnd), GFP_KERNEL); if (Cmnd == NULL) { result = -ENOMEM; goto out; @@ -1677,12 +796,12 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) Cmnd->device = dev; dev->host = host; Cmnd->scsi_done = isp_run_cmd_done; - Cmnd->request_buffer = &rsem; + Cmnd->SCp.ptr = (char *)&rsem; ISP_LOCKU_SOFTC(isp); if (isp_getrqentry(isp, &nxti, &optr, (void *)&reqp)) { ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGDEBUG0, "%s: Request Queue Overflow", __FUNCTION__); + isp_prt(isp, ISP_LOGDEBUG0, "%s: Request Queue Overflow", __func__); result = -ENOMEM; goto out; } @@ -1748,6 +867,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) } MEMCPY(Cmnd->cmnd, cmd->fcd.beg.cdb, Cmnd->cmd_len); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) Cmnd->request_bufflen = cmd->fcd.beg.data_length; Cmnd->request_buffer = cmd->fcd.beg.data_ptr; if (Cmnd->request_bufflen && Cmnd->request_buffer) { @@ -1775,14 +895,18 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd) result = 0; break; } +#else + isp_prt(isp, ISP_LOGERR, "do not have a kernel map thingie yet"); + result = -EFAULT; +#endif if (result == 0) { ISP_UNLKU_SOFTC(isp); down(&rsem); - cmd->fcd.end.data_residual = Cmnd->resid; + cmd->fcd.end.data_residual = XS_GET_RESID(Cmnd); cmd->fcd.end.status = Cmnd->SCp.Status; if (cmd->fcd.end.status == SCSI_CHECK) { - MEMCPY(cmd->fcd.end.sense_data, Cmnd->sense_buffer, min(sizeof(cmd->fcd.end.sense_data), sizeof (Cmnd->sense_buffer))); + MEMCPY(cmd->fcd.end.sense_data, XS_SNSP(Cmnd), min(sizeof(cmd->fcd.end.sense_data), XS_SNSLEN(Cmnd))); } if (host_byte(Cmnd->result) != DID_OK) { result = -EIO; @@ -1796,191 +920,10 @@ out: if (dev) { isp_kfree(dev, sizeof (struct scsi_device)); } - isp_kfree(Cmnd, sizeof (Scsi_Cmnd)); + isp_kfree(Cmnd, sizeof (struct scsi_cmnd)); return (result); } - -static int -isp_perf_test(ispsoftc_t *isp, isp_perftst_t *tt) -{ - struct scsi_device *dev = NULL; - Scsi_Cmnd *Cmnd = NULL; - fcportdb_t *lp; - struct Scsi_Host *host = NULL; - uint32_t nxti, optr, handle; - uint8_t local[QENTRY_LEN]; - int result = 0, i, iswrite, amt; - void *qep, *qel = local; - DECLARE_MUTEX_LOCKED(rsem); - unsigned long flags; - - if (IS_SCSI(isp)) { - return (-ENODEV); - } - if (tt->target < 0 || tt->target >= MAX_FC_TARG) { - return (-ENODEV); - } - - if (tt->channel < 0 || tt->channel >= isp->isp_nchan) { - return (-ENODEV); - } - - iswrite = 0; - if (tt->ioszdir) { - amt = tt->ioszdir; - if (amt < 0) { - iswrite = 1; - amt = -amt; - } - if (amt > ISP_FC_SCRLEN) { - return (-ENOMEM); - } - } else { - amt = 0; - } - i = FCPARAM(isp, tt->channel)->isp_ini_map[tt->target] - 1; - if (i < 0 || i >= MAX_FC_TARG) { - return (-ENXIO); - } - lp = &FCPARAM(isp, tt->channel)->portdb[i]; - if (lp->state != FC_PORTDB_STATE_VALID) { - return (-ENXIO); - } - - MEMZERO(local, sizeof (local)); - Cmnd = isp_kzalloc(sizeof (Scsi_Cmnd), GFP_KERNEL); - if (Cmnd == NULL) { - return (-ENOMEM); - } - host = isp->isp_osinfo.host; - dev = isp_kzalloc(sizeof (struct scsi_device), GFP_KERNEL); - if (dev == NULL) { - isp_kfree(Cmnd, sizeof (Scsi_Cmnd)); - return (-ENOMEM); - } - - Cmnd->device = dev; - dev->host = host; - Cmnd->scsi_done = isp_run_cmd_done; - Cmnd->request_buffer = &rsem; - Cmnd->cmd_len = 6; - Cmnd->sc_data_direction = SCSI_DATA_NONE; - - if (IS_24XX(isp)) { - ispreqt7_t *t7 = (ispreqt7_t *) local; - - t7->req_header.rqs_entry_type = RQSTYPE_T7RQS; - t7->req_header.rqs_entry_count = 1; - t7->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE; - t7->req_nphdl = lp->handle; - t7->req_tidlo = lp->portid; - t7->req_tidhi = lp->portid >> 16; - if (tt->lun > 256) { - t7->req_lun[0] = tt->lun >> 8; - t7->req_lun[0] |= 0x40; - } - t7->req_lun[1] = tt->lun & 0xff; - t7->req_time = 30; - if (amt) { - t7->req_seg_count = 1; - if (iswrite) { - t7->req_alen_datadir = FCP_CMND_DATA_WRITE; - t7->req_cdb[0] = 0xa; - } else { - t7->req_alen_datadir = FCP_CMND_DATA_READ; - t7->req_cdb[0] = 0x8; - } - t7->req_cdb[4] = amt >> 9; - t7->req_dl = amt; - t7->req_dataseg.ds_base = DMA_LO32(FCPARAM(isp, tt->channel)->isp_scdma); - t7->req_dataseg.ds_basehi = DMA_HI32(FCPARAM(isp, tt->channel)->isp_scdma); - t7->req_dataseg.ds_count = amt; - } else { - t7->req_seg_count = 0; - } - t7->req_vpidx = tt->channel; - } else { - ispreqt3_t *t3 = (ispreqt3_t *) local; - - t3->req_header.rqs_entry_type = RQSTYPE_T3RQS; - t3->req_header.rqs_entry_count = 1; - t3->req_flags = REQFLAG_STAG; - - if (amt) { - if (iswrite) { - t3->req_flags |= REQFLAG_DATA_OUT; - t3->req_cdb[0] = 0xa; - } else { - t3->req_flags |= REQFLAG_DATA_IN; - t3->req_cdb[0] = 0x8; - } - t3->req_cdb[4] = amt >> 9; - t3->req_dataseg[0].ds_base = DMA_LO32(FCPARAM(isp, tt->channel)->isp_scdma); - t3->req_dataseg[0].ds_basehi = DMA_HI32(FCPARAM(isp, tt->channel)->isp_scdma); - t3->req_dataseg[0].ds_count = amt; - t3->req_totalcnt = amt; - } - if (ISP_CAP_2KLOGIN(isp)) { - ((ispreqt3e_t *)t3)->req_target = lp->handle; - ((ispreqt3e_t *)t3)->req_scclun = tt->lun; - } else if (ISP_CAP_SCCFW(isp)) { - t3->req_target = lp->handle; - t3->req_scclun = tt->lun; - } else { - t3->req_target = lp->handle; - t3->req_lun_trn = tt->lun; - } - t3->req_time = 30; - } - - for (i = 0; i < tt->count; i++) { - ISP_LOCKU_SOFTC(isp); - if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) { - ISP_UNLKU_SOFTC(isp); - __set_current_state(TASK_UNINTERRUPTIBLE); - (void) schedule_timeout(1); - i -= 1; - continue; - } - if (i == tt->count - 1) { - if (isp_save_xs(isp, Cmnd, &handle)) { - ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGERR, "out of xflist pointers"); - result = -ENOMEM; - goto out; - } - } else { - handle = ISP_SPCL_HANDLE; - } - ((ispreq_t *)local)->req_handle = handle; - if (IS_24XX(isp)) { - isp_put_request_t7(isp, qel, qep); - } else { - if (ISP_CAP_2KLOGIN(isp)) { - isp_put_request_t2e(isp, qel, qep); - } else { - isp_put_request_t2(isp, qel, qep); - } - } - ISP_ADD_REQUEST(isp, nxti); - if (handle != ISP_SPCL_HANDLE) { - isp->isp_nactive++; - ISP_UNLKU_SOFTC(isp); - down(&rsem); - ISP_LOCKU_SOFTC(isp); - ISP_DMAFREE(isp, Cmnd, handle); - isp_destroy_handle(isp, handle); - } - ISP_UNLKU_SOFTC(isp); - } -out: - if (dev) { - isp_kfree(dev, sizeof (struct scsi_device)); - } - isp_kfree(Cmnd, sizeof (Scsi_Cmnd)); - return (result); -} -#endif /* CONFIG_PROC_FS */ +#endif /* * vim:ts=4:sw=4:expandtab */ diff --git a/qla_isp/linux/isp_ioctl.h b/qla_isp/linux/isp_ioctl.h index 0ea6377d8..8629e4fec 100644 --- a/qla_isp/linux/isp_ioctl.h +++ b/qla_isp/linux/isp_ioctl.h @@ -232,14 +232,6 @@ typedef struct { /* do not recycle 22 */ #define ISP_FC_GETDLIST (ISP_IOC | 23) -/* - * This is a trigger for a performance test. - */ -#define ISP_FC_PERFTST (ISP_IOC | 44) -typedef struct { - uint32_t channel, target, lun, count; - int32_t ioszdir; -} isp_perftst_t; /* * vim:ts=4:sw=4:expandtab */ diff --git a/qla_isp/linux/isp_linux.c b/qla_isp/linux/isp_linux.c index ecdf77b1b..48ac2c937 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.230 2008/04/15 22:41:03 mjacob Exp $ */ +/* $Id: isp_linux.c,v 1.234 2008/08/20 15:50:56 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -313,7 +313,7 @@ isplinux_runwaitq(ispsoftc_t *isp) */ if (IS_FC(isp)) { if (result == CMD_RQLATER && ISP_DATA(isp, XS_CHANNEL(f))->deadloop == 0) { - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, chan), 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, chan), 0, __func__, __LINE__); } } @@ -412,7 +412,6 @@ isplinux_queuecommand(Scsi_Cmnd *Cmnd, void (*donecmd)(Scsi_Cmnd *)) chan = XS_CHANNEL(Cmnd); Cmnd->scsi_done = donecmd; - Cmnd->sense_buffer[0] = 0; ISP_DRIVER_ENTRY_LOCK(isp); ISP_LOCK_SOFTC(isp); @@ -485,7 +484,7 @@ isplinux_queuecommand(Scsi_Cmnd *Cmnd, void (*donecmd)(Scsi_Cmnd *)) */ isplinux_append_to_waitq(isp, Cmnd); if (IS_FC(isp) && ISP_DATA(isp, XS_CHANNEL(Cmnd))->deadloop == 0) { - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, XS_CHANNEL(Cmnd)), 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, XS_CHANNEL(Cmnd)), 0, __func__, __LINE__); } result = 0; } else if (result == CMD_COMPLETE) { @@ -539,13 +538,19 @@ isplinux_scsi_probe_done(Scsi_Cmnd *Cmnd) sdp = SDPARAM(isp, XS_CHANNEL(Cmnd)); if (Cmnd->cmnd[0] == 0x12 && host_byte(Cmnd->result) == DID_OK) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) if (Cmnd->use_sg == 0) { iqd = (caddr_t) Cmnd->request_buffer; } else { - struct scatterlist *sg; - sg = (struct scatterlist *) Cmnd->request_buffer; + struct scatterlist *sg = (struct scatterlist *) Cmnd->request_buffer; iqd = page_address(sg_page(sg)) + sg->offset; } +#else + { + struct scatterlist *sg = scsi_sglist(Cmnd); + iqd = page_address(sg_page(sg)) + sg->offset; + } +#endif sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags &= ~(DPARM_TQING|DPARM_SYNC|DPARM_WIDE); if (iqd[7] & 0x2) { sdp->isp_devparam[XS_TGT(Cmnd)].goal_flags |= DPARM_TQING; @@ -592,8 +597,7 @@ isp_done(Scsi_Cmnd *Cmnd) } } - Cmnd->resid = XS_RESID(Cmnd); - if (Cmnd->underflow > (Cmnd->request_bufflen - Cmnd->resid)) { + if (Cmnd->underflow > (XS_XFRLEN(Cmnd) - XS_GET_RESID(Cmnd))) { XS_SETERR(Cmnd, DID_ERROR); } @@ -956,7 +960,7 @@ isp_tgt_tq(ispsoftc_t *isp) while (tmd != NULL) { tmd_cmd_t *next = tmd->cd_next; tmd->cd_next = NULL; - isp_prt(isp, ISP_LOGTDEBUG2, "isp_tgt_tq[%llx] -> code 0x%x", tmd->cd_tagval, tmd->cd_action); + isp_prt(isp, ISP_LOGTDEBUG2, "isp_tgt_tq[%llx] -> code 0x%x", (ull) tmd->cd_tagval, tmd->cd_action); ISP_PARENT_TARGET(tmd->cd_action, tmd); tmd = next; } @@ -1022,11 +1026,11 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 i = ISP_LOGTINFO; } if (lp->portid == s_id && VALID_INI(lp->port_wwn) && (lp->port_wwn == ini || ini == INI_NONE) && lp->handle == nphdl) { - isp_prt(isp, i, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x reentered", __FUNCTION__, chan, - (unsigned long long) lp->port_wwn, lp->handle, lp->portid); + isp_prt(isp, i, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x reentered", __func__, chan, + (ull) lp->port_wwn, lp->handle, lp->portid); } else { isp_prt(isp, i, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x overwrites IID 0x%016llx N-Port Handle 0x%02x Port Id 0x%06x", - __FUNCTION__, chan, (unsigned long long) ini, nphdl, s_id, (unsigned long long) lp->port_wwn, lp->handle, lp->portid); + __func__, chan, (ull) ini, nphdl, s_id, (ull) lp->port_wwn, lp->handle, lp->portid); } lp->portid = s_id; if (VALID_INI(ini)) { @@ -1048,7 +1052,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 } if (i < 0) { isp_prt(isp, ISP_LOGWARN, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x- no room in port database", - __FUNCTION__, chan, ini, nphdl, s_id); + __func__, chan, (ull) ini, nphdl, s_id); return; } lp = &fcp->portdb[i]; @@ -1058,7 +1062,7 @@ isp_add_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 lp->portid = s_id; lp->port_wwn = ini; isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x added", - __FUNCTION__, chan, (unsigned long long) ini, nphdl, s_id); + __func__, chan, (ull) ini, nphdl, s_id); } static void @@ -1075,7 +1079,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", - __FUNCTION__, chan, (unsigned long long) lp->port_wwn, lp->handle, lp->portid); + __func__, chan, (ull) lp->port_wwn, lp->handle, lp->portid); MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); continue; } @@ -1088,10 +1092,10 @@ isp_del_wwn_entry(ispsoftc_t *isp, int chan, uint64_t ini, uint16_t nphdl, uint3 } if (i == MAX_FC_TARG) { isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cannot be found to be cleared", - __FUNCTION__, chan, (unsigned long long) lp->port_wwn, nphdl, lp->portid); + __func__, chan, (ull) lp->port_wwn, nphdl, lp->portid); } else { isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID 0x%016llx N-Port Handle 0x%x Port ID 0x%06x cleared", - __FUNCTION__, chan, (unsigned long long) lp->port_wwn, nphdl, lp->portid); + __func__, chan, (ull) lp->port_wwn, nphdl, lp->portid); MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t)); } } @@ -1159,7 +1163,7 @@ isp_tgt_dump_pdb(ispsoftc_t *isp, int chan) if (lp->target_mode == 0) { continue; } - isp_prt(isp, ISP_LOGTINFO, "PDB[%d]: Chan %d 0x%016llx Port-ID 0x%06x N-Port Handle 0x%04x", i, chan, (unsigned long long) lp->port_wwn, lp->portid, lp->handle); + isp_prt(isp, ISP_LOGTINFO, "PDB[%d]: Chan %d 0x%016llx Port-ID 0x%06x N-Port Handle 0x%04x", i, chan, (ull) lp->port_wwn, lp->portid, lp->handle); } } @@ -1177,7 +1181,7 @@ isp_taction(qact_e action, void *arg) hp = (hba_register_t *) arg; isp = hp->r_identity; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } isp_prt(isp, ISP_LOGINFO, "completed target registration"); @@ -1257,7 +1261,7 @@ isp_taction(qact_e action, void *arg) ep = arg; isp = ep->en_hba; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } ep->en_error = isp_enable_lun(isp, ep->en_chan, ep->en_lun); @@ -1268,7 +1272,7 @@ isp_taction(qact_e action, void *arg) ep = arg; isp = ep->en_hba; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } ep->en_error = isp_disable_lun(isp, ep->en_chan, ep->en_lun); @@ -1292,21 +1296,21 @@ isp_taction(qact_e action, void *arg) tmd = (tmd_cmd_t *) arg; isp = tmd->cd_hba; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } ISP_LOCK_SOFTC(isp); - isp_prt(isp, ISP_LOGTDEBUG1, "freeing tmd %p [%llx]", tmd, tmd->cd_tagval); + isp_prt(isp, ISP_LOGTDEBUG1, "freeing tmd %p [%llx]", tmd, (ull) tmd->cd_tagval); if (tmd->cd_lflags & CDFL_RESRC_FILL) { if (isp_target_putback_atio(isp, tmd)) { - isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __func__, __LINE__); ISP_UNLK_SOFTC(isp); break; } } if (tmd->cd_lflags & CDFL_NEED_CLNUP) { tmd->cd_lflags &= ~CDFL_NEED_CLNUP; - isp_prt(isp, ISP_LOGTINFO, "Terminating [%llx] on FIN", (unsigned long long) tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "Terminating [%llx] on FIN", (ull) tmd->cd_tagval); (void) isp_terminate_cmd(isp, tmd); } tmd->cd_next = NULL; @@ -1316,7 +1320,7 @@ isp_taction(qact_e action, void *arg) isp->isp_osinfo.tfreelist = tmd; } isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */ - isp_prt(isp, ISP_LOGTDEBUG1, "DONE freeing tmd %p [%llx]", tmd, tmd->cd_tagval); + isp_prt(isp, ISP_LOGTDEBUG1, "DONE freeing tmd %p [%llx]", tmd, (ull) tmd->cd_tagval); ISP_UNLK_SOFTC(isp); break; @@ -1326,7 +1330,7 @@ isp_taction(qact_e action, void *arg) isp = ins->notify.nt_hba; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } ISP_LOCK_SOFTC(isp); @@ -1339,7 +1343,7 @@ isp_taction(qact_e action, void *arg) default: if (isp->isp_state != ISP_RUNSTATE) { isp_prt(isp, ISP_LOGINFO, "[%llx] Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", - ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); + (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) { ct7_entry_t local, *cto = &local; at7_entry_t *aep = (at7_entry_t *)ins->qentry; @@ -1381,7 +1385,7 @@ isp_taction(qact_e action, void *arg) 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", ins->notify.nt_tagval, ins->notify.nt_ncode, ins->qevalid); + 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 { @@ -1399,7 +1403,7 @@ isp_taction(qact_e action, void *arg) hp = (hba_register_t *) arg; isp = hp->r_identity; if (isp == NULL) { - printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); + printk(KERN_ERR "null isp @ %s:%s:%d\n", __FILE__, __func__, __LINE__); break; } isp_prt(isp, ISP_LOGINFO, "completed target unregistration"); @@ -1499,7 +1503,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) * 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", tmd->cd_tagval); + isp_prt(isp, ISP_LOGINFO, "[%llx] already ABORTED- not sending a CTIO", (ull) tmd->cd_tagval); xact->td_error = -ENXIO; goto out; } @@ -1532,7 +1536,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) } if ((xact->td_hflags & TDFH_STSVALID) && tmd->cd_scsi_status == SCSI_CHECK && (xact->td_hflags & TDFH_SNSVALID) && tmd->cd_sense[0] == 0) { - isp_prt(isp, ISP_LOGWARN, "[%llx] cdb0 0x%02x CHECK CONDITION but bogus sense 0x%x/0x%x/0x%x", tmd->cd_tagval, tmd->cd_cdb[0], tmd->cd_sense[0], tmd->cd_sense[12], tmd->cd_sense[13]); + 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); @@ -1617,7 +1621,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); } } - isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7[%llx] scsi sts %x flags %x resid %d offset %u", tmd->cd_tagval, tmd->cd_scsi_status, cto->ct_flags, resid, xact->td_offset); + isp_prt(isp, ISP_LOGTDEBUG0, "CTIO7[%llx] scsi sts %x flags %x resid %d offset %u", (ull) tmd->cd_tagval, tmd->cd_scsi_status, cto->ct_flags, resid, xact->td_offset); } else if (IS_FC(isp)) { ct2_entry_t *cto = (ct2_entry_t *) local; uint16_t *ssptr = NULL; @@ -1685,7 +1689,7 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) if (cto->ct_flags & CT2_SENDSTATUS) { cto->ct_flags |= CT2_CCINCR; } - isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2[%llx] scsi sts %x flags %x resid %d", tmd->cd_tagval, tmd->cd_scsi_status, cto->ct_flags, resid); + isp_prt(isp, ISP_LOGTDEBUG0, "CTIO2[%llx] scsi sts %x flags %x resid %d", (ull) tmd->cd_tagval, tmd->cd_scsi_status, cto->ct_flags, resid); } else { ct_entry_t *cto = (ct_entry_t *) local; @@ -1726,11 +1730,11 @@ isp_target_start_ctio(ispsoftc_t *isp, tmd_xact_t *xact) if (cto->ct_flags & CT_SENDSTATUS) { cto->ct_flags |= CT_CCINCR; } - isp_prt(isp, ISP_LOGTDEBUG0, "CTIO[%llx] scsi sts %x resid %d cd_lflags %x", tmd->cd_tagval, tmd->cd_scsi_status, resid, xact->td_hflags); + isp_prt(isp, ISP_LOGTDEBUG0, "CTIO[%llx] scsi sts %x resid %d cd_lflags %x", (ull) tmd->cd_tagval, tmd->cd_scsi_status, resid, xact->td_hflags); } if (isp_getrqentry(isp, &nxti, &optr, &qe)) { - isp_prt(isp, ISP_LOGWARN, "%s: request queue overflow", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: request queue overflow", __func__); xact->td_error = -ENOMEM; ISP_UNLK_SOFTC(isp); goto out; @@ -1935,7 +1939,7 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep) isp_endcmd(isp, aep, SCSI_BUSY, 0); if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) { isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port"); - isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __func__, __LINE__); } return; } @@ -1966,7 +1970,7 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep) AT_MAKE_TAGID(tmd->cd_tagval, tmd->cd_channel, isp->isp_unit, 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", tmd->cd_tagval, aep->at_cdb[0] & 0xff, + 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, GET_BUS_VAL(aep->at_iid), GET_IID_VAL(aep->at_iid), aep->at_lun, aep->at_tag_type, (aep->at_flags & AT_NODISC)? "nondisc" : "disconnecting"); if (isp->isp_osinfo.hcb == 0) { @@ -2026,7 +2030,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) isp_endcmd(isp, aep, SCSI_BUSY, 0); if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) { isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port"); - isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __func__, __LINE__); } return; } @@ -2107,7 +2111,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) sstr = "BIDIR"; break; } - isp_prt(isp, ISP_LOGALL, "ATIO2[%llx] CDB=0x%x 0x%016llx for lun %d tcode 0x%x dlen %d %s", tmd->cd_tagval, + isp_prt(isp, ISP_LOGALL, "ATIO2[%llx] CDB=0x%x 0x%016llx for lun %d tcode 0x%x dlen %d %s", (ull) tmd->cd_tagval, aep->at_cdb[0] & 0xff, tmd->cd_iid, lun, aep->at_taskcodes, aep->at_datalen, sstr); } @@ -2121,7 +2125,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) } else { tmd->cd_portid = PORT_NONE; isp_add_wwn_entry(isp, 0, tmd->cd_iid, tmd->cd_nphdl, PORT_NONE); - (void) isp_thread_event(isp, ISP_THREAD_FINDPORTID, tmd, 0, __FUNCTION__, __LINE__); + (void) isp_thread_event(isp, ISP_THREAD_FINDPORTID, tmd, 0, __func__, __LINE__); } } } @@ -2175,7 +2179,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) * It's Hackaroni time... */ if ((tmd = isp->isp_osinfo.tfreelist) == NULL || ++aep->at_count == 250) { - isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __FUNCTION__, aep->at_rxid, did); + isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __func__, aep->at_rxid, did); return; } if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) { @@ -2189,7 +2193,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) tmd->cd_lastoff = 1; return; } - isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x", __FUNCTION__, aep->at_rxid, did, chan, sid); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x", __func__, aep->at_rxid, did, chan, sid); if (isp_find_pdb_by_sid(isp, chan, sid, &lp)) { nphdl = lp->handle; @@ -2198,7 +2202,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) /* * If we're not in the port database, do a tentative entry. */ - isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already", __FUNCTION__, aep->at_rxid, did, chan, sid); + isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already", __func__, aep->at_rxid, did, chan, sid); isp_add_wwn_entry(isp, chan, INI_NONE, NIL_HANDLE, sid); } @@ -2221,7 +2225,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) isp_endcmd(isp, aep, chan, SCSI_BUSY, 0); if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) { isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port"); - isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __func__, __LINE__); } return; } @@ -2306,8 +2310,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) sstr = "BIDIR"; break; } - isp_prt(isp, ISP_LOGALL, "ATIO7[%llx] cdb0=0x%x from 0x%016llx/0x%06x ox_id 0x%x N-Port Handle 0x%02x for lun %u dlen %d %s", tmd->cd_tagval, - tmd->cd_cdb[0] & 0xff, (unsigned long long) tmd->cd_iid, tmd->cd_portid, tmd->cd_oxid, tmd->cd_nphdl, lun, tmd->cd_totlen, sstr); + isp_prt(isp, ISP_LOGALL, "ATIO7[%llx] cdb0=0x%x from 0x%016llx/0x%06x ox_id 0x%x N-Port Handle 0x%02x for lun %u dlen %d %s", (ull) tmd->cd_tagval, + tmd->cd_cdb[0] & 0xff, (ull) tmd->cd_iid, tmd->cd_portid, tmd->cd_oxid, tmd->cd_nphdl, lun, tmd->cd_totlen, sstr); } if (isp->isp_osinfo.hcb == 0) { @@ -2317,8 +2321,8 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) if (VALID_INI(tmd->cd_iid)) { CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START); } else { - isp_prt(isp, ISP_LOGTDEBUG0, "[0x%llx] asking taskthread to find iid of initiator", (unsigned long long) tmd->cd_tagval); - if (isp_thread_event(isp, ISP_THREAD_FINDIID, tmd, 0, __FUNCTION__, __LINE__)) { + 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); if (isp->isp_osinfo.tfreelist) { @@ -2340,7 +2344,7 @@ isp_terminate_cmd(ispsoftc_t *isp, tmd_cmd_t *tmd) ct7_entry_t local, *cto = &local; if (IS_24XX(isp)) { - isp_prt(isp, ISP_LOGTINFO, "isp_terminate_cmd: [%llx] is being terminated", (unsigned long long) tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "isp_terminate_cmd: [%llx] is being terminated", (ull) tmd->cd_tagval); MEMZERO(&local, sizeof (local)); cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; cto->ct_header.rqs_entry_count = 1; @@ -2440,7 +2444,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) tmd->cd_moved -= resid; - isp_prt(isp, ISP_LOGTDEBUG0, "%s[%llx] status 0x%x flg 0x%x %s", ctstr, tmd->cd_tagval, status, flags, sentstatus? "FIN" : "MID"); + isp_prt(isp, ISP_LOGTDEBUG0, "%s[%llx] status 0x%x flg 0x%x %s", ctstr, (ull) tmd->cd_tagval, status, flags, sentstatus? "FIN" : "MID"); /* * We're here either because intermediate data transfers are done @@ -2463,14 +2467,15 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) cx = "O"; } if ((status & ~QLTM_SVALID) == CT_ABORTED) { - isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s aborted", tmd->cd_tagval, cx); + isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s aborted", (ull) tmd->cd_tagval, cx); tmd->cd_lflags |= CDFL_ABORTED; } else if ((status & QLTM_SVALID) == CT_LOGOUT) { - isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s killed by Port Logout", tmd->cd_tagval, cx); + isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s killed by Port Logout", (ull) tmd->cd_tagval, cx); } else { - isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s ended with badstate (0x%x)", tmd->cd_tagval, cx, status); + isp_prt(isp, ISP_LOGINFO, "[%llx] CTI%s ended with badstate (0x%x)", (ull) tmd->cd_tagval, cx, status); } xact->td_error = -EIO; + xact->td_lflags |= TDFL_ERROR; if (isp_target_putback_atio(isp, tmd)) { tmd->cd_lflags |= CDFL_RESRC_FILL; } @@ -2489,7 +2494,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) continue; } } - isp_thread_event(isp, ISP_THREAD_LOGOUT, &FCPARAM(isp, tmd->cd_channel)->portdb[i], 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_LOGOUT, &FCPARAM(isp, tmd->cd_channel)->portdb[i], 0, __func__, __LINE__); break; } } @@ -2509,10 +2514,10 @@ isp_target_putback_atio(ispsoftc_t *isp, tmd_cmd_t *tmd) return (0); } if (isp_getrqentry(isp, &nxti, NULL, &qe)) { - isp_prt(isp, ISP_LOGWARN, "%s: Request Queue Overflow", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: Request Queue Overflow", __func__); return (-ENOMEM); } - isp_prt(isp, ISP_LOGTDEBUG0, "[%llx] resource putback being sent", tmd->cd_tagval); + isp_prt(isp, ISP_LOGTDEBUG0, "[%llx] resource putback being sent", (ull) tmd->cd_tagval); MEMZERO(local, sizeof (local)); if (IS_FC(isp)) { at2_entry_t *at = (at2_entry_t *) local; @@ -2579,7 +2584,7 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) return (0); } if (chan >= isp->isp_nchan) { - isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __FUNCTION__, chan); + isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan); return (-ENXIO); } fcp = FCPARAM(isp, chan); @@ -2648,7 +2653,7 @@ isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role) FC_SCRATCH_RELEASE(isp, chan); if (vp->vp_mod_status != VP_STS_OK) { - isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of Chan %d failed with status %d", __FUNCTION__, chan, vp->vp_mod_status); + isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of Chan %d failed with status %d", __func__, chan, vp->vp_mod_status); ISP_DATA(isp, chan)->blocked = 0; return (-EIO); } @@ -2707,7 +2712,7 @@ isp_enable_lun(ispsoftc_t *isp, uint16_t bus, uint16_t lun) * first in some kind of role. */ if (IS_FC(isp) && bus != 0 && (((FCPARAM(isp, 0)->role & ISP_ROLE_TARGET) && nolunsenabled(isp, 0)) || (FCPARAM(isp, 0)->role == ISP_ROLE_NONE))) { - isp_prt(isp, ISP_LOGWARN, "%s: must enable Chan 0 before Chan %u", __FUNCTION__, bus); + isp_prt(isp, ISP_LOGWARN, "%s: must enable Chan 0 before Chan %u", __func__, bus); up(&isp->isp_osinfo.tgt_inisem); isp_kfree(axl, sizeof (tgt_enalun_t)); return (-EINVAL); @@ -2871,7 +2876,7 @@ isp_disable_lun(ispsoftc_t *isp, uint16_t bus, uint16_t lun) } } if (rstat > 0) { - isp_prt(isp, ISP_LOGERR, "%s: must disable Chan %u before Chan 0\n", __FUNCTION__, rstat); + isp_prt(isp, ISP_LOGERR, "%s: must disable Chan %u before Chan 0\n", __func__, rstat); ISP_UNLK_SOFTC(isp); up(&isp->isp_osinfo.tgt_inisem); return (-EINVAL); @@ -2941,7 +2946,7 @@ out: if (axl) { isp_kfree(axl, sizeof (tgt_enalun_t)); } else { - isp_prt(isp, ISP_LOGWARN, "%s: Chan %d lun %u unable to find axl to delete", __FUNCTION__, bus, lun); + isp_prt(isp, ISP_LOGWARN, "%s: Chan %d lun %u unable to find axl to delete", __func__, bus, lun); } if (rstat != LUN_OK) { isp_prt(isp, ISP_LOGERR, "lun %u disable failed", lun); @@ -3119,11 +3124,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (lp->ini_map_idx) { unsigned long arg; tgt = lp->ini_map_idx - 1; - isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, lp->node_wwn, lp->port_wwn); + 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, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__); } else { - isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", lp->node_wwn, lp->port_wwn); + isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", (ull) lp->node_wwn, (ull) lp->port_wwn); } break; case ISPASYNC_DEV_CHANGED: @@ -3138,9 +3143,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) int t = lp->ini_map_idx - 1; fcp->isp_ini_map[t] = (lp - fcp->portdb) + 1; tgt = lp->ini_map_idx - 1; - isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "changed at", tgt, lp->node_wwn, lp->port_wwn); + 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", lp->node_wwn, lp->port_wwn); + 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); } break; case ISPASYNC_DEV_STAYED: @@ -3150,9 +3155,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) va_end(ap); if (lp->ini_map_idx) { tgt = lp->ini_map_idx - 1; - isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "stayed at", tgt, lp->node_wwn, lp->port_wwn); + 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", lp->node_wwn, lp->port_wwn); + 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); } break; case ISPASYNC_DEV_GONE: @@ -3167,11 +3172,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) fcp->isp_ini_map[tgt] = 0; lp->state = FC_PORTDB_STATE_NIL; lp->ini_map_idx = 0; - isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, lp->node_wwn, lp->port_wwn); + 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, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __func__, __LINE__); } else if (lp->reserved == 0) { - isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", lp->node_wwn, lp->port_wwn); + isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", (ull) lp->node_wwn, (ull) lp->port_wwn); } break; case ISPASYNC_CHANGE_NOTIFY: @@ -3203,7 +3208,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) isp_prt(isp, ISP_LOGINFO, "Chan %d Other Change Notify occurred", bus); } if (isp->isp_state >= ISP_INITSTATE) { - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __func__, __LINE__); } break; } @@ -3311,8 +3316,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) 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, (unsigned long long) mp->nt_iid, (unsigned long long) mp->nt_tgt, - mp->nt_lun, mp->nt_tagval); + mp->nt_ncode, (ull) mp->nt_iid, (ull) mp->nt_tgt, mp->nt_lun, mp->nt_tagval); CALL_PARENT_NOTIFY(isp, ins); break; } @@ -3421,14 +3425,14 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) 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", (unsigned long long) tmd->cd_tagval); + 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; } } } - isp_prt(isp, ISP_LOGTINFO, "ABTS [%llx] from 0x%016llx", ins->notify.nt_tagval, ins->notify.nt_iid); + isp_prt(isp, ISP_LOGTINFO, "ABTS [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); CALL_PARENT_NOTIFY(isp, ins); break; } @@ -3471,7 +3475,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) IN_MAKE_TAGID(ins->notify.nt_tagval, GET_BUS_VAL(inot->in_iid), isp->isp_unit, 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", ins->notify.nt_tagval, + 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); CALL_PARENT_NOTIFY(isp, ins); break; @@ -3543,7 +3547,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) break; case PDISC: isp_prt(isp, ISP_LOGTINFO, "%s: Chan %d IID N-Port Handle 0x%x Port ID 0x%06x PDISC", - __FUNCTION__, inot->in_vpindex, nphdl, portid); + __func__, inot->in_vpindex, nphdl, portid); break; default: isp_prt(isp, ISP_LOGTINFO, "ELS CODE 0x%x Received from 0x%06x", inot->in_status_subcode, portid); @@ -3581,11 +3585,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) 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", - __FUNCTION__, inot->in_vpindex, status, (unsigned long long) ins->notify.nt_iid, nphdl); + __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", - ins->notify.nt_tagval, ins->notify.nt_iid); + (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); CALL_PARENT_NOTIFY(isp, ins); break; @@ -3647,8 +3651,8 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) ins->notify.nt_need_ack = 1; IN_FC_MAKE_TAGID(ins->notify.nt_tagval, 0, isp->isp_unit, seqid); ins->notify.nt_ncode = NT_ABORT_TASK; - isp_prt(isp, ISP_LOGINFO, "ABORT TASK [%llx] from 0x%016llx to lun %u", ins->notify.nt_tagval, - (unsigned long long) ins->notify.nt_iid, lun); + 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); CALL_PARENT_NOTIFY(isp, ins); break; } else if (status == IN_PORT_LOGOUT) { @@ -3658,10 +3662,10 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (isp_find_pdb_by_loopid(isp, 0, nphdl, &lp)) { ins->notify.nt_iid = 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", __FUNCTION__, (unsigned long long)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_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", ins->notify.nt_tagval, (unsigned long long) ins->notify.nt_iid); + isp_prt(isp, ISP_LOGINFO, "PORT LOGOUT [%llx] from 0x%016llx", (ull) ins->notify.nt_tagval, (ull) ins->notify.nt_iid); ins->notify.nt_need_ack = 1; CALL_PARENT_NOTIFY(isp, ins); break; @@ -3688,14 +3692,14 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) /* * Everyone Logged Out */ - isp_prt(isp, ISP_LOGTINFO, "%s: isp_del_wwn called for everyone due to GLOBAL PORT_LOGOUT", __FUNCTION__); + 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_ncode = NT_LOGOUT; ins->notify.nt_need_ack = 1; CALL_PARENT_NOTIFY(isp, ins); } else { - isp_prt(isp, ISP_LOGINFO, "%s: ACKing unknown status 0x%x", __FUNCTION__, status); + isp_prt(isp, ISP_LOGINFO, "%s: ACKing unknown status 0x%x", __func__, status); isp_notify_ack(isp, qe); } } @@ -3721,7 +3725,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) ISP_DATA(isp, mbox6)->blocked = 1; ISP_RESET0(isp); isp_shutdown(isp); - isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __func__, __LINE__); break; } case ISPASYNC_FW_RESTARTED: @@ -3729,7 +3733,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) if (IS_FC(isp)) { int i; for (i = 0; i < isp->isp_nchan; i++) { - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __func__, __LINE__); } } break; @@ -3917,7 +3921,7 @@ isplinux_timer(unsigned long arg) 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; - isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __func__, __LINE__); } } } @@ -3935,9 +3939,9 @@ isplinux_timer(unsigned long arg) isp->isp_osinfo.waiting_t = wt->cd_next; wt->cd_next = NULL; if (wt->cd_lastoff == 0) { - isp_thread_event(isp, ISP_THREAD_FINDIID, wt, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FINDIID, wt, 0, __func__, __LINE__); } else { - isp_thread_event(isp, ISP_THREAD_RESTART_AT7, wt, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_RESTART_AT7, wt, 0, __func__, __LINE__); } } } @@ -3973,7 +3977,7 @@ isplinux_mbtimer(unsigned long arg) ISP_IUNLK_SOFTC(isp); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) #define PTARG , struct pt_regs *pt #else #define PTARG @@ -4509,15 +4513,21 @@ isp_task_thread(void *arg) break; case ISP_THREAD_SCSI_SCAN: { - /* this gets pegged in isplinux_queuecommand, even for async scanning */ -#if 0 unsigned long arg = (unsigned long) tap->arg; int tgt, chan, rescan; tgt = arg & 0xffff; chan = (arg >> 16) & 0xff; rescan = (arg >> 31) & 1; - scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, SCAN_WILD_CARD, rescan); -#endif + if (rescan == 0) { + scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, 0, rescan); + } else { + struct scsi_device *sdev; + sdev = scsi_device_lookup(isp->isp_osinfo.host, 0, tgt, 0); + if (sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } + } break; } case ISP_THREAD_REINIT: @@ -4593,7 +4603,7 @@ isp_task_thread(void *arg) MEMZERO(&u, sizeof (u)); u.id = lp->handle; isp_prt(isp, ISP_LOGTINFO, "Doing Port Logout repair for 0x%016llx@0x%x (loop id) %u", - lp->port_wwn, lp->portid, lp->handle); + (ull) lp->port_wwn, lp->portid, lp->handle); MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_FABRIC_LOGOUT; if (ISP_CAP_2KLOGIN(isp)) { @@ -4639,8 +4649,8 @@ isp_task_thread(void *arg) uint16_t nphdl = NIL_HANDLE; if (tmd->cd_lflags & CDFL_ABORTED) { - isp_prt(isp, ISP_LOGTINFO, "[%llx] asking thread to terminate because it was marked aborted", (unsigned long long) tmd->cd_tagval); - isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__); + isp_prt(isp, ISP_LOGTINFO, "[%llx] asking thread to terminate because it was marked aborted", (ull) tmd->cd_tagval); + isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __func__, __LINE__); break; } ISP_LOCKU_SOFTC(isp); @@ -4662,7 +4672,7 @@ isp_task_thread(void *arg) if (isp_control(isp, ISPCTL_GET_PDB, tmd->cd_channel, nphdl, &pdb)) { continue; } - isp_prt(isp, ISP_LOGTINFO, "%s: nphdl 0x%04x has portid 0x%06x", __FUNCTION__, nphdl, pdb.portid); + isp_prt(isp, ISP_LOGTINFO, "%s: nphdl 0x%04x has portid 0x%06x", __func__, nphdl, pdb.portid); if (pdb.portid == tmd->cd_portid) { lp->handle = nphdl; break; @@ -4670,9 +4680,9 @@ isp_task_thread(void *arg) } if (nphdl == max) { ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because because we can't find the N-Port handle", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff); + isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because because we can't find the N-Port handle", (ull) tmd->cd_tagval, tmd->cd_cdb[0] & 0xff); isp_tgt_dump_pdb(isp, tmd->cd_channel); - isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __func__, __LINE__); break; } } @@ -4680,7 +4690,7 @@ isp_task_thread(void *arg) nphdl = lp->handle; iid = lp->port_wwn; } else { - isp_prt(isp, ISP_LOGALL, "%s: Chan %d [0x%llx] failed to get name for handle 0x%02x for portid 0x%06x", __FUNCTION__, tmd->cd_channel, tmd->cd_tagval, lp->handle, tmd->cd_portid); + isp_prt(isp, ISP_LOGALL, "%s: Chan %d [0x%llx] failed to get name for handle 0x%02x for portid 0x%06x", __func__, tmd->cd_channel, (ull) tmd->cd_tagval, lp->handle, tmd->cd_portid); } } else { nphdl = lp->handle; @@ -4692,13 +4702,13 @@ isp_task_thread(void *arg) * has cleared it out. The command is probably already dead due to initiator port logout. */ ISP_UNLKU_SOFTC(isp); - isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because PortID 0x%06x no longer in port database", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_portid); + isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because PortID 0x%06x no longer in port database", (ull) tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_portid); isp_tgt_dump_pdb(isp, tmd->cd_channel); - isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __func__, __LINE__); break; } if (iid == INI_NONE) { - isp_prt(isp, ISP_LOGTDEBUG0, "%s: [0x%llx] trying to find IID again...", __FUNCTION__, tmd->cd_tagval); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: [0x%llx] trying to find IID again...", __func__, (ull) tmd->cd_tagval); tmd->cd_next = isp->isp_osinfo.waiting_t; isp->isp_osinfo.waiting_t = tmd; tmd->cd_lastoff = 0; @@ -4708,8 +4718,8 @@ isp_task_thread(void *arg) tmd->cd_tgt = FCPARAM(isp, tmd->cd_channel)->isp_wwpn; tmd->cd_nphdl = nphdl; tmd->cd_iid = iid; - isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__, - tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid); + isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __func__, + (ull) tmd->cd_tagval, tmd->cd_channel, (ull)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid); CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START); ISP_UNLKU_SOFTC(isp); isp_tgt_tq(isp); @@ -4731,11 +4741,11 @@ isp_task_thread(void *arg) tmd->cd_portid = lp->portid; } } else { - isp_prt(isp, ISP_LOGTINFO, "[0x%llx] not in port database at all any more", tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "[0x%llx] not in port database at all any more", (ull) tmd->cd_tagval); } if (tmd->cd_portid != PORT_NONE) { - isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__, - tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid); + isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __func__, + (ull) tmd->cd_tagval, tmd->cd_channel, (ull)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid); } CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START); ISP_UNLKU_SOFTC(isp); @@ -4754,14 +4764,14 @@ 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), (unsigned long long) tmd->cd_tagval); + isp_prt(isp, ISP_LOGINFO, "Chan %d [%llx] reprieved", (int) AT2_GET_BUS(tmd->cd_tagval), (ull) tmd->cd_tagval); break; } - isp_prt(isp, ISP_LOGTINFO, "%s now terminating [%llx] from 0x%06x", __FUNCTION__, (unsigned long long) tmd->cd_tagval, tmd->cd_portid); + isp_prt(isp, ISP_LOGTINFO, "%s now terminating [%llx] from 0x%06x", __func__, (ull) tmd->cd_tagval, tmd->cd_portid); if (isp_terminate_cmd(isp, tmd)) { ISP_UNLKU_SOFTC(isp); - isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __func__, __LINE__); break; } tmd->cd_next = NULL; @@ -4795,15 +4805,15 @@ isp_task_thread(void *arg) { tmd_cmd_t *tmd = tap->arg; ISP_LOCKU_SOFTC(isp); - isp_prt(isp, ISP_LOGTINFO, "%s: [%llx] calling putback", __FUNCTION__, tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "%s: [%llx] calling putback", __func__, (ull) tmd->cd_tagval); if (isp_target_putback_atio(isp, tmd)) { ISP_UNLKU_SOFTC(isp); - isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__); + isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __func__, __LINE__); break; } if (tmd->cd_lflags & CDFL_NEED_CLNUP) { tmd->cd_lflags ^= CDFL_NEED_CLNUP; - isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (unsigned long long) tmd->cd_tagval); + isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (ull) tmd->cd_tagval); (void) isp_terminate_cmd(isp, tmd); } MEMZERO(tmd, sizeof (tmd_cmd_t)); @@ -4813,7 +4823,7 @@ isp_task_thread(void *arg) isp->isp_osinfo.tfreelist = tmd; } isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */ - isp_prt(isp, ISP_LOGTDEBUG0, "DONE freeing tmd %p [%llx] after retry", tmd, tmd->cd_tagval); + isp_prt(isp, ISP_LOGTDEBUG0, "DONE freeing tmd %p [%llx] after retry", tmd, (ull) tmd->cd_tagval); ISP_UNLKU_SOFTC(isp); break; } diff --git a/qla_isp/linux/isp_linux.h b/qla_isp/linux/isp_linux.h index 490762737..ed4b1e48a 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.161 2008/04/15 22:41:03 mjacob Exp $ */ +/* $Id: isp_linux.h,v 1.164 2008/08/20 15:50:56 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -59,15 +59,6 @@ #ifndef _ISP_LINUX_H #define _ISP_LINUX_H -//#define DISABLE_FW_LOADER 1 -//#define ISP_DISABLE_1080_SUPPORT 1 -//#define ISP_DISABLE_12160_SUPPORT 1 -//#define ISP_DISABLE_2100_SUPPORT 1 -//#define ISP_DISABLE_2200_SUPPORT 1 -//#define ISP_DISABLE_2300_SUPPORT 1 -//#define ISP_DISABLE_2322_SUPPORT 1 -//#define ISP_DISABLE_2400_SUPPORT 1 - #ifndef ISP_MODULE #define __NO_VERSION__ #endif @@ -80,14 +71,10 @@ #define KERNEL_VERSION(v,p,s) (((v)<<16)+(p<<8)+s) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 7, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,7,0) #error "Only Linux 2.5/2.6 kernels are supported with this driver" #endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24) -#error "Linux kernels newer than 2.6.24 are not supported with this driver" -#endif - #ifndef UNUSED_PARAMETER #define UNUSED_PARAMETER(x) (void) x #endif @@ -126,24 +113,34 @@ #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) #include #define ISP_CLASS struct class_simple #define CREATE_ISP_CLASS class_simple_create #define DESTROY_ISP_CLASS class_simple_destroy + #define CREATE_ISP_DEV(isp, class) \ class_simple_device_add(class, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit), \ devfs_mk_cdev(MKDEV(MAJOR(isp_dev), isp->isp_unit), S_IFCHR | S_IRUGO | S_IWUGO, "%s%d", ISP_NAME, isp->isp_unit) #define DESTROY_ISP_DEV(isp) \ devfs_remove("%s%d", ISP_NAME, isp->isp_unit), class_simple_device_remove(MKDEV(MAJOR(isp_dev), isp->isp_unit)) -#else -#define ISP_CLASS struct class -#define CREATE_ISP_CLASS class_create -#define DESTROY_ISP_CLASS class_destroy + +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define ISP_CLASS struct class +#define CREATE_ISP_CLASS class_create +#define DESTROY_ISP_CLASS class_destroy + #define CREATE_ISP_DEV(isp, class) \ class_device_create(class, NULL, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit) #define DESTROY_ISP_DEV(isp) \ class_device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (isp)->isp_unit)); + +#else +#define ISP_CLASS struct class +#define CREATE_ISP_CLASS class_create +#define DESTROY_ISP_CLASS class_destroy +#define CREATE_ISP_DEV(i, c) (void) device_create(c, NULL, MKDEV(MAJOR(isp_dev), (i)->isp_unit), "%s%d", ISP_NAME, (i)->isp_unit); +#define DESTROY_ISP_DEV(i) device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (i)->isp_unit)); #endif typedef struct scsi_cmnd Scsi_Cmnd; @@ -163,7 +160,7 @@ typedef struct scsi_host_template Scsi_Host_Template; #endif #define ISP_PLATFORM_VERSION_MAJOR 6 -#define ISP_PLATFORM_VERSION_MINOR 0 +#define ISP_PLATFORM_VERSION_MINOR 1 #ifndef ISP_NAME #define ISP_NAME "isp" @@ -201,9 +198,11 @@ typedef struct scsi_host_template Scsi_Host_Template; #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) -#define sg_page(_sg) ((_sg)->page) -#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg)) +#define ull unsigned long long + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#define sg_page(_sg) ((_sg)->page) +#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg)) #endif /* @@ -399,8 +398,8 @@ struct isposinfo { #define ISP_IUNLK_SOFTC ISP_UNLK_SOFTC #define ISP_IGET_LK_SOFTC(isp) spin_lock_irq(&isp->isp_osinfo.slock) #define ISP_DROP_LK_SOFTC(isp) spin_unlock_irq(&isp->isp_osinfo.slock) -#define ISP_LOCK_SCSI_DONE(isp) do { } while (0) -#define ISP_UNLK_SCSI_DONE(isp) do { } while (0) +#define ISP_LOCK_SCSI_DONE(isp) do { } while(0) +#define ISP_UNLK_SCSI_DONE(isp) do { } while(0) #define ISP_LOCKU_SOFTC ISP_ILOCK_SOFTC #define ISP_UNLKU_SOFTC ISP_IUNLK_SOFTC #define ISP_TLOCK_INIT(isp) spin_lock_init(&isp->isp_osinfo.tlock) @@ -498,13 +497,20 @@ struct isposinfo { #define XS_ISP(Cmnd) ((ispsoftc_t *)XS_HOST(Cmnd)->hostdata) #define XS_CDBP(Cmnd) (Cmnd)->cmnd #define XS_CDBLEN(Cmnd) (Cmnd)->cmd_len -#define XS_XFRLEN(Cmnd) (Cmnd)->request_bufflen +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +#define XS_GET_RESID(Cmnd) (Cmnd)->SCp.this_residual +#define XS_SET_RESID(Cmnd, resid) (Cmnd)->SCp.this_residual = resid +#define XS_XFRLEN(Cmnd) (Cmnd)->request_bufflen +#else +#define XS_GET_RESID scsi_get_resid +#define XS_SET_RESID scsi_set_resid +#define XS_XFRLEN scsi_bufflen +#endif #define XS_TIME(Cmnd) ((((Cmnd)->timeout_per_command) * HZ)*1000) -#define XS_RESID(Cmnd) (Cmnd)->SCp.this_residual #define XS_STSP(Cmnd) (&(Cmnd)->SCp.Status) #define XS_SNSP(Cmnd) (Cmnd)->sense_buffer -#define XS_SNSLEN(Cmnd) (sizeof (Cmnd)->sense_buffer) -#define XS_SNSKEY(Cmnd) ((Cmnd)->sense_buffer[2] & 0xf) +#define XS_SNSLEN(Cmnd) SCSI_SENSE_BUFFERSIZE +#define XS_SNSKEY(Cmnd) (XS_SNSP(Cmnd)[2] & 0xf) #define XS_TAG_P(Cmnd) (Cmnd->device->tagged_supported != 0) #define XS_TAG_TYPE isplinux_tagtype @@ -532,8 +538,7 @@ struct isposinfo { #define XS_INITERR(xs) (xs)->result = 0, (xs)->SCp.Status = 0 -#define XS_SAVE_SENSE(Cmnd, s, l) \ - MEMCPY(&Cmnd->sense_buffer, s, min(sizeof Cmnd->sense_buffer, 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) @@ -632,7 +637,7 @@ typedef struct { */ void isplinux_timer(unsigned long); void isplinux_mbtimer(unsigned long); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) irqreturn_t isplinux_intr(int, void *, struct pt_regs *); #else irqreturn_t isplinux_intr(int, void *); diff --git a/qla_isp/linux/isp_pci.c b/qla_isp/linux/isp_pci.c index dfbb1cfaa..0342ff2ba 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.168 2008/04/15 22:41:03 mjacob Exp $ */ +/* $Id: isp_pci.c,v 1.172 2008/08/20 15:50:56 mjacob Exp $ */ /* * Copyright (c) 1997-2008 by Matthew Jacob * All rights reserved. @@ -87,7 +87,7 @@ static int isp_pci_mbxdma(ispsoftc_t *); static int isp_pci_dmasetup(ispsoftc_t *, XS_T *, ispreq_t *, uint32_t *, uint32_t); static void isp_pci_dmateardown(ispsoftc_t *, XS_T *, uint32_t); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6) #define DMA_64BIT_MASK 0xffffffffffffffffULL #define DMA_32BIT_MASK 0x00000000ffffffffULL #endif @@ -99,7 +99,7 @@ static void isp_pci_dmateardown(ispsoftc_t *, XS_T *, uint32_t); #define SAME_4G(addr, cnt) (FOURG_SEG(addr) == FOURG_SEG(addr + cnt - 1)) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) #define ISP_IRQ_FLAGS SA_INTERRUPT | SA_SHIRQ #else #define ISP_IRQ_FLAGS IRQF_SHARED @@ -365,11 +365,11 @@ struct isp_pcisoftc { msix_enabled : 2, msi_enabled : 1; }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) #define pci_enable_msi(x) -ENXIO #define pci_enable_msix(x) -ENXIO -#define pci_disable_msi(x) do { ; } while (0) -#define pci_disable_msix(x) do { ; } while (0) +#define pci_disable_msi(x) do { ; } while(0) +#define pci_disable_msix(x) do { ; } while(0) #endif /* @@ -506,7 +506,7 @@ isplinux_pci_release(struct Scsi_Host *host) } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 7) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) /** * pci_intx - enables/disables PCI INTx for device dev * @pdev: the PCI device to operate on @@ -619,7 +619,7 @@ isplinux_pci_init_one(struct Scsi_Host *host) return (1); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 7) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7) if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) { struct msix_entry isp_msix[3]; int reg; @@ -669,7 +669,7 @@ isplinux_pci_init_one(struct Scsi_Host *host) pci_write_config_word(pdev, reg + PCI_EXP_DEVCTL, pectl); } } else -#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) if (pci_enable_msi(pdev) == 0) { isp_pci->msi_enabled = 1; } @@ -945,7 +945,7 @@ bad: isp_kfree(isp->isp_osinfo.storep, isp->isp_osinfo.storep_amt); isp->isp_osinfo.storep = NULL; } -#if !defined(DISABLE_FW_LOADER) && (defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)) +#ifdef CONFIG_FW_LOADER if (isp->isp_osinfo.fwp) { release_firmware(isp->isp_osinfo.fwp); isp->isp_osinfo.fwp = NULL; @@ -1677,7 +1677,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin resid = (int32_t) xact->td_xfrlen; while (resid > 0) { if (sg->length == 0) { - isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __FUNCTION__, nseg, tmd->cd_tagval); + isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __func__, nseg, tmd->cd_tagval); cto->ct_resid = -EINVAL; return (CMD_COMPLETE); } @@ -1690,7 +1690,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg, (cto->ct_flags & CT_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (new_seg_cnt == 0) { - isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); cto->ct_resid = -ENOMEM; return (CMD_COMPLETE); } @@ -1759,7 +1759,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin * pretty unlikely to ever be used. */ if (ISP_A64 && IS_HIGH_ISP_ADDR(addr)) { - isp_prt(isp, ISP_LOGERR, "%s: 64 bit tgt mode not supported", __FUNCTION__); + isp_prt(isp, ISP_LOGERR, "%s: 64 bit tgt mode not supported", __func__); cto->ct_resid = -EFAULT; pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT_DATA_IN)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE); return (CMD_COMPLETE); @@ -1779,7 +1779,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin * sending an extra CTIO with final status. */ if (send_status == 0) { - isp_prt(isp, ISP_LOGERR, "%s: ran out of segments, no status to send", __FUNCTION__); + isp_prt(isp, ISP_LOGERR, "%s: ran out of segments, no status to send", __func__); return (CMD_EAGAIN); } } @@ -1831,7 +1831,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin qe = (ct_entry_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti); nxti = ISP_NXT_QENTRY(nxti, RQUEST_QUEUE_LEN(isp)); if (nxti == optr) { - isp_prt(isp, ISP_LOGERR, "%s: request queue overflow", __FUNCTION__); + isp_prt(isp, ISP_LOGERR, "%s: request queue overflow", __func__); return (CMD_EAGAIN); } @@ -1979,7 +1979,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti xfcnt = xact->td_xfrlen; while (xfcnt > 0) { if (sg->length == 0) { - isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __FUNCTION__, nseg, tmd->cd_tagval); + isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __func__, nseg, tmd->cd_tagval); cto->ct_resid = -EINVAL; return (CMD_COMPLETE); } @@ -1990,7 +1990,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti sg = xact->td_data; 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", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); cto->ct_resid = -ENOMEM; return (CMD_COMPLETE); } @@ -2000,7 +2000,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti * Check for sequential ordering of data frames */ if (tmd->cd_lastoff + tmd->cd_lastsize != xact->td_offset) { - isp_prt(isp, ISP_LOGWARN, "%s: [0x%llx] lastoff %u lastsize %u but curoff %u (totlen %u)", __FUNCTION__, (unsigned long long) tmd->cd_tagval, tmd->cd_lastoff, tmd->cd_lastsize, xact->td_offset, tmd->cd_totlen); + isp_prt(isp, ISP_LOGWARN, "%s: [0x%llx] lastoff %u lastsize %u but curoff %u (totlen %u)", __func__, (unsigned long long) tmd->cd_tagval, tmd->cd_lastoff, tmd->cd_lastsize, xact->td_offset, tmd->cd_totlen); } tmd->cd_lastsize = xact->td_xfrlen; tmd->cd_lastoff = xact->td_offset; @@ -2074,7 +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", __FUNCTION__, seg, + 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); } cto->rsp.m0.ct_xfrlen += bc; @@ -2099,7 +2099,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti 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); - isp_prt(isp, ISP_LOGTDEBUG0, "%s: out of space for continuations (%d of %d segs done)", __FUNCTION__, cto->ct_seg_count, nseg); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: out of space for continuations (%d of %d segs done)", __func__, cto->ct_seg_count, nseg); return (CMD_EAGAIN); } cto->ct_header.rqs_entry_count++; @@ -2120,7 +2120,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti addr = sg_dma_address(sg); bc = min(sg_dma_len(sg), xfcnt); } - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __FUNCTION__, cto->ct_header.rqs_entry_count-1, ovseg, (unsigned long long) addr, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __func__, cto->ct_header.rqs_entry_count-1, ovseg, (unsigned long long) addr, bc); cto->ct_seg_count++; cto->rsp.m0.ct_xfrlen += bc; @@ -2177,7 +2177,7 @@ mbxsync: nxti = ISP_NXT_QENTRY(curi, RQUEST_QUEUE_LEN(isp)); 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", __FUNCTION__); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__); cto->ct_resid = -EAGAIN; return (CMD_COMPLETE); } @@ -2300,7 +2300,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, xfcnt = xact->td_xfrlen; while (xfcnt > 0) { if (sg->length == 0) { - isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __FUNCTION__, nseg, tmd->cd_tagval); + isp_prt(isp, ISP_LOGWARN, "%s: zero length segment #%d for tag %llx\n", __func__, nseg, tmd->cd_tagval); cto->ct_resid = -EINVAL; return (CMD_COMPLETE); } @@ -2311,7 +2311,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip, sg = xact->td_data; 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", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); cto->ct_resid = -ENOMEM; return (CMD_COMPLETE); } @@ -2413,12 +2413,12 @@ again: cto->rsp.m0.ct_xfrlen = 0; sg = xact->td_data; seglim = ISP_RQDSEG_T3; - isp_prt(isp, ISP_LOGTDEBUG2, "%s: found hi page", __FUNCTION__); + isp_prt(isp, ISP_LOGTDEBUG2, "%s: found hi page", __func__); goto again; } cto->rsp.m0.u.ct_dataseg[seg].ds_base = LOWD(addr); cto->rsp.m0.u.ct_dataseg[seg].ds_count = bc; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%x:%u", __FUNCTION__, seg, cto->rsp.m0.u.ct_dataseg[seg].ds_base, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%x:%u", __func__, seg, cto->rsp.m0.u.ct_dataseg[seg].ds_base, bc); } else { cto->rsp.m0.u.ct_dataseg64[seg].ds_base = LOWD(addr); cto->rsp.m0.u.ct_dataseg64[seg].ds_basehi = HIWD(addr); @@ -2439,12 +2439,12 @@ again: cto->rsp.m0.u.ct_dataseg64[seg].ds_count = bc; cto->rsp.m0.u.ct_dataseg64[seg].ds_base = LOWD(addr); cto->rsp.m0.u.ct_dataseg64[seg].ds_basehi = HIWD(addr); - isp_prt(isp, ISP_LOGALL, "%s: seg0[%d]%lx%08lx:%u", __FUNCTION__, seg, + isp_prt(isp, ISP_LOGALL, "%s: seg0[%d]%lx%08lx:%u", __func__, seg, (unsigned long)cto->rsp.m0.u.ct_dataseg64[seg].ds_basehi, (unsigned long)cto->rsp.m0.u.ct_dataseg64[seg].ds_base, bc); } } else { cto->rsp.m0.u.ct_dataseg64[seg].ds_count = bc; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __FUNCTION__, seg, + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __func__, seg, (unsigned long)cto->rsp.m0.u.ct_dataseg64[seg].ds_basehi, (unsigned long)cto->rsp.m0.u.ct_dataseg64[seg].ds_base, bc); } } @@ -2452,12 +2452,12 @@ again: if (seglim == ISP_RQDSEG_T2) { cto->rsp.m0.u.ct_dataseg[seg].ds_base = addr; cto->rsp.m0.u.ct_dataseg[seg].ds_count = bc; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%x:%u", __FUNCTION__, seg, cto->rsp.m0.u.ct_dataseg[seg].ds_base, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%x:%u", __func__, seg, cto->rsp.m0.u.ct_dataseg[seg].ds_base, bc); } else { cto->rsp.m0.u.ct_dataseg64[seg].ds_base = addr; cto->rsp.m0.u.ct_dataseg64[seg].ds_basehi = 0; cto->rsp.m0.u.ct_dataseg64[seg].ds_count = bc; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx:%u", __FUNCTION__, seg, (unsigned long) cto->rsp.m0.u.ct_dataseg64[seg].ds_base, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx:%u", __func__, seg, (unsigned long) cto->rsp.m0.u.ct_dataseg64[seg].ds_base, bc); } #endif cto->rsp.m0.ct_xfrlen += bc; @@ -2483,7 +2483,7 @@ again: 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); - isp_prt(isp, ISP_LOGTDEBUG0, "%s: out of space for continuations (%d of %d segs done)", __FUNCTION__, cto->ct_seg_count, nseg); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: out of space for continuations (%d of %d segs done)", __func__, cto->ct_seg_count, nseg); return (CMD_EAGAIN); } cto->ct_header.rqs_entry_count++; @@ -2508,7 +2508,7 @@ again: addr = sg_dma_address(sg); bc = min(sg_dma_len(sg), xfcnt); } - isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __FUNCTION__, cto->ct_header.rqs_entry_count-1, ovseg, (unsigned long long) addr, bc); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __func__, cto->ct_header.rqs_entry_count-1, ovseg, (unsigned long long) addr, bc); cto->ct_seg_count++; cto->rsp.m0.ct_xfrlen += bc; @@ -2561,7 +2561,7 @@ again: cto->rsp.m0.ct_xfrlen = 0; sg = xact->td_data; seglim = ISP_RQDSEG_T3; - isp_prt(isp, ISP_LOGTDEBUG1, "%s: found hi page in continuation, restarting", __FUNCTION__); + isp_prt(isp, ISP_LOGTDEBUG1, "%s: found hi page in continuation, restarting", __func__); goto again; } crq->req_dataseg[ovseg].ds_count = bc; @@ -2593,7 +2593,7 @@ mbxsync: nxti = ISP_NXT_QENTRY(curi, 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); - isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __FUNCTION__); + isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__); cto->ct_resid = -EAGAIN; return (CMD_COMPLETE); } @@ -2617,8 +2617,13 @@ static int isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq, uint32_t *nxi, uint32_t optr) { struct scatterlist *sg, *savesg; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) XS_DMA_ADDR_T one_shot_addr, last_synthetic_addr; unsigned int one_shot_length, last_synthetic_count; +#else + XS_DMA_ADDR_T last_synthetic_addr; + unsigned int last_synthetic_count; +#endif int segcnt, seg, ovseg, seglim; void *h; uint32_t nxti; @@ -2638,24 +2643,24 @@ isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq, uint32_t *nxi, nxti = *nxi; h = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); - if (Cmnd->sc_data_direction == SCSI_DATA_NONE || Cmnd->request_bufflen == 0) { + if (Cmnd->sc_data_direction == SCSI_DATA_NONE || XS_XFRLEN(Cmnd) == 0) { rq->req_seg_count = 1; goto mbxsync; } - if (Cmnd->request_bufflen <= 1024) { + if (XS_XFRLEN(Cmnd) <= 1024) { seg = 0; - } else if (Cmnd->request_bufflen <= 4096) { + } else if (XS_XFRLEN(Cmnd) <= 4096) { seg = 1; - } else if (Cmnd->request_bufflen <= 32768) { + } else if (XS_XFRLEN(Cmnd) <= 32768) { seg = 2; - } else if (Cmnd->request_bufflen <= 65536) { + } else if (XS_XFRLEN(Cmnd) <= 65536) { seg = 3; - } else if (Cmnd->request_bufflen <= 131372) { + } else if (XS_XFRLEN(Cmnd) <= 131372) { seg = 4; - } else if (Cmnd->request_bufflen <= 262144) { + } else if (XS_XFRLEN(Cmnd) <= 262144) { seg = 5; - } else if (Cmnd->request_bufflen <= 524288) { + } else if (XS_XFRLEN(Cmnd) <= 524288) { seg = 6; } else { seg = 7; @@ -2664,14 +2669,14 @@ isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq, uint32_t *nxi, if (IS_FC(isp)) { seglim = ISP_RQDSEG_T2; - ((ispreqt2_t *)rq)->req_totalcnt = Cmnd->request_bufflen; + ((ispreqt2_t *)rq)->req_totalcnt = XS_XFRLEN(Cmnd); if (Cmnd->sc_data_direction == SCSI_DATA_WRITE) { ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_OUT; } else if (Cmnd->sc_data_direction == SCSI_DATA_READ) { ((ispreqt2_t *)rq)->req_flags |= REQFLAG_DATA_IN; } else { - isp_prt(isp, ISP_LOGERR, "%s: unkown data direction (%x) for %d byte request (opcode 0x%x)", __FUNCTION__, - Cmnd->sc_data_direction, Cmnd->request_bufflen, Cmnd->cmnd[0]); + isp_prt(isp, ISP_LOGERR, "%s: unkown data direction (%x) for %d byte request (opcode 0x%x)", __func__, + Cmnd->sc_data_direction, XS_XFRLEN(Cmnd), Cmnd->cmnd[0]); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_COMPLETE); } @@ -2686,21 +2691,22 @@ isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq, uint32_t *nxi, } else if (Cmnd->sc_data_direction == SCSI_DATA_READ) { rq->req_flags |= REQFLAG_DATA_IN; } else { - isp_prt(isp, ISP_LOGERR, "%s: unkown data direction (%x) for %d byte request (opcode 0x%x)", __FUNCTION__, - Cmnd->sc_data_direction, Cmnd->request_bufflen, Cmnd->cmnd[0]); + isp_prt(isp, ISP_LOGERR, "%s: unkown data direction (%x) for %d byte request (opcode 0x%x)", __func__, + Cmnd->sc_data_direction, XS_XFRLEN(Cmnd), Cmnd->cmnd[0]); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_COMPLETE); } } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) one_shot_addr = (XS_DMA_ADDR_T) 0; one_shot_length = 0; if ((segcnt = Cmnd->use_sg) == 0) { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; segcnt = 1; sg = NULL; - one_shot_length = Cmnd->request_bufflen; - one_shot_addr = pci_map_single(pcs->pci_dev, Cmnd->request_buffer, Cmnd->request_bufflen, scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); + one_shot_length = XS_XFRLEN(Cmnd); + one_shot_addr = pci_map_single(pcs->pci_dev, Cmnd->request_buffer, XS_XFRLEN(Cmnd), scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); QLA_HANDLE(Cmnd) = (DMA_HTYPE_T) one_shot_addr; } else { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; @@ -2708,10 +2714,19 @@ isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *rq, uint32_t *nxi, segcnt = pci_map_sg(pcs->pci_dev, sg, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); } if (segcnt == 0) { - isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __FUNCTION__); + isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_COMPLETE); } +#else + segcnt = scsi_dma_map(Cmnd); + if (segcnt <= 0) { + isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__); + XS_SETERR(Cmnd, HBA_BOTCH); + return (CMD_COMPLETE); + } + sg = scsi_sglist(Cmnd); +#endif savesg = sg; again: @@ -2721,6 +2736,7 @@ again: XS_DMA_ADDR_T addr; unsigned int length; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) if (sg) { length = sg_dma_len(sg); addr = sg_dma_address(sg); @@ -2729,6 +2745,11 @@ again: length = one_shot_length; addr = one_shot_addr; } +#else + length = sg_dma_len(sg); + addr = sg_dma_address(sg); + sg++; +#endif if (ISP_A64 && IS_HIGH_ISP_ADDR(addr)) { if (IS_FC(isp)) { @@ -2845,7 +2866,7 @@ again: nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp)); if (nxti == optr) { isp_pci_dmateardown(isp, Cmnd, 0); - isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __FUNCTION__, XS_CHANNEL(Cmnd), seg, segcnt); + isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __func__, XS_CHANNEL(Cmnd), seg, segcnt); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_EAGAIN); } @@ -2969,8 +2990,13 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 { struct scatterlist *sg, *savesg; ispreqt7_t *rq; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) XS_DMA_ADDR_T addr, one_shot_addr, last_synthetic_addr; unsigned int one_shot_length, last_synthetic_count, length; +#else + XS_DMA_ADDR_T addr, last_synthetic_addr; + unsigned int last_synthetic_count, length; +#endif int segcnt, seg, ovseg; void *h; uint32_t nxti; @@ -2984,31 +3010,31 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 nxti = *nxi; h = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx); - if (Cmnd->sc_data_direction == SCSI_DATA_NONE || Cmnd->request_bufflen == 0) { + if (Cmnd->sc_data_direction == SCSI_DATA_NONE || XS_XFRLEN(Cmnd) == 0) { rq->req_seg_count = 0; goto mbxsync; } - if (Cmnd->request_bufflen <= 1024) { + if (XS_XFRLEN(Cmnd) <= 1024) { seg = 0; - } else if (Cmnd->request_bufflen <= 4096) { + } else if (XS_XFRLEN(Cmnd) <= 4096) { seg = 1; - } else if (Cmnd->request_bufflen <= 32768) { + } else if (XS_XFRLEN(Cmnd) <= 32768) { seg = 2; - } else if (Cmnd->request_bufflen <= 65536) { + } else if (XS_XFRLEN(Cmnd) <= 65536) { seg = 3; - } else if (Cmnd->request_bufflen <= 131372) { + } else if (XS_XFRLEN(Cmnd) <= 131372) { seg = 4; - } else if (Cmnd->request_bufflen <= 262144) { + } else if (XS_XFRLEN(Cmnd) <= 262144) { seg = 5; - } else if (Cmnd->request_bufflen <= 524288) { + } else if (XS_XFRLEN(Cmnd) <= 524288) { seg = 6; } else { seg = 7; } isp->isp_osinfo.bins[seg]++; - rq->req_dl = Cmnd->request_bufflen; + rq->req_dl = XS_XFRLEN(Cmnd); rq->req_seg_count = 1; if (Cmnd->sc_data_direction == SCSI_DATA_WRITE) { rq->req_alen_datadir = FCP_CMND_DATA_WRITE; @@ -3016,19 +3042,20 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 rq->req_alen_datadir = FCP_CMND_DATA_READ; } else { isp_prt(isp, ISP_LOGERR, "unknown data direction (%x) for %d byte request (opcode 0x%x)", - Cmnd->sc_data_direction, Cmnd->request_bufflen, Cmnd->cmnd[0]); + Cmnd->sc_data_direction, XS_XFRLEN(Cmnd), Cmnd->cmnd[0]); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_COMPLETE); } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) one_shot_addr = (XS_DMA_ADDR_T) 0; one_shot_length = 0; if ((segcnt = Cmnd->use_sg) == 0) { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; segcnt = 1; sg = NULL; - one_shot_length = Cmnd->request_bufflen; - one_shot_addr = pci_map_single(pcs->pci_dev, Cmnd->request_buffer, Cmnd->request_bufflen, scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); + one_shot_length = XS_XFRLEN(Cmnd); + one_shot_addr = pci_map_single(pcs->pci_dev, Cmnd->request_buffer, XS_XFRLEN(Cmnd), scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); QLA_HANDLE(Cmnd) = (DMA_HTYPE_T) one_shot_addr; } else { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; @@ -3041,12 +3068,22 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_EAGAIN); } +#else + segcnt = scsi_dma_map(Cmnd); + if (segcnt <= 0) { + isp_prt(isp, ISP_LOGWARN, "unable to dma map request"); + XS_SETERR(Cmnd, HBA_BOTCH); + return (CMD_EAGAIN); + } + sg = scsi_sglist(Cmnd); +#endif savesg = sg; last_synthetic_count = 0; last_synthetic_addr = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) if (sg) { length = sg_dma_len(sg); addr = sg_dma_address(sg); @@ -3055,6 +3092,11 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 length = one_shot_length; addr = one_shot_addr; } +#else + length = sg_dma_len(sg); + addr = sg_dma_address(sg); + sg++; +#endif seg = 1; rq->req_dataseg.ds_base = LOWD(addr); @@ -3088,7 +3130,7 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3 nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp)); if (nxti == optr) { isp_pci_dmateardown(isp, Cmnd, 0); - isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __FUNCTION__, XS_CHANNEL(Cmnd), seg, segcnt); + isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __func__, XS_CHANNEL(Cmnd), seg, segcnt); XS_SETERR(Cmnd, HBA_BOTCH); return (CMD_EAGAIN); } @@ -3162,13 +3204,13 @@ mbxsync: static void isp_pci_dmateardown(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, uint32_t handle) { - struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; #ifdef ISP_TARGET_MODE /* * The argument passed may not be a Cmnd pointer- this is the * safest way to keep the two w/o redoing our internal apis. */ if (IS_TARGET_HANDLE(handle)) { + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; tmd_xact_t *xact = (tmd_xact_t *) Cmnd; tmd_cmd_t *tmd = xact? xact->td_cmd : NULL; int nseg = tmd? tmd->cd_nseg : 0; @@ -3179,12 +3221,17 @@ isp_pci_dmateardown(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, uint32_t handle) } else #endif if (Cmnd->sc_data_direction != SCSI_DATA_NONE) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) + struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp; if (Cmnd->use_sg) { pci_unmap_sg(pcs->pci_dev, (struct scatterlist *)Cmnd->request_buffer, Cmnd->use_sg, scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); - } else if (Cmnd->request_bufflen) { + } else if (XS_XFRLEN(Cmnd)) { XS_DMA_ADDR_T dhandle = (XS_DMA_ADDR_T) QLA_HANDLE(Cmnd); - pci_unmap_single(pcs->pci_dev, dhandle, Cmnd->request_bufflen, scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); + pci_unmap_single(pcs->pci_dev, dhandle, XS_XFRLEN(Cmnd), scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); } +#else + scsi_dma_unmap(Cmnd); +#endif } } @@ -3468,7 +3515,7 @@ isplinux_pci_remove(struct pci_dev *pdev) isp_deinit_target(isp); #endif scsi_host_put(host); -#if !defined(DISABLE_FW_LOADER) && (defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)) +#ifdef CONFIG_FW_LOADER if (isp->isp_osinfo.fwp) { release_firmware(isp->isp_osinfo.fwp); isp->isp_osinfo.fwp = NULL; @@ -3479,7 +3526,7 @@ isplinux_pci_remove(struct pci_dev *pdev) static struct pci_driver isplinux_pci_driver = { .name = ISP_NAME, -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 9) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) .driver = { .owner = THIS_MODULE, }, @@ -3497,12 +3544,12 @@ isplinux_pci_init(void) printk(KERN_INFO "Feral Software QLogic SCSI/FC Driver built on %s %s\n", __DATE__, __TIME__); ret = alloc_chrdev_region(&isp_dev, 0, MAX_ISP, ISP_NAME); if (ret) { - printk(KERN_ERR "%s: cannot allocate chrdev region\n", __FUNCTION__); + printk(KERN_ERR "%s: cannot allocate chrdev region\n", __func__); return (ret); } cdev_init(&isp_cdev, &isp_ioctl_operations); if (cdev_add(&isp_cdev, isp_dev, MAX_ISP)) { - printk(KERN_ERR "%s: cannot add cdev\n", __FUNCTION__); + printk(KERN_ERR "%s: cannot add cdev\n", __func__); kobject_put(&isp_cdev.kobj); unregister_chrdev_region(isp_dev, MAX_ISP); return (-EIO); @@ -3516,7 +3563,7 @@ isplinux_pci_init(void) } ret = pci_register_driver(&isplinux_pci_driver); if (ret < 0) { - printk(KERN_ERR "%s: unable to register driver (return value %d)", __FUNCTION__, ret); + printk(KERN_ERR "%s: unable to register driver (return value %d)", __func__, ret); unregister_chrdev_region(isp_dev, MAX_ISP); return (ret); } diff --git a/qla_isp/linux/isp_scst.c b/qla_isp/linux/isp_scst.c index 286ae9831..5864a75d5 100644 --- a/qla_isp/linux/isp_scst.c +++ b/qla_isp/linux/isp_scst.c @@ -1295,7 +1295,7 @@ isp_write_proc(struct file *file, const char __user *buf, size_t len, loff_t *of enum { DISABLE = 0, ENABLE = 1, TEST } action; int en = -1, res = -EINVAL; int all_channels = 0, all_luns = 0; - int lun, chan; + int lun = 0, chan = 0; bus_t *bp = PDE(file->f_dentry->d_inode)->data; if (bp == NULL || bp->bchan == NULL) { diff --git a/qla_isp/linux/scsi_target.c b/qla_isp/linux/scsi_target.c deleted file mode 100644 index fad4f2138..000000000 --- a/qla_isp/linux/scsi_target.c +++ /dev/null @@ -1,2549 +0,0 @@ -/* $Id: scsi_target.c,v 1.84 2008/04/15 22:41:03 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 - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - */ -/* - * SCSI Target Mode "toy disk" target device for Linux. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef min -#undef min -#endif -#define min(a,b) (((a)<(b))?(a):(b)) -#ifndef roundup -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) -#endif - -#ifndef DECLARE_MUTEX_LOCKED -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) -#define sg_page(_sg) ((_sg)->page) -#define sg_assign_page(_sg, _pg) ((_sg)->page = (_pg)) -#endif - -#include "isp_tpublic.h" -#include "linux/smp_lock.h" - -#define DEFAULT_DEVICE_TYPE 0 /* DISK */ -#define MAX_BUS 8 -#define MAX_LUN 64 -#define N_SENSE_BUFS 256 - -#define cd_dp cd_hreserved[0].ptrs[0] -#define cd_nsgelems cd_hreserved[1].longs[0] -#define cd_off cd_hreserved[2].llongs[0] -#define cd_next cd_hreserved[3].ptrs[0] - -#define CDF_PRIVATE_0 0x8000 /* small (non page) data allocation */ -#define CDF_PRIVATE_1 0x4000 /* page allocation attached */ -#define CDF_PRIVATE_2 0x2000 /* sent status already */ -#define CDF_PRIVATE_3 0x1000 /* sg list from sg element cache */ -#ifndef SCSI_GOOD -#define SCSI_GOOD 0x0 -#endif -#ifndef SCSI_BUSY -#define SCSI_BUSY 0x8 -#endif -#ifndef SCSI_CHECK -#define SCSI_CHECK 0x2 -#endif -#ifndef SCSI_QFULL -#define SCSI_QFULL 0x28 -#endif - -#ifndef SERVICE_ACTION_IN -#define SERVICE_ACTION_IN 0x9e -#endif -#ifndef SAI_READ_CAPACITY_16 -#define SAI_READ_CAPACITY_16 0x10 -#endif -#ifndef READ_12 -#define READ_12 0xa8 -#endif -#ifndef READ_16 -#define READ_16 0x88 -#endif -#ifndef WRITE_12 -#define WRITE_12 0xaa -#endif -#ifndef WRITE_16 -#define WRITE_16 0x8a -#endif -#ifndef REPORT_LUNS -#define REPORT_LUNS 0xa0 -#endif - -#define MODE_ALL_PAGES 0x3f -#define MODE_VU_PAGE 0x00 -#define MODE_RWER 0x01 -#define MODE_DISCO_RECO 0x02 -#define MODE_FORMAT_DEVICE 0x03 -#define MODE_GEOMETRY 0x04 -#define MODE_CACHE 0x08 -#define MODE_PERIPH 0x09 -#define MODE_CONTROL 0x0A - -#define MODE_DBD 0x08 - -#define MODE_PF 0x08 -#define MODE_SP 0x01 - -#define MODE_PGCTL_MASK 0xC0 -#define MODE_PGCTL_CURRENT 0x00 -#define MODE_PGCTL_CHANGEABLE 0x40 -#define MODE_PGCTL_DEFAULT 0x80 -#define MODE_PGCTL_SAVED 0xC0 - -#define PSEUDO_SPT 64 /* sectors per track */ -#define PSEUDO_HDS 64 /* number of heads */ -#define PSEUDO_SPC (PSEUDO_SPT * PSEUDO_HDS) - -/* - * Size to allocate both a scatterlist + payload for small allocations - */ -#define SGS_SIZE 1024 -#define SGS0 (roundup(sizeof (struct scatterlist), sizeof (void *))) -#define SGS_PAYLOAD_SIZE (SGS_SIZE - SGS0) -#define SGS_SGP(x) ((struct scatterlist *)&((u8 *)(x))[SGS_PAYLOAD_SIZE]) -#define COPYIN(uarg, karg, amt) copy_from_user(karg, uarg, amt) -#define COPYOUT(karg, uarg, amt) copy_to_user(uarg, karg, amt) - -static __inline void * scsi_target_kalloc(size_t, int); -static __inline void scsi_target_kfree(void *, size_t); -static __inline void * scsi_target_kzalloc(size_t, int); - -static __inline void * -scsi_target_kalloc(size_t size, int flags) -{ - void *ptr; - if (size > PAGE_SIZE) { - ptr = vmalloc(size); - } else { - ptr = kmalloc(size, flags); - } - return (ptr); -} - -static __inline void -scsi_target_kfree(void *ptr, size_t size) -{ - if (size > PAGE_SIZE) { - vfree(ptr); - } else { - kfree(ptr); - } -} - -static __inline void * -scsi_target_kzalloc(size_t size, int flags) -{ - void *ptr = scsi_target_kalloc(size, flags); - if (ptr != NULL){ - memset(ptr, 0, size); - } - return (ptr); -} - -static __inline void init_sg_elem(struct scatterlist *, struct page *, int, void *, size_t); - -static __inline void -init_sg_elem(struct scatterlist *sgp, struct page *p, int offset, void *addr, size_t length) -{ - sgp->length = length; - if (p) { - sg_assign_page(sgp, p); - sgp->offset = offset; - } else { - sg_assign_page(sgp, virt_to_page(addr)); - sgp->offset = offset_in_page(addr); - } -} - -#include "scsi_target.h" - - -#ifndef SERNO -#define SERNO "000000" -#endif - -typedef struct bus bus_t; -typedef struct initiator ini_t; -typedef struct sdata sdata_t; - -struct sdata { - sdata_t *next; - uint8_t sdata[TMD_SENSELEN]; -}; - - -struct initiator { - ini_t * ini_next; - bus_t * ini_bus; /* backpointer to containing bus */ - sdata_t * ini_sdata; /* pending sense data list */ - sdata_t * ini_sdata_tail; /* pending sense data list, tail */ - uint64_t ini_iid; /* initiator identifier */ -}; - -#define HASH_WIDTH 16 -#define INI_HASH_LISTP(busp, chan, ini_id) busp->bchan[chan].list[ini_id & (HASH_WIDTH - 1)] - -/* - * We maintain a reasonable cache of large sized (8MB) scatterlists - */ -#define SGELEM_CACHE_SIZE 2048 -#define SGELEM_CACHE_COUNT 128 -static struct scatterlist *sg_cache = NULL; - - -/* - * A memory disk is constructed of a two dimensional array of pointers to pages. - * - * Allocate a series of chunks of memory, each of which becomes a flat array - * of pointers to pages that we allocate one at a time. - */ -#define PGLIST_SIZE (32 << 10) /* how big each list is, in bytes */ -#define PG_PER_LIST (PGLIST_SIZE / sizeof (struct page *)) /* how many page pointers fist into that list */ -#define PGLIST_MAPPING_SIZE (PG_PER_LIST << PAGE_SHIFT) /* how many bytes each list covers */ -#define START_LIST_IDX(x) ((x) / PGLIST_MAPPING_SIZE) -#define START_PAGE_IDX(x) (((x) % PGLIST_MAPPING_SIZE) >> PAGE_SHIFT) - -/* - * An overcommit disk is a cache of a fixed size. - */ -#define OC_SIZE (64 << 20) -#define NextPage(pp) pp->private -#define NextPageType unsigned long - -typedef struct { - struct page *** pagelists; - int npglists; - int : 28, - outtagas : 1, - wce : 1, - overcommit : 1, - enabled : 1; - wait_queue_head_t whook; - tmd_cmd_t * u_front; - tmd_cmd_t * u_tail; - uint64_t nbytes; -} lun_t; -#define LUN_BLOCK_SHIFT 9 - -struct bus_chan { - ini_t * list[HASH_WIDTH]; /* hash list of known initiators */ - lun_t luns[MAX_LUN]; /* per-channel lun arrays */ -}; - -struct bus { - hba_register_t h; /* must be first */ - struct bus_chan *bchan; -}; - -#define SDprintk if (scsi_tdebug) printk -#define SDprintk2 if (scsi_tdebug > 1) printk -#define SDprintk3 if (scsi_tdebug > 2) printk - - -static int scsi_tdebug = 0; - -static int -scsi_target_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static void scsi_target_handler(qact_e, void *); - -static __inline bus_t *bus_from_tmd(tmd_cmd_t *); -static __inline bus_t *bus_from_name(char *); -static __inline ini_t *ini_from_tmd(bus_t *, tmd_cmd_t *); - -static void add_sdata(ini_t *, void *); -static void rem_sdata(ini_t *); -static void free_sdata_chain(sdata_t *); -static void scsi_target_start_cmd(tmd_cmd_t *, int); -static void scsi_target_read_capacity_16(tmd_cmd_t *, ini_t *); -static void scsi_target_read_capacity(tmd_cmd_t *, ini_t *); -static void scsi_target_modesense(tmd_cmd_t *, ini_t *); -static int scsi_target_rdwr(tmd_cmd_t *, ini_t *, int); -static int scsi_target_thread(void *); -static int scsi_alloc_disk(bus_t *, int, int, int, uint64_t); -static void scsi_free_disk(bus_t *, int, int); -static int scsi_target_copydata(struct scatterlist *, void *, uint32_t, int); -static int scsi_target_start_user_io(sc_io_t *); -static int scsi_target_end_user_io(sc_io_t *); -static int scsi_target_endis(char *, uint64_t, int, int, int); - -/* - * Local Declarations - */ -#define INQ_SIZE 36 -static uint8_t inqdata[INQ_SIZE] = { - DEFAULT_DEVICE_TYPE, 0x0, 0x2, 0x2, 32, 0, 0, 0x32, - 'L', 'I', 'N', 'U', 'X', ' ', ' ', ' ', - 'S', 'C', 'S', 'I', ' ', 'M', 'E', 'M', - 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K', - '0', '0', '0', '1' -}; -static uint8_t vp0data[7] = { - DEFAULT_DEVICE_TYPE, 0, 0, 0x3, 0, 0x80, 0x83 -}; -static uint8_t vp80data[36] = { - DEFAULT_DEVICE_TYPE, 0x80, 0, 0x20, -}; -/* Binary, Associated with Target Port, FC-FS Identifier */ -static uint8_t vp83data[18] = { - DEFAULT_DEVICE_TYPE, 0x83, 0, 0xc, 0x01, 0x13, 0, 0x8 -}; -static uint8_t enomem[TMD_SENSELEN] = { - 0xf0, 0, 0x4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x55, 0x03 -}; -static uint8_t illfld[TMD_SENSELEN] = { - 0xf0, 0, 0x5, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x24 -}; -static uint8_t nolun[TMD_SENSELEN] = { - 0xf0, 0, 0x5, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x25 -}; -static uint8_t invfld[TMD_SENSELEN] = { - 0xf0, 0, 0x5, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x26 -}; -#if 0 -static uint8_t notrdy[TMD_SENSELEN] = { - 0xf0, 0, 0x2, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x04 -}; -#endif -static uint8_t mediaerr[TMD_SENSELEN] = { - 0xf0, 0, 0x3 -}; -static uint8_t ifailure[TMD_SENSELEN] = { - 0xf0, 0, 0x4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x44 -}; -static uint8_t ua[TMD_SENSELEN] = { - 0xf0, 0, 0x6, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x29, 0x1 -}; -static uint8_t nosense[TMD_SENSELEN] = { - 0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; -static uint8_t invchg[TMD_SENSELEN] = { - 0xf0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3f, 0x0e -}; -static uint8_t parity[TMD_SENSELEN] = { - 0xf0, 0, 0xb, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0x47, 0x02 -}; - -static bus_t busses[MAX_BUS]; -static sdata_t *sdp = NULL; - -DECLARE_MUTEX_LOCKED(scsi_thread_sleep_semaphore); -DECLARE_MUTEX_LOCKED(scsi_thread_entry_exit_semaphore); -static tmd_cmd_t *p_front = NULL, *p_last = NULL; -static tmd_cmd_t *q_front = NULL, *q_last = NULL; -static tmd_cmd_t *r_front = NULL, *r_last = NULL; -static DEFINE_SPINLOCK(scsi_target_lock); -static int scsi_target_thread_exit = 0; - -static struct file_operations scsi_target_fops = { - .ioctl = scsi_target_ioctl, - .owner = THIS_MODULE, -}; - -static __inline int -validate_bus_pointer(bus_t *bp, void *identity) -{ - if (bp >= busses && bp < &busses[MAX_BUS]) { - if (bp->h.r_action) { - if (bp->h.r_identity == identity) { - return (1); - } - } - } - return (0); -} - -static __inline bus_t * -bus_from_tmd(tmd_cmd_t *tmd) -{ - bus_t *bp; - for (bp = busses; bp < &busses[MAX_BUS]; bp++) { - if (validate_bus_pointer(bp, tmd->cd_hba)) { - return (bp); - } - } - return (NULL); -} - -static __inline bus_t * -bus_from_name(char *name) -{ - bus_t *bp; - for (bp = busses; bp < &busses[MAX_BUS]; bp++) { - char localbuf[32]; - if (bp->h.r_action == NULL) { - continue; - } - snprintf(localbuf, sizeof (localbuf), "%s%d", bp->h.r_name, bp->h.r_inst); - if (strncmp(name, localbuf, sizeof (localbuf) - 1) == 0) { - return (bp); - } - } - return (NULL); -} - -static __inline ini_t * -ini_from_tmd(bus_t *bp, tmd_cmd_t *tmd) -{ - ini_t *ptr = INI_HASH_LISTP(bp, tmd->cd_channel, tmd->cd_iid); - if (ptr) { - do { - if (ptr->ini_iid == tmd->cd_iid) { - return (ptr); - } - } while ((ptr = ptr->ini_next) != NULL); - } - return (ptr); -} - -static __inline bus_t * -bus_from_notify(tmd_notify_t *np) -{ - bus_t *bp; - for (bp = busses; bp < &busses[MAX_BUS]; bp++) { - if (bp->h.r_action == NULL) { - continue; - } - if (bp->h.r_identity == np->nt_hba) { - return (bp); - } - } - return (NULL); -} - -static int -scsi_target_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) -{ - int rv = 0; - - switch (cmd) { - case SC_ENABLE_LUN: - case SC_DISABLE_LUN: - { - sc_enable_t local, *sc = &local; - if (COPYIN((void *)arg, (void *)sc, sizeof (*sc))) { - rv = -EFAULT; - break; - } - rv = scsi_target_endis(sc->hba_name_unit, sc->nbytes, sc->channel, sc->lun, (cmd == SC_ENABLE_LUN)? ((sc->flags & SC_EF_OVERCOMMIT)? 2 : 1) : 0); - break; - } - case SC_PUT_IO: - case SC_GET_IO: - { - sc_io_t sc; - - if (COPYIN((void *)arg, (void *)&sc, sizeof (sc))) { - rv = -EFAULT; - break; - } - if (cmd == SC_PUT_IO) { - rv = scsi_target_end_user_io(&sc); - } else { - rv = scsi_target_start_user_io(&sc); - } - if (COPYOUT((void *)&sc, (void *)arg, sizeof (sc))) { - if (rv == 0) { - rv = EFAULT; - } - } - break; - } - case SC_DEBUG: - { - int odebug = scsi_tdebug; - if (COPYIN((void *)arg, (void *)&scsi_tdebug, sizeof (int))) { - rv = EFAULT; - break; - } - if (COPYOUT((void *)&odebug, (void *)arg, sizeof (int))) { - rv = EFAULT; - break; - } - break; - } - case SC_INJECT_UA: - { - sc_inject_ua_t local, *sc = &local; - bus_t *bp; - struct bus_chan *bc; - unsigned long flags; - int i, n; - - if (COPYIN((void *)arg, (void *)sc, sizeof (sc))) { - rv = -EFAULT; - break; - } - spin_lock_irqsave(&scsi_target_lock, flags); - bp = bus_from_name(sc->hba_name_unit); - if (bp == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - rv = -ENXIO; - break; - } - for (rv = n = 0; n < bp->h.r_nchannels && rv == 0; n++) { - bc = &bp->bchan[n]; - for (i = 0; i < HASH_WIDTH && rv == 0; i++) { - ini_t *ini; - for (ini = bc->list[i]; ini; ini = ini->ini_next) { - sdata_t *t = sdp; - if (t == NULL) { - rv = -ENOMEM; - break; - } - sdp = t->next; - t->next = NULL; - memcpy(t->sdata, ua, sizeof (ua)); - if (ini->ini_sdata == NULL) { - ini->ini_sdata = t; - } else { - ini->ini_sdata_tail->next = t; - } - ini->ini_sdata_tail = t; - } - } - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - break; - } - default: - rv = -EINVAL; - break; - } - return (rv); -} - -/* - * Make an initiator structure - */ -static void -add_ini(bus_t *bp, int chan, uint64_t iid, ini_t *nptr) -{ - ini_t **ptrlptr = &INI_HASH_LISTP(bp, chan, iid); - - nptr->ini_iid = iid; - nptr->ini_bus = (struct bus *) bp; - nptr->ini_next = *ptrlptr; - - *ptrlptr = nptr; -} - -/* - * Add this sense data from the list of - * sense data structures for this initiator. - * We always add to the tail of the list. - */ -static void -add_sdata(ini_t *ini, void *sd) -{ - unsigned long flags; - sdata_t *t; - - spin_lock_irqsave(&scsi_target_lock, flags); - t = sdp; - if (t == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk(KERN_WARNING "outta sense data structures\n"); - t = scsi_target_kalloc(sizeof (sdata_t), GFP_KERNEL|GFP_ATOMIC); - if (t == NULL) { - panic("REALLY outta sense data structures\n"); - } - spin_lock_irqsave(&scsi_target_lock, flags); - } else { - sdp = t->next; - } - t->next = NULL; - memcpy(t->sdata, sd, sizeof (t->sdata)); - if (ini->ini_sdata == NULL) { - ini->ini_sdata = t; - } else { - ini->ini_sdata_tail->next = t; - } - ini->ini_sdata_tail = t; - spin_unlock_irqrestore(&scsi_target_lock, flags); -} - -/* - * Remove one sense data item from the list of - * sense data structures for this initiator. - */ -static void -rem_sdata(ini_t *ini) -{ - sdata_t *t = ini->ini_sdata; - if (t) { - unsigned long flags; - spin_lock_irqsave(&scsi_target_lock, flags); - if ((ini->ini_sdata = t->next) == NULL) { - ini->ini_sdata_tail = NULL; - } - t->next = sdp; - sdp = t; - spin_unlock_irqrestore(&scsi_target_lock, flags); - } -} - -static void -free_sdata_chain(sdata_t *sdp) -{ - while (sdp) { - sdata_t *nxt = sdp->next; - scsi_target_kfree(sdp, sizeof (*sdp)); - sdp = nxt; - } -} - - -static __inline void scsi_cmd_sched_restart_locked(tmd_cmd_t *, int, const char *); -static __inline void scsi_cmd_sched_restart(tmd_cmd_t *, const char *); - -static __inline void -scsi_cmd_sched_restart_locked(tmd_cmd_t *tmd, int donotify, const char *msg) -{ - SDprintk("scsi_cmd_sched_restart[%llx]: %s\n", tmd->cd_tagval, msg); - tmd->cd_next = NULL; - if (p_front) { - p_last->cd_next = tmd; - } else { - p_front = tmd; - } - p_last = tmd; - if (donotify) { - up(&scsi_thread_sleep_semaphore); - } -} - - -static __inline void -scsi_cmd_sched_restart(tmd_cmd_t *tmd, const char *msg) -{ - unsigned long flags; - spin_lock_irqsave(&scsi_target_lock, flags); - scsi_cmd_sched_restart_locked(tmd, 1, msg); - spin_unlock_irqrestore(&scsi_target_lock, flags); -} - -static void -scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr) -{ - unsigned long flags; - tmd_xact_t *xact = &tmd->cd_xact; - bus_t *bp; - void *addr; - ini_t *ini; - - /* - * First, find the bus. - */ - spin_lock_irqsave(&scsi_target_lock, flags); - bp = bus_from_tmd(tmd); - if (bp == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk(KERN_WARNING "cannot find bus for incoming command\n"); - return; - } - - /* - * Next check if we have commands pending on the front - * queue and we're coming in at interrupt level. In order - * to preserve ordering, we force commands to come in at thread - * level if there are commands already at thread level - */ - if (from_intr && p_front) { - scsi_cmd_sched_restart_locked(tmd, 1, "from_intr && p_front"); - spin_unlock_irqrestore(&scsi_target_lock, flags); - return; - } - - ini = ini_from_tmd(bp, tmd); - if (ini == NULL) { - ini_t *nptr; - - if (from_intr) { - scsi_cmd_sched_restart_locked(tmd, 1, "had to make ini"); - spin_unlock_irqrestore(&scsi_target_lock, flags); - return; - } - - spin_unlock_irqrestore(&scsi_target_lock, flags); - nptr = scsi_target_kzalloc(sizeof (ini_t), GFP_KERNEL|GFP_ATOMIC); - spin_lock_irqsave(&scsi_target_lock, flags); - - /* - * Check again to see if it showed while we were allocating... - */ - ini = ini_from_tmd(bp, tmd); - if (ini) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - if (nptr) { - scsi_target_kfree(nptr, sizeof (ini_t)); - } - } else { - if (nptr == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_hflags |= TDFH_STSVALID; - xact->td_hflags &= ~TDFH_DATA_MASK; - xact->td_xfrlen = 0; - (*bp->h.r_action)(QIN_TMD_CONT, xact); - return; - } - add_ini(bp, tmd->cd_channel, tmd->cd_iid, nptr); - spin_unlock_irqrestore(&scsi_target_lock, flags); - ini = nptr; - /* - * Start off with a Unit Attention condition. - */ - add_sdata(ini, ua); - } - } else { - spin_unlock_irqrestore(&scsi_target_lock, flags); - } - - /* - * Commands get lumped into 5 rough groups: - * - * + Commands which don't ever really return CHECK CONDITIONS and - * always work. These are typically INQUIRY. - * - * + Commands that we accept, but also report CHECK CONDITIONS against if - * we have pending contingent allegiance (e..g, TEST UNIT READY). - * - * + Commands that retrieve Sense Data (REQUEST SENSE) - * - * + Commmands that do something (like READ or WRITE) - * - * + All others (which we bounce with either ILLEGAL COMMAND or BAD LUN). - */ - - if (unlikely(tmd->cd_cdb[0] == INQUIRY)) { - uint8_t vpdcd = tmd->cd_cdb[2]; - uint8_t legal = (((tmd->cd_cdb[1] & 0x1f) == 0 && vpdcd == 0) || (tmd->cd_cdb[1] & 0x1f) == 1); - uint8_t isvpd = (tmd->cd_cdb[1] & 0x1f) == 1; - - if (legal) { - struct scatterlist *dp = NULL; - uint8_t *buf; - uint32_t len; - - if (from_intr) { - scsi_cmd_sched_restart(tmd, "INQUIRY"); - return; - } - if (tmd->cd_totlen == 0) { - xact->td_hflags |= TDFH_STSVALID; - goto doit; - } - len = min(tmd->cd_totlen, tmd->cd_cdb[4]); - - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk(KERN_WARNING "scsi_target_alloc: out of memory for inquiry data\n"); - add_sdata(ini, enomem); - xact->td_hflags |= TDFH_SNSVALID; - goto doit; - } - buf = addr; - dp = SGS_SGP(addr); - if (isvpd) { - int i, j; - switch (vpdcd) { - case 0: /* Supported VPD Pages */ - len = min(sizeof(vp0data), len); - if (len) { - memcpy(addr, vp0data, len); - } - break; - case 0x80: /* Unit Serial Number */ - len = min(sizeof(vp80data), len); - if (len) { - memcpy(addr, vp80data, len); - snprintf(&buf[4], sizeof (vp80data) - 4, "FERAL0LUN%06dSER%s", L0LUN_TO_FLATLUN(tmd->cd_lun), SERNO); - for (j = 0, i = 4; i < sizeof (vp80data); i++) { - if (j == 0) { - if (buf[i] == 0) { - j = 1; - buf[i] = ' '; - } - } else { - buf[i] = ' '; - } - } - } - break; - case 0x83: /* Device Identification */ - len = min(sizeof(vp83data), len); - if (len) { - memcpy(addr, vp83data, len); - for (j = 8, i = 56; i >= 0; i -= 8, j++) { - buf[j] = tmd->cd_tgt >> i; - } - } - break; - default: - scsi_target_kfree(addr, SGS_SIZE); - add_sdata(ini, invfld); - xact->td_hflags |= TDFH_SNSVALID; - goto doit; - } - } else { - len = min(sizeof(inqdata), len); - if (len) { - memcpy(addr, inqdata, len); - } - } - if (len == 0) { - scsi_target_kfree(addr, SGS_SIZE); - xact->td_hflags |= TDFH_STSVALID; - } else { - init_sg_elem(dp, NULL, 0, addr, len); - xact->td_xfrlen = dp->length; - xact->td_data = dp; - xact->td_hflags |= TDFH_STSVALID|TDFH_DATA_IN; - tmd->cd_flags |= CDF_PRIVATE_0; - /* - * If we're not here, say we aren't here. - */ - if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) { - ((u8 *)addr)[0] = 0x7f; - } - SDprintk2("scsi_target(%s%d): %p (%p) length %d byte0 0x%x\n", bp->h.r_name, bp->h.r_inst, addr, dp, dp->length, ((u8 *)addr)[0]); - } - } else { - SDprintk2("scsi_target(%s%d): illegal field for inquiry data\n", bp->h.r_name, bp->h.r_inst); - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - } - goto doit; - } - - if (tmd->cd_cdb[0] == REQUEST_SENSE) { - struct scatterlist *dp = NULL; - xact->td_xfrlen = TMD_SENSELEN; - xact->td_xfrlen = min(tmd->cd_cdb[4], xact->td_xfrlen); - xact->td_xfrlen = min(tmd->cd_totlen, xact->td_xfrlen); - if (xact->td_xfrlen != 0) { - if (from_intr) { - scsi_cmd_sched_restart(tmd, "REQUEST_SENSE"); - return; - } - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk("scsi_target_alloc: out of memory for sense data\n"); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_xfrlen = 0; - } else { - dp = SGS_SGP(addr); - init_sg_elem(dp, NULL, 0, addr, TMD_SENSELEN); - if (ini->ini_sdata == NULL) { - memcpy(addr, nosense, TMD_SENSELEN); - } else { - memcpy(addr, ini->ini_sdata->sdata, TMD_SENSELEN); - rem_sdata(ini); - } - xact->td_data = dp; - xact->td_hflags |= TDFH_DATA_IN; - tmd->cd_flags |= CDF_PRIVATE_0; - SDprintk2("sense data in scsi_target for %s%d: %p (%p) len %d, key/asc/ascq 0x%x/0x%x/0x%x\n", - bp->h.r_name, bp->h.r_inst, addr, dp, dp->length, - ((u8 *)addr)[2]&0xf, ((u8 *)addr)[12]&0xff, ((u8 *)addr)[13]); - } - } - xact->td_hflags |= TDFH_STSVALID; - goto doit; - } - - if (tmd->cd_cdb[0] == REPORT_LUNS) { - struct scatterlist *dp = NULL; - if (tmd->cd_totlen != 0) { - if (from_intr) { - scsi_cmd_sched_restart(tmd, "REPORT_LUNS"); - return; - } - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk("scsi_target_alloc: out of memory for report luns\n"); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_xfrlen = 0; - } else { - int i; - uint32_t lim, nluns; - uint8_t *rpa = addr; - - lim = (tmd->cd_cdb[6] << 24) | (tmd->cd_cdb[7] << 16) | (tmd->cd_cdb[8] << 8) | tmd->cd_cdb[9]; - - spin_lock_irqsave(&scsi_target_lock, flags); - for (nluns = i = 0; i < MAX_LUN; i++) { - lun_t *lp = &bp->bchan[tmd->cd_channel].luns[i]; - if (lp->enabled) { - uint8_t *ptr = &rpa[8 + (nluns << 3)]; - if (i >= 256) { - ptr[0] = 0x40 | ((i >> 8) & 0x3f); - } - ptr[1] = i; - nluns++; - } - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - - /* - * Make sure we always have *one* (lun 0) enabled - */ - if (nluns == 0) { - nluns = 1; - } - rpa[0] = (nluns << 3) >> 24; - rpa[1] = (nluns << 3) >> 16; - rpa[2] = (nluns << 3) >> 8; - rpa[3] = (nluns << 3); - - dp = SGS_SGP(addr); - lim = min(lim, tmd->cd_totlen); - lim = min(lim, (nluns << 3) + 8); - init_sg_elem(dp, NULL, 0, addr, lim); - xact->td_xfrlen = dp->length; - xact->td_data = dp; - xact->td_hflags |= TDFH_DATA_IN; - tmd->cd_flags |= CDF_PRIVATE_0; - } - } - xact->td_hflags |= TDFH_STSVALID; - goto doit; - } - - /* - * Make sure we have a legal and open lun - */ - if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) { - if (from_intr) { - scsi_cmd_sched_restart(tmd, "bad or disabled lun"); - return; - } - add_sdata(ini, nolun); - xact->td_hflags |= TDFH_SNSVALID; - goto doit; - } - - /* - * All other commands first check for Contingent Allegiance - */ - if (ini->ini_sdata) { - xact->td_hflags |= TDFH_SNSVALID; - goto doit; - } - - switch (tmd->cd_cdb[0]) { - case VERIFY: /* lie */ - case REZERO_UNIT: - case FORMAT_UNIT: - case SYNCHRONIZE_CACHE: - case START_STOP: - case TEST_UNIT_READY: - xact->td_hflags |= TDFH_STSVALID; - break; - case READ_CAPACITY: - if (from_intr) { - scsi_cmd_sched_restart(tmd, "READ CAPACITY"); - return; - } - scsi_target_read_capacity(tmd, ini); - break; - case MODE_SENSE: - if (from_intr) { - scsi_cmd_sched_restart(tmd, "MODE SENSE"); - return; - } - scsi_target_modesense(tmd, ini); - break; - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_16: - if (scsi_target_rdwr(tmd, ini, from_intr)) { - return; - } - break; - case SERVICE_ACTION_IN: - if ((tmd->cd_cdb[1] & 0x1f) == SAI_READ_CAPACITY_16) { - if (from_intr) { - scsi_cmd_sched_restart(tmd, "READ CAPACITY 16"); - return; - } - scsi_target_read_capacity_16(tmd, ini); - break; - } - /* FALLTHROUGH */ - default: - if (from_intr) { - scsi_cmd_sched_restart(tmd, "RANDOM OTHER COMMAND"); - return; - } - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - break; - } - -doit: - if (xact->td_hflags & TDFH_SNSVALID) { - tmd->cd_scsi_status = SCSI_CHECK; - xact->td_hflags |= TDFH_STSVALID; - if (ini && ini->ini_sdata) { - memcpy(tmd->cd_sense, ini->ini_sdata->sdata, TMD_SENSELEN); - rem_sdata(ini); - } else { - if (ini == NULL) { - printk("%s%d: no initiator structure for sense data\n", bp->h.r_name, bp->h.r_inst); - } else { - printk("%s%d: no sense data available\n", bp->h.r_name, bp->h.r_inst); - } - memcpy(tmd->cd_sense, nosense, TMD_SENSELEN); - } - printk("%s%d: INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u CHECK (0x%x 0x%x 0x%x)\n", bp->h.r_name, bp->h.r_inst, tmd->cd_iid, L0LUN_TO_FLATLUN(tmd->cd_lun), - tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_totlen, tmd->cd_sense[2] & 0xf, tmd->cd_sense[12], tmd->cd_sense[13]); - } else { - SDprintk("%s%d: INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u ssts=%x hf 0x%x\n", bp->h.r_name, bp->h.r_inst, tmd->cd_iid, L0LUN_TO_FLATLUN(tmd->cd_lun), - tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_totlen, tmd->cd_scsi_status, xact->td_hflags); - } - (*bp->h.r_action)(QIN_TMD_CONT, xact); -} - -static void -scsi_target_read_capacity_16(tmd_cmd_t *tmd, ini_t *ini) -{ - bus_t *bp; - void *addr; - struct scatterlist *dp; - tmd_xact_t *xact = &tmd->cd_xact; - lun_t *lp; - - bp = ini->ini_bus; - - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk(KERN_WARNING "scsi_target_read_capacity: alloc failed\n"); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_hflags |= TDFH_STSVALID; - return; - } - - lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - - dp = SGS_SGP(addr); - if (tmd->cd_cdb[14] & 0x1) { /* PMI */ - ((u8 *)addr)[0] = 0xff; - ((u8 *)addr)[1] = 0xff; - ((u8 *)addr)[2] = 0xff; - ((u8 *)addr)[3] = 0xff; - ((u8 *)addr)[4] = 0xff; - ((u8 *)addr)[5] = 0xff; - ((u8 *)addr)[6] = 0xff; - ((u8 *)addr)[7] = 0xff; - } else { - uint64_t blks = (lp->nbytes >> LUN_BLOCK_SHIFT) - 1; - if (tmd->cd_cdb[2] || tmd->cd_cdb[3] || tmd->cd_cdb[4] || tmd->cd_cdb[5] || - tmd->cd_cdb[6] || tmd->cd_cdb[7] || tmd->cd_cdb[8] || tmd->cd_cdb[9]) { - scsi_target_kfree(addr, SGS_SIZE); - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - return; - } - ((u8 *)addr)[0] = (blks >> 56) & 0xff; - ((u8 *)addr)[1] = (blks >> 48) & 0xff; - ((u8 *)addr)[2] = (blks >> 40) & 0xff; - ((u8 *)addr)[3] = (blks >> 32) & 0xff; - ((u8 *)addr)[4] = (blks >> 24) & 0xff; - ((u8 *)addr)[5] = (blks >> 16) & 0xff; - ((u8 *)addr)[6] = (blks >> 8) & 0xff; - ((u8 *)addr)[7] = (blks) & 0xff; - } - ((u8 *)addr)[8] = ((1 << LUN_BLOCK_SHIFT) >> 24) & 0xff; - ((u8 *)addr)[9] = ((1 << LUN_BLOCK_SHIFT) >> 16) & 0xff; - ((u8 *)addr)[10] = ((1 << LUN_BLOCK_SHIFT) >> 8) & 0xff; - ((u8 *)addr)[11] = ((1 << LUN_BLOCK_SHIFT)) & 0xff; - init_sg_elem(dp, NULL, 0, addr, min(32, tmd->cd_totlen)); - xact->td_xfrlen = dp->length; - xact->td_data = dp; - xact->td_hflags |= TDFH_DATA_IN|TDFH_STSVALID; - tmd->cd_flags |= CDF_PRIVATE_0; -} - -static void -scsi_target_read_capacity(tmd_cmd_t *tmd, ini_t *ini) -{ - bus_t *bp; - void *addr; - struct scatterlist *dp; - tmd_xact_t *xact = &tmd->cd_xact; - lun_t *lp; - - bp = ini->ini_bus; - - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk(KERN_WARNING "scsi_target_read_capacity: alloc failed\n"); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_hflags |= TDFH_STSVALID; - return; - } - - lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - - dp = SGS_SGP(addr); - if (tmd->cd_cdb[8] & 0x1) { /* PMI */ - ((u8 *)addr)[0] = 0xff; - ((u8 *)addr)[1] = 0xff; - ((u8 *)addr)[2] = 0xff; - ((u8 *)addr)[3] = 0xff; - } else { - uint64_t blks = (lp->nbytes >> LUN_BLOCK_SHIFT) - 1; - if (tmd->cd_cdb[2] || tmd->cd_cdb[3] || tmd->cd_cdb[4] || tmd->cd_cdb[5]) { - scsi_target_kfree(addr, SGS_SIZE); - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - return; - } - if (blks < 0xffffffffull) { - ((u8 *)addr)[0] = (blks >> 24) & 0xff; - ((u8 *)addr)[1] = (blks >> 16) & 0xff; - ((u8 *)addr)[2] = (blks >> 8) & 0xff; - ((u8 *)addr)[3] = (blks) & 0xff; - } else { - ((u8 *)addr)[0] = 0xff; - ((u8 *)addr)[1] = 0xff; - ((u8 *)addr)[2] = 0xff; - ((u8 *)addr)[3] = 0xff; - } - } - ((u8 *)addr)[4] = ((1 << LUN_BLOCK_SHIFT) >> 24) & 0xff; - ((u8 *)addr)[5] = ((1 << LUN_BLOCK_SHIFT) >> 16) & 0xff; - ((u8 *)addr)[6] = ((1 << LUN_BLOCK_SHIFT) >> 8) & 0xff; - ((u8 *)addr)[7] = ((1 << LUN_BLOCK_SHIFT)) & 0xff; - init_sg_elem(dp, NULL, 0, addr, min(8, tmd->cd_totlen)); - xact->td_xfrlen = dp->length; - xact->td_data = dp; - xact->td_hflags |= TDFH_DATA_IN|TDFH_STSVALID; - tmd->cd_flags |= CDF_PRIVATE_0; -} - -static void -scsi_target_modesense(tmd_cmd_t *tmd, ini_t *ini) -{ - bus_t *bp; - lun_t *lp; - int dlen, pgctl, page; - tmd_xact_t *xact = &tmd->cd_xact; - struct scatterlist *dp; - uint8_t *pgdata; - uint32_t nblks; - void *addr; - - bp = ini->ini_bus; - lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - pgctl = tmd->cd_cdb[2] & MODE_PGCTL_MASK; - page = tmd->cd_cdb[2] & MODE_ALL_PAGES; - - SDprintk("scsi_target_modesense(%s%d): page 0x%x, ctl %x, dbd %d for lun %d\n", bp->h.r_name, bp->h.r_inst, - page, pgctl, (tmd->cd_cdb[1] & MODE_DBD) != 0, L0LUN_TO_FLATLUN(tmd->cd_lun)); - - switch (page) { - case MODE_ALL_PAGES: - case MODE_CACHE: - case MODE_FORMAT_DEVICE: - case MODE_GEOMETRY: - case MODE_CONTROL: - break; - default: - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - return; - } - - addr = scsi_target_kzalloc(SGS_SIZE, GFP_KERNEL|GFP_ATOMIC); - if (addr == NULL) { - printk(KERN_WARNING "scsi_target_modesense: alloc failure\n"); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_hflags |= TDFH_STSVALID; - return; - } - dp = SGS_SGP(addr); - - nblks = lp->nbytes >> LUN_BLOCK_SHIFT; - pgdata = addr; - - if (tmd->cd_cdb[1] & MODE_DBD) { - pgdata += 4; - } else { - pgdata[3] = 8; - pgdata[4] = ((1 << LUN_BLOCK_SHIFT) >> 24) & 0xff; - pgdata[5] = ((1 << LUN_BLOCK_SHIFT) >> 16) & 0xff; - pgdata[6] = ((1 << LUN_BLOCK_SHIFT) >> 8) & 0xff; - pgdata[7] = ((1 << LUN_BLOCK_SHIFT)) & 0xff; - - pgdata[8] = (nblks >> 24) & 0xff; - pgdata[9] = (nblks >> 16) & 0xff; - pgdata[10] = (nblks >> 8) & 0xff; - pgdata[11] = nblks & 0xff; - pgdata += 12; - } - - if (page == MODE_ALL_PAGES || page == MODE_FORMAT_DEVICE) { - pgdata[0] = MODE_FORMAT_DEVICE; - pgdata[1] = 24; - if (pgctl != MODE_PGCTL_CHANGEABLE) { - /* tracks per zone */ - /* pgdata[2] = 0; */ - /* pgdata[3] = 0; */ - /* alternate sectors per zone */ - /* pgdata[4] = 0; */ - /* pgdata[5] = 0; */ - /* alternate tracks per zone */ - /* pgdata[6] = 0; */ - /* pgdata[7] = 0; */ - /* alternate tracks per logical unit */ - /* pgdata[8] = 0; */ - /* pgdata[9] = 0; */ - /* sectors per track */ - pgdata[10] = (PSEUDO_SPT >> 8) & 0xff; - pgdata[11] = PSEUDO_SPT & 0xff; - /* data bytes per physical sector */ - pgdata[12] = ((1 << LUN_BLOCK_SHIFT) >> 8) & 0xff; - pgdata[13] = (1 << LUN_BLOCK_SHIFT) & 0xff; - /* interleave */ - /* pgdata[14] = 0; */ - /* pgdata[15] = 1; */ - /* track skew factor */ - /* pgdata[16] = 0; */ - /* pgdata[17] = 0; */ - /* cylinder skew factor */ - /* pgdata[18] = 0; */ - /* pgdata[19] = 0; */ - /* SSRC, HSEC, RMB, SURF */ - } - pgdata += 26; - } - - if (page == MODE_ALL_PAGES || page == MODE_GEOMETRY) { - pgdata[0] = MODE_GEOMETRY; - pgdata[1] = 24; - if (pgctl != MODE_PGCTL_CHANGEABLE) { - uint32_t cyl = (nblks + ((PSEUDO_SPC - 1))) / PSEUDO_SPC; - /* number of cylinders */ - pgdata[2] = (cyl >> 24) & 0xff; - pgdata[3] = (cyl >> 16) & 0xff; - pgdata[4] = cyl & 0xff; - /* number of heads */ - pgdata[5] = PSEUDO_HDS; - /* starting cylinder- write precompensation */ - /* pgdata[6] = 0; */ - /* pgdata[7] = 0; */ - /* pgdata[8] = 0; */ - /* starting cylinder- reduced write current */ - /* pgdata[9] = 0; */ - /* pgdata[10] = 0; */ - /* pgdata[11] = 0; */ - /* drive step rate */ - /* pgdata[12] = 0; */ - /* pgdata[13] = 0; */ - /* landing zone cylinder */ - /* pgdata[14] = 0; */ - /* pgdata[15] = 0; */ - /* pgdata[16] = 0; */ - /* RPL */ - /* pgdata[17] = 0; */ - /* rotational offset */ - /* pgdata[18] = 0; */ - /* medium rotation rate - 7200 RPM */ - pgdata[20] = 0x1c; - pgdata[21] = 0x20; - } - pgdata += 26; - } - - if (page == MODE_ALL_PAGES || page == MODE_CACHE) { - pgdata[0] = MODE_CACHE; - pgdata[1] = 18; -#if 0 - if (pgctl == MODE_PGCTL_CHANGEABLE) { - pgdata[2] = 1 << 2; - } else { - pgdata[2] = 1 << 2; - } -#else - pgdata[2] = 1 << 2; -#endif - pgdata += 20; - } - - if (page == MODE_ALL_PAGES || page == MODE_CONTROL) { - pgdata[0] = MODE_CONTROL; - pgdata[1] = 10; - if (pgctl != MODE_PGCTL_CHANGEABLE) { - pgdata[3] = 1 << 4; /* unrestricted reordering allowed */ - pgdata[8] = 0x75; /* 30000 ms */ - pgdata[9] = 0x30; - } - pgdata += 12; - } - - ((u8 *)addr)[0] = (u8 *)pgdata - (u8 *) addr - 4; - dlen = min(tmd->cd_cdb[4], tmd->cd_totlen); - dlen = min(dlen, SGS_PAYLOAD_SIZE); - init_sg_elem(dp, NULL, 0, addr, dlen); - xact->td_xfrlen = dp->length; - xact->td_data = dp; - xact->td_hflags |= TDFH_DATA_IN|TDFH_STSVALID; - tmd->cd_flags |= CDF_PRIVATE_0; -} - -static int -scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr) -{ - bus_t *bp; - lun_t *lp; - struct page **pglist; - uint64_t lba, devoff; - uint32_t transfer_count, byte_count, count, first_offset; - struct scatterlist *dp; - tmd_xact_t *xact = &tmd->cd_xact; - int iswrite, page_idx, list_idx, sgidx; - unsigned long flags; - - bp = ini->ini_bus; - lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - iswrite = 0; - - switch (tmd->cd_cdb[0]) { - case WRITE_16: - iswrite++; - /* FALLTHROUGH */ - case READ_16: - transfer_count = - (((uint32_t)tmd->cd_cdb[10]) << 24) | - (((uint32_t)tmd->cd_cdb[11]) << 16) | - (((uint32_t)tmd->cd_cdb[12]) << 8) | - ((uint32_t)tmd->cd_cdb[13]); - lba = - (((uint64_t)tmd->cd_cdb[2]) << 56) | - (((uint64_t)tmd->cd_cdb[3]) << 48) | - (((uint64_t)tmd->cd_cdb[4]) << 40) | - (((uint64_t)tmd->cd_cdb[5]) << 32) | - (((uint64_t)tmd->cd_cdb[6]) << 24) | - (((uint64_t)tmd->cd_cdb[7]) << 16) | - (((uint64_t)tmd->cd_cdb[8]) << 8) | - ((uint64_t)tmd->cd_cdb[9]); - break; - case WRITE_12: - iswrite++; - /* FALLTHROUGH */ - case READ_12: - transfer_count = - (((uint32_t)tmd->cd_cdb[6]) << 16) | - (((uint32_t)tmd->cd_cdb[7]) << 8) | - ((u_int32_t)tmd->cd_cdb[8]); - lba = - (((uint32_t)tmd->cd_cdb[2]) << 24) | - (((uint32_t)tmd->cd_cdb[3]) << 16) | - (((uint32_t)tmd->cd_cdb[4]) << 8) | - ((uint32_t)tmd->cd_cdb[5]); - break; - case WRITE_10: - iswrite++; - /* FALLTHROUGH */ - case READ_10: - transfer_count = (((uint32_t)tmd->cd_cdb[7]) << 8) | ((u_int32_t)tmd->cd_cdb[8]); - lba = - (((uint32_t)tmd->cd_cdb[2]) << 24) | - (((uint32_t)tmd->cd_cdb[3]) << 16) | - (((uint32_t)tmd->cd_cdb[4]) << 8) | - ((uint32_t)tmd->cd_cdb[5]); - break; - case WRITE_6: - iswrite++; - /* FALLTHROUGH */ - case READ_6: - transfer_count = tmd->cd_cdb[4]; - if (transfer_count == 0) { - transfer_count = 256; - } - lba = - (((uint32_t)tmd->cd_cdb[1] & 0x1f) << 16) | - (((uint32_t)tmd->cd_cdb[2]) << 8) | - ((uint32_t)tmd->cd_cdb[3]); - break; - default: - if (from_intr) { - scsi_cmd_sched_restart(tmd, "OTHER READ_WR command"); - return (-1); - } - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - return (0); - } - - /* - * Bounds checks. - */ - devoff = lba << LUN_BLOCK_SHIFT; - if (unlikely((devoff + (((uint64_t)transfer_count) << LUN_BLOCK_SHIFT)) > lp->nbytes)) { - printk(KERN_WARNING "scsi_target: overflow devoff (0x%llx) + count (0x%llx) > limit (0x%llx)\n", (unsigned long long) devoff, - (unsigned long long)(((uint64_t)transfer_count) << LUN_BLOCK_SHIFT), (unsigned long long) lp->nbytes); - add_sdata(ini, illfld); - xact->td_hflags |= TDFH_SNSVALID; - return (0); - } - - if (unlikely(transfer_count == 0)) { - printk(KERN_WARNING "%s: zero length transfer count\n", __FUNCTION__); - xact->td_hflags |= TDFH_STSVALID; - return (0); - } - - /* - * Make sure that the transfer_count doesn't exceed total data length - */ - byte_count = transfer_count << LUN_BLOCK_SHIFT; - if (unlikely(byte_count > tmd->cd_totlen)) { - byte_count = tmd->cd_totlen; - byte_count &= ~((1 << LUN_BLOCK_SHIFT) - 1); - if (byte_count == 0) { - printk(KERN_WARNING "%s: byte count less than a block\n", __FUNCTION__); - xact->td_hflags |= TDFH_STSVALID; - return (0); - } - transfer_count = byte_count >> LUN_BLOCK_SHIFT; - } - tmd->cd_off = devoff; - - if (lp->overcommit) { - first_offset = 0; - tmd->cd_nsgelems = (byte_count + PAGE_SIZE - 1) >> PAGE_SHIFT; - } else { - /* - * Calculate the initial offset into the first page - */ - first_offset = devoff & (PAGE_SIZE - 1); - - /* - * Allocate a scatterlist that will cover this I/O - */ - tmd->cd_nsgelems = (byte_count + first_offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - } - dp = NULL; - if (likely(from_intr && tmd->cd_nsgelems < SGELEM_CACHE_SIZE)) { - spin_lock_irqsave(&scsi_target_lock, flags); - dp = sg_cache; - if (dp) { - sg_cache = (struct scatterlist *) sg_page(dp); - sg_assign_page(dp, NULL); - tmd->cd_flags |= CDF_PRIVATE_3; - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - } - if (unlikely(dp == NULL)) { - if (from_intr) { - if (tmd->cd_nsgelems < SGELEM_CACHE_SIZE) - scsi_cmd_sched_restart(tmd, "scatterlist restart: none available"); - else - scsi_cmd_sched_restart(tmd, "scatterlist restart: large_xfr"); - return (-1); - } - dp = scsi_target_kzalloc(tmd->cd_nsgelems * sizeof (struct scatterlist), GFP_KERNEL|GFP_ATOMIC); - if (dp == NULL) { - printk(KERN_WARNING "unable to allocate %d entry scatterlist\n", tmd->cd_nsgelems); - tmd->cd_scsi_status = SCSI_BUSY; - xact->td_hflags |= TDFH_STSVALID; - return (0); - } - } - - /* - * If this is an overcommit disk, get pages for it. - */ - if (lp->overcommit) { - sgidx = 0; - count = 0; - SDprintk2("scsi_target: [%llx] get overcommit pages page_count %d\n", tmd->cd_tagval, lp->npglists); - spin_lock_irqsave(&scsi_target_lock, flags); - while (count < byte_count) { - struct page *pp; - sg_assign_page(&dp[sgidx], (struct page *) lp->pagelists); - if (sg_page(&dp[sgidx]) == NULL) { - lp->outtagas = 1; - scsi_cmd_sched_restart_locked(tmd, 0, "out of pages"); - while (--sgidx >= 0) { - struct page *pp = sg_page(&dp[sgidx]); - NextPage(pp) = (NextPageType) lp->pagelists; - lp->pagelists = (struct page ***) pp; - } - if (tmd->cd_flags & CDF_PRIVATE_3) { - sg_assign_page(dp, (struct page *) sg_cache); - sg_cache = (struct scatterlist *) dp; - spin_unlock_irqrestore(&scsi_target_lock, flags); - tmd->cd_flags ^= CDF_PRIVATE_3; - } else { - spin_unlock_irqrestore(&scsi_target_lock, flags); - scsi_target_kfree(dp, tmd->cd_nsgelems * sizeof (struct scatterlist)); - } - return (-1); - } - dp[sgidx].length = min(PAGE_SIZE, byte_count - count); - count += dp[sgidx].length; - pp = sg_page(&dp[sgidx]); - lp->pagelists = (struct page ***) NextPage(pp); - lp->npglists -= 1; - SDprintk2("scsi_target: [%llx] dp[%d]:off %u len %u\n", tmd->cd_tagval, sgidx, dp[sgidx].offset, dp[sgidx].length); - sgidx++; - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - goto out; - } - - - /* - * Find the indices for the start of the transfer. - */ - list_idx = START_LIST_IDX(devoff); - page_idx = START_PAGE_IDX(devoff); - - SDprintk("%s lba %llu %u bytes dp %p np %d off %u %u:%u\n", iswrite? "write" : "read", lba, byte_count, - dp, tmd->cd_nsgelems, first_offset, list_idx, page_idx); - - pglist = lp->pagelists[list_idx]; - sgidx = 0; - count = 0; - while (count < byte_count) { - if (count == 0 && first_offset != 0) { - dp[sgidx].offset = first_offset; - dp[sgidx].length = min(PAGE_SIZE - first_offset, byte_count); - } else { - dp[sgidx].offset = 0; - dp[sgidx].length = min(PAGE_SIZE, byte_count - count); - } - SDprintk2(" dp[%d]:off %u len %u %u:%u\n", sgidx, dp[sgidx].offset, dp[sgidx].length, list_idx, page_idx); - sg_assign_page(&dp[sgidx], pglist[page_idx++]); - count += dp[sgidx++].length; - if (count != byte_count) { - if (page_idx == PG_PER_LIST) { - page_idx = 0; - if (++list_idx >= lp->npglists) { - printk(KERN_WARNING "bad list_idx for block %lld\n", lba); - xact->td_data = dp; - tmd->cd_dp = dp; - xact->td_xfrlen = 0; - add_sdata(ini, ifailure); - xact->td_hflags |= TDFH_SNSVALID|TDFH_STSVALID; - tmd->cd_flags |= CDF_PRIVATE_1; - return (0); - } - pglist = lp->pagelists[list_idx]; - } - } - } - -out: - xact->td_xfrlen = byte_count; - xact->td_data = dp; - tmd->cd_dp = dp; - tmd->cd_flags |= CDF_PRIVATE_1; - if (iswrite) { - xact->td_hflags |= TDFH_DATA_OUT; - /* - * WCE is set, or we're *not* an overcommit disk, - * the command is done as soon as data lands - * in memory. - */ - if (/* lp->wce || */ lp->overcommit == 0) { - xact->td_hflags |= TDFH_STSVALID; - } - } else { - xact->td_hflags |= TDFH_DATA_IN; - /* - * If we're an overcommit disk, then we don't do - * anything with this command yet- we put it on - * a queue for a user agent to fill. The amount - * to fill by the user agent is known by the - * tmd->cd_totlen; - * - * When the user agent is done, the command is - * then released back to move the fetched data - * back to the initiator. - */ - if (lp->overcommit) { - spin_lock_irqsave(&scsi_target_lock, flags); - tmd->cd_next = NULL; - if (lp->u_front) { - lp->u_tail->cd_next = tmd; - } else { - lp->u_front = tmd; - } - lp->u_tail = tmd; - spin_unlock_irqrestore(&scsi_target_lock, flags); - wake_up_all(&lp->whook); - return (1); - } else { - xact->td_hflags |= TDFH_STSVALID; - } - } - return (0); -} - -static int -scsi_target_ldfree(bus_t *bp, tmd_xact_t *xact, int from_intr) -{ - int i; - unsigned long flags; - tmd_cmd_t *tmd = xact->td_cmd; - - if (tmd->cd_flags & CDF_PRIVATE_0) { - struct scatterlist *dp = xact->td_data; - if (from_intr) { - goto resched; - } - SDprintk("scsi_target: LDFREE[%llx] %p xact->td_data %p\n", tmd->cd_tagval, tmd, dp); - if (dp) { - scsi_target_kfree(page_address(sg_page(dp)) + dp->offset, SGS_SIZE); - } else { - printk(KERN_ERR "scsi_target: LDFREE[%llx] null dp @ line %d\n", tmd->cd_tagval, __LINE__); - return (0); - } - xact->td_data = NULL; - tmd->cd_flags &= ~CDF_PRIVATE_0; - } else if (tmd->cd_flags & CDF_PRIVATE_1) { - struct scatterlist *dp = tmd->cd_dp; - lun_t *lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - - if (dp == NULL) { - printk(KERN_ERR "scsi_target: LDFREE[%llx] null dp @ line %d\n", tmd->cd_tagval, __LINE__); - return (0); - } - - if ((tmd->cd_flags & CDF_PRIVATE_3) == 0 && from_intr) { - goto resched; - } - spin_lock_irqsave(&scsi_target_lock, flags); - if (lp->outtagas) { - lp->outtagas = 0; - up(&scsi_thread_sleep_semaphore); - } - if (lp->overcommit) { - for (i = 0; i < tmd->cd_nsgelems; i++) { - struct page *pp = sg_page(&dp[i]); - if (pp == NULL) { - printk(KERN_ERR "%s: LDFREE[%llx] whoa! nullpage at index %d of %d for command 0x%x\n", __FUNCTION__, tmd->cd_tagval, i, tmd->cd_nsgelems - 1, tmd->cd_cdb[0] & 0xff); - continue; - } - NextPage(pp) = (NextPageType) lp->pagelists; - lp->pagelists = (struct page ***) pp; - lp->npglists += 1; - } - SDprintk("scsi_target: LDFREE[%llx] %s freeing nsgelems %d free count now %u\n", tmd->cd_tagval, from_intr? "intr" : "task", tmd->cd_nsgelems, lp->npglists); - } else { - SDprintk("scsi_target: LDFREE[%llx] %s freeing nsgelems %d\n", tmd->cd_tagval, from_intr? "intr" : "task", tmd->cd_nsgelems); - } - if (tmd->cd_flags & CDF_PRIVATE_3) { - memset(dp, 0, tmd->cd_nsgelems * sizeof (struct scatterlist)); - sg_assign_page(dp, (struct page *) sg_cache); - sg_cache = dp; - spin_unlock_irqrestore(&scsi_target_lock, flags); - tmd->cd_flags &= ~CDF_PRIVATE_3; - } else { - spin_unlock_irqrestore(&scsi_target_lock, flags); - scsi_target_kfree(dp, tmd->cd_nsgelems * sizeof (struct scatterlist)); - } - xact->td_data = NULL; - tmd->cd_flags &= ~CDF_PRIVATE_1; - } - return (1); -resched: - tmd->cd_next = NULL; - spin_lock_irqsave(&scsi_target_lock, flags); - if (q_front) { - q_last->cd_next = tmd; - } else { - q_front = tmd; - } - q_last = tmd; - up(&scsi_thread_sleep_semaphore); - spin_unlock_irqrestore(&scsi_target_lock, flags); - return (0); -} - - -void -scsi_target_handler(qact_e action, void *arg) -{ - unsigned long flags; - bus_t *bp; - - switch (action) { - case QOUT_HBA_REG: - { - hba_register_t *hp = arg; - - /* - * Make sure we can allocate an adequate number of lun structures - */ - spin_lock_irqsave(&scsi_target_lock, flags); - for (bp = busses; bp < &busses[MAX_BUS]; bp++) { - if (bp->h.r_action == NULL) { - break; - } - } - if (bp == &busses[MAX_BUS]) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk("scsi_target: cannot register any more SCSI busses\n"); - break; - } - if (hp->r_version != QR_VERSION) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk("scsi_target: version mismatch- compiled with %d, got %d\n", QR_VERSION, hp->r_version); - break; - } - bp->h = *hp; - spin_unlock_irqrestore(&scsi_target_lock, flags); - bp->bchan = scsi_target_kzalloc(bp->h.r_nchannels * sizeof (struct bus_chan), GFP_KERNEL); - if (bp->bchan == NULL) { - memset(&bp->h, 0, sizeof (hba_register_t)); - printk("scsi_target: cannot allocate buschan for %s%d\n", hp->r_name, hp->r_inst); - } else { - printk("scsi_target: registering %s%d\n", hp->r_name, hp->r_inst); - } - (hp->r_action)(QIN_HBA_REG, arg); - break; - } - case QOUT_ENABLE: - { - enadis_t *ep = arg; - if (ep->en_private) { - up(ep->en_private); - } - break; - } - case QOUT_DISABLE: - { - enadis_t *ep = arg; - if (ep->en_private) { - up(ep->en_private); - } - break; - } - case QOUT_TMD_START: - { - tmd_cmd_t *tmd = arg; - - SDprintk2("scsi_target: TMD_START[%llx] %p cdb0=%x\n", tmd->cd_tagval, tmd, tmd->cd_cdb[0] & 0xff); - - tmd->cd_xact.td_cmd = tmd; - scsi_target_start_cmd(tmd, 1); - break; - } - case QOUT_TMD_DONE: - { - tmd_xact_t *xact = arg; - tmd_cmd_t *tmd = xact->td_cmd; - - bp = bus_from_tmd(tmd); - if (bp == NULL) { - printk(KERN_WARNING "%s: TMD_DONE cannot find bus again\n", __FUNCTION__); - break; - } - - SDprintk2("scsi_target: TMD_DONE[%llx] %p hf %x lf %x\n", tmd->cd_tagval, tmd, xact->td_hflags, xact->td_lflags); - - if (xact->td_lflags & TDFL_ERROR) { - ini_t *ini; - printk("scsi_target: [%llx] ended in error (%d)\n", tmd->cd_tagval, xact->td_error); - if (xact->td_error == -ENOMEM) { - spin_lock_irqsave(&scsi_target_lock, flags); - tmd->cd_next = NULL; - if (r_front) { - r_last->cd_next = tmd; - } else { - r_front = tmd; - } - r_last = tmd; - spin_unlock_irqrestore(&scsi_target_lock, flags); - up(&scsi_thread_sleep_semaphore); - return; - } - /* - * This command is dead. Mark CA for Parity Error and drive on. - */ - spin_lock_irqsave(&scsi_target_lock, flags); - ini = ini_from_tmd(bp, tmd); - spin_unlock_irqrestore(&scsi_target_lock, flags); - if (ini) { - add_sdata(ini, parity); - } - xact->td_hflags &= ~(TDFH_DATA_OUT|TDFH_DATA_IN|TDFH_STSVALID|TDFH_SNSVALID); - } - - /* - * Okay- were we moving data? If so, deal with the result. - * - * If so, check to see if we sent it. - */ - if (xact->td_hflags & TDFH_DATA_OUT) { - lun_t *lp; - SDprintk("scsi_target: [%llx] data receive done\n", tmd->cd_tagval); - spin_lock_irqsave(&scsi_target_lock, flags); - lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)]; - /* - * If we're an overcommit disk we don't complete the command here. - * - * Instead, we give the data to a user agent. It knows how much - * to write based upon tmd->cd_totlen. - * - * When the user agent is done, it will send back status for the command. - */ - if (lp->enabled && lp->overcommit) { - tmd->cd_next = NULL; - if (lp->u_front) { - lp->u_tail->cd_next = tmd; - } else { - lp->u_front = tmd; - } - lp->u_tail = tmd; - spin_unlock_irqrestore(&scsi_target_lock, flags); - wake_up_all(&lp->whook); - break; - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - } else if (xact->td_hflags & TDFH_DATA_IN) { - SDprintk("scsi_target: [%llx] data transmit done\n", tmd->cd_tagval); - } - xact->td_hflags &= ~TDFH_DATA_MASK; - xact->td_xfrlen = 0; - - - /* - * Did we send status already? - */ - if (xact->td_hflags & TDFH_STSVALID) { - if ((xact->td_lflags & TDFL_SENTSTATUS) == 0) { - if (tmd->cd_flags & CDF_PRIVATE_2) { - printk(KERN_ERR "[%llx] already tried to send status\n", tmd->cd_tagval); - } else { - tmd->cd_flags |= CDF_PRIVATE_2; - SDprintk("[%llx] sending status\n", tmd->cd_tagval); - (*bp->h.r_action)(QIN_TMD_CONT, xact); - break; - } - } - } - - /* - * Did we send sense? If so, remove one sense structure. - */ - if (xact->td_hflags & TDFH_SNSVALID) { - if ((xact->td_lflags & TDFL_SENTSENSE) == 0) { - printk(KERN_WARNING "%s: oops, lost sense data\n", __FUNCTION__); - } - } - - if (scsi_target_ldfree(bp, xact, 1)) { - SDprintk("%s: TMD_FIN[%llx]\n", __FUNCTION__, tmd->cd_tagval); - (*bp->h.r_action)(QIN_TMD_FIN, tmd); - } - break; - } - case QOUT_NOTIFY: - { - tmd_notify_t *np = arg; - spin_lock_irqsave(&scsi_target_lock, flags); - bp = bus_from_notify(arg); - if (bp == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk(KERN_WARNING "%s: TMD_NOTIFY cannot find bus\n", __FUNCTION__); - break; - } - if (np->nt_ncode == NT_ABORT_TASK) { - tmd_cmd_t *tmd; - lun_t *lp = &bp->bchan[np->nt_channel].luns[np->nt_lun]; - int i; - - for (i = 0, tmd = p_front; tmd; tmd = tmd->cd_next, i++) { - if (tmd->cd_tagval == np->nt_tagval) { - printk(KERN_WARNING "scsi_target: ABORT_TASK[%llx] found %d into global waitq\n", tmd->cd_tagval, i); - break; - } - } - if (tmd == NULL) { - for (i = 0, tmd = lp->u_front; tmd; tmd = tmd->cd_next, i++) { - if (tmd->cd_tagval == np->nt_tagval) { - printk(KERN_WARNING "scsi_target: ABORT_TASK[%llx] found %d into waitq for lun %d\n", tmd->cd_tagval, i, np->nt_lun); - break; - } - } - if (tmd == NULL) { - printk(KERN_WARNING "scsi_target: ABORT_TASK[%llx] cannot find tmd\n", np->nt_tagval); - } - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - } else if (np->nt_ncode == NT_TARGET_RESET) { - int i; - struct bus_chan *bc = &bp->bchan[np->nt_channel]; - for (i = 0; i < HASH_WIDTH; i++) { - ini_t *ini; - for (ini = bc->list[i]; ini; ini = ini->ini_next) { - add_sdata(ini, ua); - } - } - } else if (np->nt_ncode == NT_LUN_RESET) { - printk(KERN_INFO "%s: LUN RESET from 0x%llx for lun %u\n", __FUNCTION__, np->nt_iid, np->nt_lun); - } else { - spin_unlock_irqrestore(&scsi_target_lock, flags); - SDprintk("scsi_target: MGT code %x from %s%d\n", np->nt_ncode, bp->h.r_name, bp->h.r_inst); - } - (*bp->h.r_action)(QIN_NOTIFY_ACK, arg); - break; - } - case QOUT_HBA_UNREG: - { - hba_register_t *hp = arg; - int j, k; - - spin_lock_irqsave(&scsi_target_lock, flags); - for (bp = busses; bp < &busses[MAX_BUS]; bp++) { - if (bp->h.r_action == NULL) { - continue; - } - if (bp->h.r_identity == hp->r_identity) { - break; - } - } - if (bp == &busses[MAX_BUS]) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - printk(KERN_WARNING "%s: HBA_UNREG cannot find bus\n", __FUNCTION__); - break; - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - for (j = 0; j < bp->h.r_nchannels; j++) { - for (k = 0; k < HASH_WIDTH; k++) { - ini_t *nptr = bp->bchan[j].list[k]; - while (nptr) { - ini_t *next = nptr->ini_next; - free_sdata_chain(nptr->ini_sdata); - scsi_target_kfree(nptr, sizeof (ini_t)); - nptr = next; - } - } - } - for (j = 0; j < bp->h.r_nchannels; j++) { - for (k = 0; k < MAX_LUN; k++) { - if (bp->bchan[j].luns[k].enabled) { - printk("scsi_target: %s%d chan %d had lun %d enabled\n", bp->h.r_name, bp->h.r_inst, j, k); - scsi_free_disk(bp, j, k); - } - } - } - scsi_target_kfree(bp->bchan, sizeof (struct bus_chan) * bp->h.r_nchannels); - memset(bp, 0, sizeof (*bp)); - printk("scsi_target: unregistering %s%d\n", hp->r_name, hp->r_inst); - (hp->r_action)(QIN_HBA_UNREG, arg); - break; - } - default: - printk("scsi_target: action code %d (0x%x)?\n", action, action); - break; - } -} - -static int -scsi_target_thread(void *arg) -{ - unsigned long flags; - - siginitsetinv(¤t->blocked, 0); - lock_kernel(); - daemonize("scsi_target_thread"); - unlock_kernel(); - up(&scsi_thread_entry_exit_semaphore); - SDprintk("scsi_target_thread starting\n"); - - while (scsi_target_thread_exit == 0) { - tmd_cmd_t *pending_start, *pending_free, *pending_restart; - - spin_lock_irqsave(&scsi_target_lock, flags); - if (p_front == NULL && q_front == NULL && r_front == NULL) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - SDprintk3("scsi_task_thread sleeping\n"); - down_interruptible(&scsi_thread_sleep_semaphore); - SDprintk3("scsi_task_thread running\n"); - spin_lock_irqsave(&scsi_target_lock, flags); - } - - if ((pending_start = p_front) != NULL) { - if ((p_front = pending_start->cd_next) == NULL) { - p_last = p_front = NULL; - } - } - if ((pending_free = q_front) != NULL) { - q_last = q_front = NULL; - } - if ((pending_restart = r_front) != NULL) { - r_last = r_front = NULL; - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - while (pending_start) { - tmd_cmd_t *next = pending_start->cd_next; - pending_start->cd_next = NULL; - scsi_target_start_cmd(pending_start, 0); - pending_start = next; - } - while (pending_free) { - bus_t *bp; - tmd_cmd_t *active; - - active = pending_free; - pending_free = active->cd_next; - active->cd_next = NULL; - bp = bus_from_tmd(active); - if (bp == NULL) { - printk(KERN_WARNING "lost bus when tring to call TMD_FIN\n"); - } else { - if (scsi_target_ldfree(bp, &active->cd_xact, 0)) { - SDprintk("%s: TMD_FIN[%llx]\n", __FUNCTION__, active->cd_tagval); - (*bp->h.r_action)(QIN_TMD_FIN, active); - } - } - } - while (pending_restart) { - bus_t *bp; - tmd_cmd_t *active; - - active = pending_restart; - pending_restart = active->cd_next; - active->cd_next = NULL; - bp = bus_from_tmd(active); - (*bp->h.r_action)(QIN_TMD_CONT, active); - } - } - SDprintk("scsi_target_thread exiting\n"); - up(&scsi_thread_entry_exit_semaphore); - return (0); -} - -static int -scsi_alloc_disk(bus_t *bp, int chan, int lun, int overcommit, uint64_t nbytes) -{ - int i; - lun_t *lp; - - if (nbytes == 0) { - return (-EINVAL); - } - /* - * Round up the size to the next 512 byte boundary - */ - if (nbytes & ((1 << LUN_BLOCK_SHIFT) - 1)) { - uint64_t rusz = nbytes + (1 << LUN_BLOCK_SHIFT) - 1; - rusz &= ~((1 << LUN_BLOCK_SHIFT) - 1); - printk(KERN_WARNING "%s: rounding disk size from %llu to %llu\n", __FUNCTION__, nbytes, rusz); - nbytes = rusz; - } - - lp = &bp->bchan[chan].luns[lun]; - lp->nbytes = nbytes; - - if (overcommit) { - struct page *pp; - int npgs = OC_SIZE >> PAGE_SHIFT; - - lp->overcommit = 1; - lp->npglists = 0; - for (i = 0; i < npgs; i++) { - pp = alloc_page(__GFP_HIGHMEM | __GFP_WAIT); - if (pp == NULL) { - printk(KERN_ERR "%s: unable to allocate memory pages\n", __FUNCTION__); - goto fail; - } - NextPage(pp) = (NextPageType) lp->pagelists; - lp->pagelists = (struct page ***) pp; - lp->npglists += 1; - } - } else { - int npgs, j; - size_t npgl; - struct page **pptr; - - npgs = (nbytes + PAGE_SIZE - 1) >> PAGE_SHIFT; - lp->npglists = (nbytes + PGLIST_MAPPING_SIZE - 1) / PGLIST_MAPPING_SIZE; - npgl = lp->npglists * sizeof (struct page **); - lp->pagelists = scsi_target_kzalloc(npgl, GFP_KERNEL); - if (lp->pagelists == NULL) { - return (-ENOMEM); - } - - for (i = 0; i < lp->npglists; i++) { - lp->pagelists[i] = scsi_target_kzalloc(PGLIST_SIZE, GFP_KERNEL); - pptr = lp->pagelists[i]; - if (pptr == NULL) { - goto fail; - } - for (j = 0; j < PG_PER_LIST; j++) { - pptr[j] = alloc_page(__GFP_HIGHMEM | __GFP_WAIT); - if (pptr[j] == NULL) { - printk(KERN_ERR "%s: unable to allocate memory pages\n", __FUNCTION__); - goto fail; - } - if (--npgs == 0) { - break; - } - } - if (npgs == 0) { - break; - } - } - } - return (0); - -fail: - scsi_free_disk(bp, chan, lun); - return (-ENOMEM); -} - -static void -scsi_free_disk(bus_t *bp, int chan, int lun) -{ - lun_t *lp = &bp->bchan[chan].luns[lun]; - - if (lp->overcommit) { - while (lp->pagelists) { - struct page *pp = (struct page *) lp->pagelists; - lp->pagelists = (struct page ***) NextPage(pp); - __free_page(pp); - } - lp->npglists = 0; - } else { - if (lp->pagelists && lp->npglists) { - int i, j; - struct page **pptr; - for (i = 0; i < lp->npglists; i++) { - pptr = lp->pagelists[i]; - if (pptr == NULL) { - continue; - } - for (j = 0; j < PG_PER_LIST; j++) { - if (pptr[j] != NULL) { - __free_page(pptr[j]); - pptr[j] = NULL; - } - } - scsi_target_kfree(pptr, PGLIST_SIZE); - } - scsi_target_kfree(lp->pagelists, lp->npglists * sizeof (struct page **)); - lp->pagelists = NULL; - lp->npglists = 0; - } - } - lp->overcommit = 0; -} - -static int -scsi_target_copydata(struct scatterlist *dp, void *ubuf, uint32_t len, int from_user) -{ - struct page *pp; - uint32_t count; - char *kva, *uva; - int err, idx, cpylen; - - idx = count = 0; - uva = ubuf; - while (count < len) { - pp = sg_page(&dp[idx]); - kva = kmap(pp); - if (kva == NULL) { - return (-EFAULT); - } - cpylen = min(PAGE_SIZE, len - count); - if (from_user) { - err = copy_from_user(kva, uva, cpylen); - SDprintk3("scsi_target: copy from user %p dp[%d].length=%u\n", uva, idx, cpylen); - } else { - err = copy_to_user(uva, kva, cpylen); - SDprintk3("scsi_target: copy to user %p dp[%d].length=%u\n", uva, idx, cpylen); - } - kunmap(pp); - if (err) { - return (err); - } - uva += cpylen; - count += cpylen; - idx++; - } - return (0); -} - -static int -scsi_target_start_user_io(sc_io_t *sc) -{ - unsigned long flags; - tmd_cmd_t *tmd; - bus_t *bp; - lun_t *lp; - - bp = bus_from_name(sc->hba_name_unit); - if (bp == NULL) { - SDprintk("%s: cannot find bus for %s\n", __FUNCTION__, sc->hba_name_unit); - return (-ENXIO); - } - - if (sc->channel >= bp->h.r_nchannels) { - SDprintk("%s: bad chan (%d)\n", __FUNCTION__, sc->channel); - return (-EINVAL); - } - if (sc->lun >= MAX_LUN) { - SDprintk("%s: bad lun (%d)\n", __FUNCTION__, sc->lun); - return (-EINVAL); - } - lp = &bp->bchan[sc->channel].luns[sc->lun]; - - SDprintk2("%s: waiting for a R/W IO operation\n", __FUNCTION__); - if (wait_event_interruptible(lp->whook, (lp->u_front != NULL))) { - return (-EINTR); - } - spin_lock_irqsave(&scsi_target_lock, flags); - if ((tmd = lp->u_front) != NULL) { - if ((lp->u_front = tmd->cd_next) == NULL) { - lp->u_tail = NULL; - } - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - if (tmd == NULL) { - return (-ENOENT); - } - - sc->off = tmd->cd_off; - sc->tag = tmd; - - /* - * If data is coming to us, copy it out to user space first. - */ - if (tmd->cd_flags & CDF_DATA_OUT) { - int r; - - sc->amt = tmd->cd_totlen; - if (sc->amt > sc->len) { - sc->amt = sc->len; - printk(KERN_WARNING "scsi_target: A write to us (%u bytes) that is bigger than the user supplied buffer (%u bytes)\n", sc->amt, sc->len); - } - r = scsi_target_copydata(tmd->cd_dp, sc->addr, sc->amt, 0); - if (r) { - printk(KERN_ERR "scsi_target: failed to copy data to user space\n"); - memcpy(tmd->cd_sense, ifailure, TMD_SENSELEN); - tmd->cd_scsi_status = CHECK_CONDITION; - tmd->cd_xact.td_hflags &= ~TDFH_DATA_MASK; - tmd->cd_xact.td_hflags |= TDFH_SNSVALID|TDFH_STSVALID; - tmd->cd_xact.td_xfrlen = 0; - (*bp->h.r_action)(QIN_TMD_CONT, &tmd->cd_xact); - return (r); - } - sc->read = 0; - if (lp->wce == 0) { - sc->sync = 1; - } - SDprintk2("scsi_target: WR->USER [%llx] %p amt %u \n", tmd->cd_tagval, tmd, sc->amt); - } else { - sc->amt = tmd->cd_totlen; - sc->read = 1; - SDprintk2("scsi_target: RD->USER [%llx] %p amt %u\n", tmd->cd_tagval, tmd, sc->amt); - } - return (0); -} - -static int -scsi_target_end_user_io(sc_io_t *sc) -{ - bus_t *bp; - lun_t *lp; - tmd_cmd_t *tmd; - tmd_xact_t *xact; - - bp = bus_from_name(sc->hba_name_unit); - if (bp == NULL) { - SDprintk("%s: cannot find bus for %s\n", __FUNCTION__, sc->hba_name_unit); - return (-ENXIO); - } - - if (sc->channel >= bp->h.r_nchannels) { - SDprintk("%s: bad chan (%d)\n", __FUNCTION__, sc->channel); - return (-EINVAL); - } - if (sc->lun >= MAX_LUN) { - SDprintk("%s: bad lun (%d)\n", __FUNCTION__, sc->lun); - return (-EINVAL); - } - lp = &bp->bchan[sc->channel].luns[sc->lun]; - tmd = sc->tag; - xact = &tmd->cd_xact; - SDprintk2("scsi_target: USER->KERN [%llx] %p err %d len %u\n", tmd->cd_tagval, tmd, sc->err, sc->len); - /* - * If we had an error, stop right here and return something to the initiator. - */ - if (sc->err) { - printk(KERN_ERR "err %d from user app\n", sc->err); - memcpy(tmd->cd_sense, mediaerr, TMD_SENSELEN); - barf: - tmd->cd_scsi_status = CHECK_CONDITION; - xact->td_hflags &= ~TDFH_DATA_MASK; - xact->td_hflags |= TDFH_SNSVALID|TDFH_STSVALID; - xact->td_xfrlen = 0; - (*bp->h.r_action)(QIN_TMD_CONT, xact); - return (0); - } - - /* - * If we were reading from us to the initiator, copy the data in and set it up for transmit back to the initiator. - */ - if (tmd->cd_flags & CDF_DATA_IN) { - /* - * In this context, a user buffer length that is not equal to what the amount we told the user agent to move is not legal. - */ - if (sc->len != tmd->cd_totlen) { - printk(KERN_ERR "scsi_target: user read length %u not equal to required amount of %u\n", sc->len, tmd->cd_totlen); - memcpy(tmd->cd_sense, ifailure, TMD_SENSELEN); - goto barf; - } - if (scsi_target_copydata(tmd->cd_dp, sc->addr, sc->len, 1)) { - printk(KERN_ERR "failed to copy in data for read\n"); - memcpy(tmd->cd_sense, ifailure, TMD_SENSELEN); - goto barf; - } - xact->td_xfrlen = sc->len; - xact->td_hflags |= TDFH_DATA_IN; - } else { - xact->td_xfrlen = 0; - xact->td_hflags &= ~TDFH_DATA_MASK; - } - xact->td_hflags |= TDFH_STSVALID; - (*bp->h.r_action)(QIN_TMD_CONT, xact); - return (0); -} - -static int -scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int chan, int lun, int en) -{ - DECLARE_MUTEX_LOCKED(rsem); - unsigned long flags; - enadis_t ec; - info_t info; - lun_t *lp; - bus_t *bp; - int rv, i; - - /* - * XXX: yes, there is a race condition here where the bus can - * XXX: go away. But in order to solve it, we have to make the - * XXX: bus structure stay around while we call into the HBA - * XXX: anyway, so fooey,. - */ - bp = bus_from_name(hba_name_unit); - if (bp == NULL) { - SDprintk("%s: cannot find bus for %s\n", __FUNCTION__, hba_name_unit); - return (-ENXIO); - } - - if (chan < 0 || chan >= bp->h.r_nchannels) { - SDprintk("%s: bad chan (%d)\n", __FUNCTION__, chan); - return (-EINVAL); - } - if (lun < 0 || lun >= MAX_LUN) { - SDprintk("%s: bad lun (%d)\n", __FUNCTION__, lun); - return (-EINVAL); - } - lp = &bp->bchan[chan].luns[lun]; - - if (en) { - if (lp->enabled) { - printk("%s: lun %d already enabled\n", __FUNCTION__, lun); - return (-EBUSY); - } - rv = scsi_alloc_disk(bp, chan, lun, en == 2, nbytes); - if (rv) { - return (rv); - } - } else { - lp->enabled = 0; - } - - memset(&info, 0, sizeof (info)); - info.i_identity = bp->h.r_identity; - info.i_channel = chan; - (*bp->h.r_action)(QIN_GETINFO, &info); - if (info.i_error) { - return (info.i_error); - } - memset(&ec, 0, sizeof (ec)); - ec.en_hba = bp->h.r_identity; - if (bp->h.r_type == R_FC) { - ec.en_lun = LUN_ANY; - } else { - ec.en_lun = lun; - } - ec.en_chan = chan; - ec.en_private = &rsem; - - (*bp->h.r_action)(en? QIN_ENABLE : QIN_DISABLE, &ec); - down(&rsem); - - if (ec.en_error) { - SDprintk("%s: HBA returned %d for %s action\n", __FUNCTION__, ec.en_error, en? "enable" : "disable"); - scsi_free_disk(bp, chan, lun); - return (ec.en_error); - } - - spin_lock_irqsave(&scsi_target_lock, flags); - for (i = 0; i < HASH_WIDTH; i++) { - ini_t *ini = bp->bchan[chan].list[i]; - while (ini) { - spin_unlock_irqrestore(&scsi_target_lock, flags); - add_sdata(ini, invchg); - spin_lock_irqsave(&scsi_target_lock, flags); - ini = ini->ini_next; - } - } - spin_unlock_irqrestore(&scsi_target_lock, flags); - - if (en == 0) { - scsi_free_disk(bp, chan, lun); - } else { - lp->u_tail = lp->u_front = NULL; - init_waitqueue_head(&lp->whook); - lp->wce = 1; - lp->enabled = 1; - } - return (0); -} - -EXPORT_SYMBOL(scsi_target_handler); -module_param(scsi_tdebug, int, 0); -#ifdef MODULE_LICENSE -MODULE_LICENSE("Dual BSD/GPL"); -#endif - -int init_module(void) -{ - int i; - struct proc_dir_entry *e; - - e = create_proc_entry(SCSI_TARGET, S_IFREG|S_IRUGO|S_IWUSR, 0); - if (e == NULL){ - printk(KERN_ERR "cannot make %s\n", SCSI_TARGET); - return (-EIO); - } - e->proc_fops = &scsi_target_fops; - spin_lock_init(&scsi_target_lock); - kernel_thread(scsi_target_thread, NULL, 0); - down(&scsi_thread_entry_exit_semaphore); - for (i = 0; i < N_SENSE_BUFS; i++) { - sdata_t *t = scsi_target_kalloc(sizeof (sdata_t), GFP_KERNEL); - if (t) { - t->next = sdp; - sdp = t; - } else { - break; - } - } - printk(KERN_INFO "Allocated %d sense buffers\n", i); - for (i = 0; i < SGELEM_CACHE_COUNT; i++) { - struct scatterlist *sg = scsi_target_kzalloc(SGELEM_CACHE_SIZE * sizeof (struct scatterlist), GFP_KERNEL); - if (sg == NULL) { - break; - } - sg_assign_page(sg, (struct page *) sg_cache); - sg_cache = sg; - } - printk(KERN_INFO "Allocated %d cached sg elements\n", i); - return (0); -} - -/* - * We can't get here until all hbas have deregistered - */ -void cleanup_module(void) -{ - scsi_target_thread_exit = 1; - up(&scsi_thread_sleep_semaphore); - down(&scsi_thread_entry_exit_semaphore); - free_sdata_chain(sdp); - while (sg_cache) { - struct scatterlist *sg = (struct scatterlist *) sg_page(sg_cache); - scsi_target_kfree(sg_cache, SGELEM_CACHE_SIZE * sizeof (struct scatterlist)); - sg_cache = sg; - } - remove_proc_entry(SCSI_TARGET, 0); -} -/* - * vim:ts=4:sw=4:expandtab - */ diff --git a/qla_isp/linux/scsi_target.h b/qla_isp/linux/scsi_target.h deleted file mode 100644 index fc08424de..000000000 --- a/qla_isp/linux/scsi_target.h +++ /dev/null @@ -1,119 +0,0 @@ -/* $Id: scsi_target.h,v 1.30 2008/02/11 23:59:06 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 - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - */ -/* - * SCSI Target Control Port - */ -#define SCSI_TARGET "scsi_target" -#define SCSI_TARGET_DEV "/proc/" SCSI_TARGET - -/* - * SCSI Target Stub Driver for Linux for a memory or user agent disk device. - * Ioctl Definitions File. - */ - -#define _SI ('j' << 8) - -/* - * Set new debugging level (get previous) (int argument). - */ -#define SC_DEBUG (_SI | 0) - -/* - * Enable/Disable lun - */ -typedef struct { - char hba_name_unit[16]; /* e.g., "isp0" */ - uint64_t nbytes; /* disk size, in bytes */ - uint16_t lun; /* lun to map it to */ - uint8_t channel; /* channel */ - uint8_t flags; -} sc_enable_t; -#define SC_EF_OVERCOMMIT 0x01 /* allow overcommit */ - -#define SC_ENABLE_LUN (_SI | 1) -#define SC_DISABLE_LUN (_SI | 2) - -/* - * Overcommit disks have to have data written to backing store - * and read from it. - */ -typedef struct { - char hba_name_unit[16]; /* e.g., "isp0" */ - uint16_t lun; /* lun */ - uint8_t channel; - uint8_t : 6, - sync : 1, /* (implied) sync after write */ - read : 1; /* read (from target to initiator) flag */ - void * tag; /* id tag for this command */ - void * addr; /* user buffer address */ - uint32_t len; /* user buffer length */ - uint64_t off; /* disk offset */ - uint32_t amt; /* this command's actual data length */ - int err; /* from user app */ -} sc_io_t; -#define SC_GET_IO (_SI | 3) -#define SC_PUT_IO (_SI | 4) - -/* - * Inject a UNIT ATTENTION error on the next command for this device - */ -typedef struct { - char hba_name_unit[16]; -} sc_inject_ua_t; -#define SC_INJECT_UA (_SI | 21) - -/* - * vim:ts=4:sw=4:expandtab - */ diff --git a/qla_isp/linux/scsi_target_ctl.c b/qla_isp/linux/scsi_target_ctl.c deleted file mode 100644 index f7a5aff9b..000000000 --- a/qla_isp/linux/scsi_target_ctl.c +++ /dev/null @@ -1,286 +0,0 @@ -/* $Id: scsi_target_ctl.c,v 1.22 2008/02/11 23:59:06 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 - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * 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 - */ -/* - * SCSI Target Mode "stub" control program for Linux. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "scsi_target.h" - -#define dprintf if (debug) printf - -const char usage[] = "usage: %s\n\ - scsi_target_ctl debug level\n\ - scsi_target_ctl enable hba-name-unit channel lun nbytes [ overcommit-file ]\n\ - scsi_target_ctl disable hba-name-unit channel lun\n\ - scsi_target_ctl ua hba-name-unit\n"; - -static uint64_t szarg(char *); -static void ioloop(int, int, char *, uint16_t); -static int debug; - -int -main(int a, char **v) -{ - union { - sc_enable_t _x; - int _y; - sc_inject_ua_t _u; - } x; - int iofd = -1, fd, action, dd = 0; - char *progname; - - if (v) { - progname = v[0]; - if (progname == NULL) { - return (1); - } - } else { - return (1); - } - - debug = getenv("DEBUG") != NULL; - - if (a < 3 || a > 7) { - usage: - fprintf(stderr, usage, progname); - return (1); - } - - memset(&x, 0, sizeof (x)); - if (strcmp(v[1], "enable") == 0) { - if (a < 6) { - goto usage; - } - action = SC_ENABLE_LUN; - strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit)); - x._x.channel = atoi(v[3]); - x._x.lun = atoi(v[4]); - x._x.nbytes = szarg(v[5]); - if (a == 7) { - iofd = open(v[6], O_RDWR); - if (iofd < 0) { - perror(v[6]); - return (1); - } - dprintf("opened %s to back size 0x%016llx bytes\n", v[6], (unsigned long long) x._x.nbytes); - x._x.flags = SC_EF_OVERCOMMIT; - } - } else if (strcmp(v[1], "disable") == 0) { - if (a != 5) { - goto usage; - } - action = SC_DISABLE_LUN; - strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit)); - x._x.channel = atoi(v[3]); - x._x.lun = atoi(v[4]); - } else if (strcmp(v[1], "debug") == 0) { - if (a != 3) { - goto usage; - } - action = SC_DEBUG; - dd = x._y = atoi(v[2]); - } else if (strcmp(v[1], "ua") == 0) { - if (a != 3) { - goto usage; - } - strncpy(x._u.hba_name_unit, v[2], sizeof (x._u.hba_name_unit)); - action = SC_INJECT_UA; - } else { - goto usage; - } - - - if ((fd = open(SCSI_TARGET_DEV, O_RDWR)) < 0) { - perror(SCSI_TARGET_DEV); - return (1); - } - - if (ioctl(fd, action, &x) < 0) { - perror(v[1]); - return (2); - } - if (action == SC_ENABLE_LUN && iofd != -1) { - pid_t p = fork(); - if (p == 0) { - (void) close(0); - (void) close(1); - (void) close(2); - ioloop(fd, iofd, x._x.hba_name_unit, x._x.lun); - } else if (p < 0) { - perror("fork"); - } - } else if (action == SC_DEBUG) { - printf("old debug level: %d; new debug level %d\n", x._y, dd); - } - return (0); -} - -static uint64_t -szarg(char *n) -{ - uint64_t result; - char *q = n; - - while (isxdigit(*q)) { - q++; - } - result = (uint64_t) strtoull(n, NULL, 0); - if (*q == '\0') { - return (result); - } - if (strcasecmp(q, "kib") == 0) { - result <<= 10; - } else if (strcasecmp(q, "mib") == 0) { - result <<= 20; - } else if (strcasecmp(q, "gib") == 0) { - result <<= 30; - } else if (strcasecmp(q, "tib") == 0) { - result <<= 40; - } else if (strcasecmp(q, "pib") == 0) { - result <<= 50; - } else if (strcasecmp(q, "k") == 0) { - result <<= 10; - } else if (strcasecmp(q, "m") == 0) { - result <<= 20; - } else if (strcasecmp(q, "g") == 0) { - result <<= 30; - } else if (strcasecmp(q, "t") == 0) { - result <<= 40; - } else if (strcasecmp(q, "p") == 0) { - result <<= 50; - } else if (strcasecmp(q, "kb") == 0) { - result *= 1000; - } else if (strcasecmp(q, "mb") == 0) { - result *= 1000000; - } else if (strcasecmp(q, "gb") == 0) { - result *= 1000000000ULL; - } else if (strcasecmp(q, "tb") == 0) { - result *= 1000000000000ULL; - } else if (strcasecmp(q, "pb") == 0) { - result *= 1000000000000000ULL; - } - return (result); -} - -static void -ioloop(int fd, int iofd, char *hba, uint16_t lun) -{ - sc_io_t sc; - off_t off; - int amt; - void *buffer = valloc(4 << 20); - - openlog("scsi_target_ctl", LOG_NDELAY|LOG_PID, LOG_DAEMON); - - for (;;) { - memset(&sc, 0, sizeof (sc)); - strcpy(sc.hba_name_unit, hba); - sc.lun = lun; - sc.addr = buffer; - sc.len = 4 << 20; - if (ioctl(fd, SC_GET_IO, &sc) < 0) { - if (errno == EINTR || errno == ENOENT) { - continue; - } - syslog(LOG_ERR, "SC_GET_IO returned %s", strerror(errno)); - break; - } - off = (off_t) sc.off; - if (lseek(iofd, off, SEEK_SET) != off) { - syslog(LOG_ERR, "lseek error: %s", strerror(errno)); - break; - } - if (sc.read) { - amt = read(iofd, sc.addr, sc.amt); - syslog(LOG_DEBUG, "read %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt); - } else { - amt = write(iofd, sc.addr, sc.amt); - syslog(LOG_DEBUG, "write %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt); - if (sc.sync) { - if (fdatasync(iofd) < 0) { - sc.err = errno; - syslog(LOG_ERR, "FDATASYNC: %s", strerror(errno)); - } - } - } - if (amt < 0) { - perror(sc.read? "read" : "write"); - sc.err = errno; - sc.len = 0; - } else { - sc.len = amt; - } - if (ioctl(fd, SC_PUT_IO, &sc) < 0) { - syslog(LOG_ERR, "SC_PUT_IO: %s", strerror(errno)); - break; - } - } -} -/* - * vim:ts=4:sw=4:expandtab - */