Linux Audio

Check our new training course

Loading...
v5.9
   1/*
   2 *  linux/drivers/message/fusion/mptscsih.c
   3 *      For use with LSI PCI chip/adapter(s)
   4 *      running LSI Fusion MPT (Message Passing Technology) firmware.
   5 *
   6 *  Copyright (c) 1999-2008 LSI Corporation
   7 *  (mailto:DL-MPTFusionLinux@lsi.com)
   8 *
   9 */
  10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  11/*
  12    This program is free software; you can redistribute it and/or modify
  13    it under the terms of the GNU General Public License as published by
  14    the Free Software Foundation; version 2 of the License.
  15
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20
  21    NO WARRANTY
  22    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  23    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  24    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  25    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  26    solely responsible for determining the appropriateness of using and
  27    distributing the Program and assumes all risks associated with its
  28    exercise of rights under this Agreement, including but not limited to
  29    the risks and costs of program errors, damage to or loss of data,
  30    programs or equipment, and unavailability or interruption of operations.
  31
  32    DISCLAIMER OF LIABILITY
  33    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  34    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  36    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  37    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  38    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  39    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  40
  41    You should have received a copy of the GNU General Public License
  42    along with this program; if not, write to the Free Software
  43    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  44*/
  45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  46
  47#include <linux/module.h>
  48#include <linux/kernel.h>
  49#include <linux/slab.h>
  50#include <linux/init.h>
  51#include <linux/errno.h>
  52#include <linux/kdev_t.h>
  53#include <linux/blkdev.h>
  54#include <linux/delay.h>	/* for mdelay */
  55#include <linux/interrupt.h>	/* needed for in_interrupt() proto */
  56#include <linux/reboot.h>	/* notifier code */
  57#include <linux/workqueue.h>
  58
  59#include <scsi/scsi.h>
  60#include <scsi/scsi_cmnd.h>
  61#include <scsi/scsi_device.h>
  62#include <scsi/scsi_host.h>
  63#include <scsi/scsi_tcq.h>
  64#include <scsi/scsi_dbg.h>
  65
  66#include "mptbase.h"
  67#include "mptscsih.h"
  68#include "lsi/mpi_log_sas.h"
  69
  70/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  71#define my_NAME		"Fusion MPT SCSI Host driver"
  72#define my_VERSION	MPT_LINUX_VERSION_COMMON
  73#define MYNAM		"mptscsih"
  74
  75MODULE_AUTHOR(MODULEAUTHOR);
  76MODULE_DESCRIPTION(my_NAME);
  77MODULE_LICENSE("GPL");
  78MODULE_VERSION(my_VERSION);
  79
  80/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  81/*
  82 *  Other private/forward protos...
  83 */
  84struct scsi_cmnd	*mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
  85static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
  86static void	mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
  87static int	SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
  88int		mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  89static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
  90int		mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  91
  92static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  93				 SCSIIORequest_t *pReq, int req_idx);
  94static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
  95static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
  96
  97int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
  98		u64 lun, int ctx2abort, ulong timeout);
  99
 100int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 101int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 102
 103void
 104mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
 105static int	mptscsih_get_completion_code(MPT_ADAPTER *ioc,
 106		MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 107int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 108static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 109static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 110
 111static int
 112mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
 113				SCSITaskMgmtReply_t *pScsiTmReply);
 114void 		mptscsih_remove(struct pci_dev *);
 115void 		mptscsih_shutdown(struct pci_dev *);
 116#ifdef CONFIG_PM
 117int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 118int 		mptscsih_resume(struct pci_dev *pdev);
 119#endif
 120
 
 
 121
 122/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 123/*
 124 *	mptscsih_getFreeChainBuffer - Function to get a free chain
 125 *	from the MPT_SCSI_HOST FreeChainQ.
 126 *	@ioc: Pointer to MPT_ADAPTER structure
 127 *	@req_idx: Index of the SCSI IO request frame. (output)
 128 *
 129 *	return SUCCESS or FAILED
 130 */
 131static inline int
 132mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
 133{
 134	MPT_FRAME_HDR *chainBuf;
 135	unsigned long flags;
 136	int rc;
 137	int chain_idx;
 138
 139	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
 140	    ioc->name));
 141	spin_lock_irqsave(&ioc->FreeQlock, flags);
 142	if (!list_empty(&ioc->FreeChainQ)) {
 143		int offset;
 144
 145		chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
 146				u.frame.linkage.list);
 147		list_del(&chainBuf->u.frame.linkage.list);
 148		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
 149		chain_idx = offset / ioc->req_sz;
 150		rc = SUCCESS;
 151		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 152		    "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
 153		    ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
 154	} else {
 155		rc = FAILED;
 156		chain_idx = MPT_HOST_NO_CHAIN;
 157		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
 158		    ioc->name));
 159	}
 160	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 161
 162	*retIndex = chain_idx;
 163	return rc;
 164} /* mptscsih_getFreeChainBuffer() */
 165
 166/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 167/*
 168 *	mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
 169 *	SCSIIORequest_t Message Frame.
 170 *	@ioc: Pointer to MPT_ADAPTER structure
 171 *	@SCpnt: Pointer to scsi_cmnd structure
 172 *	@pReq: Pointer to SCSIIORequest_t structure
 173 *
 174 *	Returns ...
 175 */
 176static int
 177mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
 178		SCSIIORequest_t *pReq, int req_idx)
 179{
 180	char 	*psge;
 181	char	*chainSge;
 182	struct scatterlist *sg;
 183	int	 frm_sz;
 184	int	 sges_left, sg_done;
 185	int	 chain_idx = MPT_HOST_NO_CHAIN;
 186	int	 sgeOffset;
 187	int	 numSgeSlots, numSgeThisFrame;
 188	u32	 sgflags, sgdir, thisxfer = 0;
 189	int	 chain_dma_off = 0;
 190	int	 newIndex;
 191	int	 ii;
 192	dma_addr_t v2;
 193	u32	RequestNB;
 194
 195	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
 196	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
 197		sgdir = MPT_TRANSFER_HOST_TO_IOC;
 198	} else {
 199		sgdir = MPT_TRANSFER_IOC_TO_HOST;
 200	}
 201
 202	psge = (char *) &pReq->SGL;
 203	frm_sz = ioc->req_sz;
 204
 205	/* Map the data portion, if any.
 206	 * sges_left  = 0 if no data transfer.
 207	 */
 208	sges_left = scsi_dma_map(SCpnt);
 209	if (sges_left < 0)
 210		return FAILED;
 211
 212	/* Handle the SG case.
 213	 */
 214	sg = scsi_sglist(SCpnt);
 215	sg_done  = 0;
 216	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
 217	chainSge = NULL;
 218
 219	/* Prior to entering this loop - the following must be set
 220	 * current MF:  sgeOffset (bytes)
 221	 *              chainSge (Null if original MF is not a chain buffer)
 222	 *              sg_done (num SGE done for this MF)
 223	 */
 224
 225nextSGEset:
 226	numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
 227	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
 228
 229	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
 230
 231	/* Get first (num - 1) SG elements
 232	 * Skip any SG entries with a length of 0
 233	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
 234	 */
 235	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
 236		thisxfer = sg_dma_len(sg);
 237		if (thisxfer == 0) {
 238			/* Get next SG element from the OS */
 239			sg = sg_next(sg);
 240			sg_done++;
 241			continue;
 242		}
 243
 244		v2 = sg_dma_address(sg);
 245		ioc->add_sge(psge, sgflags | thisxfer, v2);
 246
 247		/* Get next SG element from the OS */
 248		sg = sg_next(sg);
 249		psge += ioc->SGE_size;
 250		sgeOffset += ioc->SGE_size;
 251		sg_done++;
 252	}
 253
 254	if (numSgeThisFrame == sges_left) {
 255		/* Add last element, end of buffer and end of list flags.
 256		 */
 257		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
 258				MPT_SGE_FLAGS_END_OF_BUFFER |
 259				MPT_SGE_FLAGS_END_OF_LIST;
 260
 261		/* Add last SGE and set termination flags.
 262		 * Note: Last SGE may have a length of 0 - which should be ok.
 263		 */
 264		thisxfer = sg_dma_len(sg);
 265
 266		v2 = sg_dma_address(sg);
 267		ioc->add_sge(psge, sgflags | thisxfer, v2);
 268		sgeOffset += ioc->SGE_size;
 269		sg_done++;
 270
 271		if (chainSge) {
 272			/* The current buffer is a chain buffer,
 273			 * but there is not another one.
 274			 * Update the chain element
 275			 * Offset and Length fields.
 276			 */
 277			ioc->add_chain((char *)chainSge, 0, sgeOffset,
 278				ioc->ChainBufferDMA + chain_dma_off);
 279		} else {
 280			/* The current buffer is the original MF
 281			 * and there is no Chain buffer.
 282			 */
 283			pReq->ChainOffset = 0;
 284			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 285			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 286			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 287			ioc->RequestNB[req_idx] = RequestNB;
 288		}
 289	} else {
 290		/* At least one chain buffer is needed.
 291		 * Complete the first MF
 292		 *  - last SGE element, set the LastElement bit
 293		 *  - set ChainOffset (words) for orig MF
 294		 *             (OR finish previous MF chain buffer)
 295		 *  - update MFStructPtr ChainIndex
 296		 *  - Populate chain element
 297		 * Also
 298		 * Loop until done.
 299		 */
 300
 301		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
 302				ioc->name, sg_done));
 303
 304		/* Set LAST_ELEMENT flag for last non-chain element
 305		 * in the buffer. Since psge points at the NEXT
 306		 * SGE element, go back one SGE element, update the flags
 307		 * and reset the pointer. (Note: sgflags & thisxfer are already
 308		 * set properly).
 309		 */
 310		if (sg_done) {
 311			u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
 312			sgflags = le32_to_cpu(*ptmp);
 313			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
 314			*ptmp = cpu_to_le32(sgflags);
 315		}
 316
 317		if (chainSge) {
 318			/* The current buffer is a chain buffer.
 319			 * chainSge points to the previous Chain Element.
 320			 * Update its chain element Offset and Length (must
 321			 * include chain element size) fields.
 322			 * Old chain element is now complete.
 323			 */
 324			u8 nextChain = (u8) (sgeOffset >> 2);
 325			sgeOffset += ioc->SGE_size;
 326			ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
 327					 ioc->ChainBufferDMA + chain_dma_off);
 328		} else {
 329			/* The original MF buffer requires a chain buffer -
 330			 * set the offset.
 331			 * Last element in this MF is a chain element.
 332			 */
 333			pReq->ChainOffset = (u8) (sgeOffset >> 2);
 334			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 335			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 336			ioc->RequestNB[req_idx] = RequestNB;
 337		}
 338
 339		sges_left -= sg_done;
 340
 341
 342		/* NOTE: psge points to the beginning of the chain element
 343		 * in current buffer. Get a chain buffer.
 344		 */
 345		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
 346			dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 347			    "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
 348 			    ioc->name, pReq->CDB[0], SCpnt));
 349			return FAILED;
 350		}
 351
 352		/* Update the tracking arrays.
 353		 * If chainSge == NULL, update ReqToChain, else ChainToChain
 354		 */
 355		if (chainSge) {
 356			ioc->ChainToChain[chain_idx] = newIndex;
 357		} else {
 358			ioc->ReqToChain[req_idx] = newIndex;
 359		}
 360		chain_idx = newIndex;
 361		chain_dma_off = ioc->req_sz * chain_idx;
 362
 363		/* Populate the chainSGE for the current buffer.
 364		 * - Set chain buffer pointer to psge and fill
 365		 *   out the Address and Flags fields.
 366		 */
 367		chainSge = (char *) psge;
 368		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Current buff @ %p (index 0x%x)",
 369		    ioc->name, psge, req_idx));
 370
 371		/* Start the SGE for the next buffer
 372		 */
 373		psge = (char *) (ioc->ChainBuffer + chain_dma_off);
 374		sgeOffset = 0;
 375		sg_done = 0;
 376
 377		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Chain buff @ %p (index 0x%x)\n",
 378		    ioc->name, psge, chain_idx));
 379
 380		/* Start the SGE for the next buffer
 381		 */
 382
 383		goto nextSGEset;
 384	}
 385
 386	return SUCCESS;
 387} /* mptscsih_AddSGE() */
 388
 389static void
 390mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
 391    U32 SlotStatus)
 392{
 393	MPT_FRAME_HDR *mf;
 394	SEPRequest_t 	 *SEPMsg;
 395
 396	if (ioc->bus_type != SAS)
 397		return;
 398
 399	/* Not supported for hidden raid components
 400	 */
 401	if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
 402		return;
 403
 404	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
 405		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
 406		    ioc->name,__func__));
 407		return;
 408	}
 409
 410	SEPMsg = (SEPRequest_t *)mf;
 411	SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
 412	SEPMsg->Bus = vtarget->channel;
 413	SEPMsg->TargetID = vtarget->id;
 414	SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
 415	SEPMsg->SlotStatus = SlotStatus;
 416	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 417	    "Sending SEP cmd=%x channel=%d id=%d\n",
 418	    ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
 419	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 420}
 421
 422#ifdef CONFIG_FUSION_LOGGING
 423/**
 424 *	mptscsih_info_scsiio - debug print info on reply frame
 425 *	@ioc: Pointer to MPT_ADAPTER structure
 426 *	@sc: original scsi cmnd pointer
 427 *	@pScsiReply: Pointer to MPT reply frame
 428 *
 429 *	MPT_DEBUG_REPLY needs to be enabled to obtain this info
 430 *
 431 *	Refer to lsi/mpi.h.
 432 **/
 433static void
 434mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
 435{
 436	char	*desc = NULL;
 437	char	*desc1 = NULL;
 438	u16	ioc_status;
 439	u8	skey, asc, ascq;
 440
 441	ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 442
 443	switch (ioc_status) {
 444
 445	case MPI_IOCSTATUS_SUCCESS:
 446		desc = "success";
 447		break;
 448	case MPI_IOCSTATUS_SCSI_INVALID_BUS:
 449		desc = "invalid bus";
 450		break;
 451	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
 452		desc = "invalid target_id";
 453		break;
 454	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
 455		desc = "device not there";
 456		break;
 457	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
 458		desc = "data overrun";
 459		break;
 460	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
 461		desc = "data underrun";
 462		break;
 463	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
 464		desc = "I/O data error";
 465		break;
 466	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
 467		desc = "protocol error";
 468		break;
 469	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
 470		desc = "task terminated";
 471		break;
 472	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
 473		desc = "residual mismatch";
 474		break;
 475	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
 476		desc = "task management failed";
 477		break;
 478	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
 479		desc = "IOC terminated";
 480		break;
 481	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
 482		desc = "ext terminated";
 483		break;
 484	default:
 485		desc = "";
 486		break;
 487	}
 488
 489	switch (pScsiReply->SCSIStatus)
 490	{
 491
 492	case MPI_SCSI_STATUS_SUCCESS:
 493		desc1 = "success";
 494		break;
 495	case MPI_SCSI_STATUS_CHECK_CONDITION:
 496		desc1 = "check condition";
 497		break;
 498	case MPI_SCSI_STATUS_CONDITION_MET:
 499		desc1 = "condition met";
 500		break;
 501	case MPI_SCSI_STATUS_BUSY:
 502		desc1 = "busy";
 503		break;
 504	case MPI_SCSI_STATUS_INTERMEDIATE:
 505		desc1 = "intermediate";
 506		break;
 507	case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
 508		desc1 = "intermediate condmet";
 509		break;
 510	case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
 511		desc1 = "reservation conflict";
 512		break;
 513	case MPI_SCSI_STATUS_COMMAND_TERMINATED:
 514		desc1 = "command terminated";
 515		break;
 516	case MPI_SCSI_STATUS_TASK_SET_FULL:
 517		desc1 = "task set full";
 518		break;
 519	case MPI_SCSI_STATUS_ACA_ACTIVE:
 520		desc1 = "aca active";
 521		break;
 522	case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
 523		desc1 = "fcpext device logged out";
 524		break;
 525	case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
 526		desc1 = "fcpext no link";
 527		break;
 528	case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
 529		desc1 = "fcpext unassigned";
 530		break;
 531	default:
 532		desc1 = "";
 533		break;
 534	}
 535
 536	scsi_print_command(sc);
 537	printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
 538	    ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
 539	printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
 540	    "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
 541	    scsi_get_resid(sc));
 542	printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
 543	    "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
 544	    le32_to_cpu(pScsiReply->TransferCount), sc->result);
 545
 546	printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
 547	    "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
 548	    ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
 549	    pScsiReply->SCSIState);
 550
 551	if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
 552		skey = sc->sense_buffer[2] & 0x0F;
 553		asc = sc->sense_buffer[12];
 554		ascq = sc->sense_buffer[13];
 555
 556		printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
 557		    "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
 558	}
 559
 560	/*
 561	 *  Look for + dump FCP ResponseInfo[]!
 562	 */
 563	if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 564	    pScsiReply->ResponseInfo)
 565		printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
 566		    ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
 567}
 568#endif
 569
 570/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 571/*
 572 *	mptscsih_io_done - Main SCSI IO callback routine registered to
 573 *	Fusion MPT (base) driver
 574 *	@ioc: Pointer to MPT_ADAPTER structure
 575 *	@mf: Pointer to original MPT request frame
 576 *	@r: Pointer to MPT reply frame (NULL if TurboReply)
 577 *
 578 *	This routine is called from mpt.c::mpt_interrupt() at the completion
 579 *	of any SCSI IO request.
 580 *	This routine is registered with the Fusion MPT (base) driver at driver
 581 *	load/init time via the mpt_register() API call.
 582 *
 583 *	Returns 1 indicating alloc'd request frame ptr should be freed.
 584 */
 585int
 586mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 587{
 588	struct scsi_cmnd	*sc;
 589	MPT_SCSI_HOST	*hd;
 590	SCSIIORequest_t	*pScsiReq;
 591	SCSIIOReply_t	*pScsiReply;
 592	u16		 req_idx, req_idx_MR;
 593	VirtDevice	 *vdevice;
 594	VirtTarget	 *vtarget;
 595
 596	hd = shost_priv(ioc->sh);
 597	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 598	req_idx_MR = (mr != NULL) ?
 599	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
 600
 601	/* Special case, where already freed message frame is received from
 602	 * Firmware. It happens with Resetting IOC.
 603	 * Return immediately. Do not care
 604	 */
 605	if ((req_idx != req_idx_MR) ||
 606	    (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
 607		return 0;
 608
 609	sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
 610	if (sc == NULL) {
 611		MPIHeader_t *hdr = (MPIHeader_t *)mf;
 612
 613		/* Remark: writeSDP1 will use the ScsiDoneCtx
 614		 * If a SCSI I/O cmd, device disabled by OS and
 615		 * completion done. Cannot touch sc struct. Just free mem.
 616		 */
 617		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
 618			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
 619			ioc->name);
 620
 621		mptscsih_freeChainBuffers(ioc, req_idx);
 622		return 1;
 623	}
 624
 625	if ((unsigned char *)mf != sc->host_scribble) {
 626		mptscsih_freeChainBuffers(ioc, req_idx);
 627		return 1;
 628	}
 629
 630	if (ioc->bus_type == SAS) {
 631		VirtDevice *vdevice = sc->device->hostdata;
 632
 633		if (!vdevice || !vdevice->vtarget ||
 634		    vdevice->vtarget->deleted) {
 635			sc->result = DID_NO_CONNECT << 16;
 636			goto out;
 637		}
 638	}
 639
 640	sc->host_scribble = NULL;
 641	sc->result = DID_OK << 16;		/* Set default reply as OK */
 642	pScsiReq = (SCSIIORequest_t *) mf;
 643	pScsiReply = (SCSIIOReply_t *) mr;
 644
 645	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
 646		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 647			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
 648			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
 649	}else{
 650		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 651			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
 652			ioc->name, mf, mr, sc, req_idx));
 653	}
 654
 655	if (pScsiReply == NULL) {
 656		/* special context reply handling */
 657		;
 658	} else {
 659		u32	 xfer_cnt;
 660		u16	 status;
 661		u8	 scsi_state, scsi_status;
 662		u32	 log_info;
 663
 664		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 665
 666		scsi_state = pScsiReply->SCSIState;
 667		scsi_status = pScsiReply->SCSIStatus;
 668		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
 669		scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 670		log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
 671
 672		/*
 673		 *  if we get a data underrun indication, yet no data was
 674		 *  transferred and the SCSI status indicates that the
 675		 *  command was never started, change the data underrun
 676		 *  to success
 677		 */
 678		if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
 679		    (scsi_status == MPI_SCSI_STATUS_BUSY ||
 680		     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
 681		     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
 682			status = MPI_IOCSTATUS_SUCCESS;
 683		}
 684
 685		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
 686			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
 687
 688		/*
 689		 *  Look for + dump FCP ResponseInfo[]!
 690		 */
 691		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 692		    pScsiReply->ResponseInfo) {
 693			printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
 694			"FCP_ResponseInfo=%08xh\n", ioc->name,
 695			sc->device->host->host_no, sc->device->channel,
 696			sc->device->id, sc->device->lun,
 697			le32_to_cpu(pScsiReply->ResponseInfo));
 698		}
 699
 700		switch(status) {
 701		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
 702		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 703			/* CHECKME!
 704			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
 705			 * But not: DID_BUS_BUSY lest one risk
 706			 * killing interrupt handler:-(
 707			 */
 708			sc->result = SAM_STAT_BUSY;
 709			break;
 710
 711		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
 712		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
 713			sc->result = DID_BAD_TARGET << 16;
 714			break;
 715
 716		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
 717			/* Spoof to SCSI Selection Timeout! */
 718			if (ioc->bus_type != FC)
 719				sc->result = DID_NO_CONNECT << 16;
 720			/* else fibre, just stall until rescan event */
 721			else
 722				sc->result = DID_REQUEUE << 16;
 723
 724			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
 725				hd->sel_timeout[pScsiReq->TargetID]++;
 726
 727			vdevice = sc->device->hostdata;
 728			if (!vdevice)
 729				break;
 730			vtarget = vdevice->vtarget;
 731			if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
 732				mptscsih_issue_sep_command(ioc, vtarget,
 733				    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
 734				vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
 735			}
 736			break;
 737
 738		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
 739			if ( ioc->bus_type == SAS ) {
 740				u16 ioc_status =
 741				    le16_to_cpu(pScsiReply->IOCStatus);
 742				if ((ioc_status &
 743					MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
 744					&&
 745					((log_info & SAS_LOGINFO_MASK) ==
 746					SAS_LOGINFO_NEXUS_LOSS)) {
 747						VirtDevice *vdevice =
 748						sc->device->hostdata;
 749
 750					    /* flag the device as being in
 751					     * device removal delay so we can
 752					     * notify the midlayer to hold off
 753					     * on timeout eh */
 754						if (vdevice && vdevice->
 755							vtarget &&
 756							vdevice->vtarget->
 757							raidVolume)
 758							printk(KERN_INFO
 759							"Skipping Raid Volume"
 760							"for inDMD\n");
 761						else if (vdevice &&
 762							vdevice->vtarget)
 763							vdevice->vtarget->
 764								inDMD = 1;
 765
 766					    sc->result =
 767						    (DID_TRANSPORT_DISRUPTED
 768						    << 16);
 769					    break;
 770				}
 771			} else if (ioc->bus_type == FC) {
 772				/*
 773				 * The FC IOC may kill a request for variety of
 774				 * reasons, some of which may be recovered by a
 775				 * retry, some which are unlikely to be
 776				 * recovered. Return DID_ERROR instead of
 777				 * DID_RESET to permit retry of the command,
 778				 * just not an infinite number of them
 779				 */
 780				sc->result = DID_ERROR << 16;
 781				break;
 782			}
 783
 784			/*
 785			 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
 786			 */
 787			fallthrough;
 788
 789		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
 790			/* Linux handles an unsolicited DID_RESET better
 791			 * than an unsolicited DID_ABORT.
 792			 */
 793			sc->result = DID_RESET << 16;
 794			break;
 795
 796		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
 797			if (ioc->bus_type == FC)
 798				sc->result = DID_ERROR << 16;
 799			else
 800				sc->result = DID_RESET << 16;
 801			break;
 802
 803		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 804			scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 805			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
 806				sc->result=DID_SOFT_ERROR << 16;
 807			else /* Sufficient data transfer occurred */
 808				sc->result = (DID_OK << 16) | scsi_status;
 809			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 810			    "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
 811			    ioc->name, sc->result, sc->device->channel, sc->device->id));
 812			break;
 813
 814		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 815			/*
 816			 *  Do upfront check for valid SenseData and give it
 817			 *  precedence!
 818			 */
 819			sc->result = (DID_OK << 16) | scsi_status;
 820			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
 821
 822				/*
 823				 * For an Errata on LSI53C1030
 824				 * When the length of request data
 825				 * and transfer data are different
 826				 * with result of command (READ or VERIFY),
 827				 * DID_SOFT_ERROR is set.
 828				 */
 829				if (ioc->bus_type == SPI) {
 830					if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
 831					    pScsiReq->CDB[0] == READ_10 ||
 832					    pScsiReq->CDB[0] == READ_12 ||
 833						(pScsiReq->CDB[0] == READ_16 &&
 834						((pScsiReq->CDB[1] & 0x02) == 0)) ||
 835					    pScsiReq->CDB[0] == VERIFY  ||
 836					    pScsiReq->CDB[0] == VERIFY_16) {
 837						if (scsi_bufflen(sc) !=
 838							xfer_cnt) {
 839							sc->result =
 840							DID_SOFT_ERROR << 16;
 841						    printk(KERN_WARNING "Errata"
 842						    "on LSI53C1030 occurred."
 843						    "sc->req_bufflen=0x%02x,"
 844						    "xfer_cnt=0x%02x\n",
 845						    scsi_bufflen(sc),
 846						    xfer_cnt);
 847						}
 848					}
 849				}
 850
 851				if (xfer_cnt < sc->underflow) {
 852					if (scsi_status == SAM_STAT_BUSY)
 853						sc->result = SAM_STAT_BUSY;
 854					else
 855						sc->result = DID_SOFT_ERROR << 16;
 856				}
 857				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
 858					/* What to do?
 859				 	*/
 860					sc->result = DID_SOFT_ERROR << 16;
 861				}
 862				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 863					/*  Not real sure here either...  */
 864					sc->result = DID_RESET << 16;
 865				}
 866			}
 867
 868
 869			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 870			    "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
 871			    ioc->name, sc->underflow));
 872			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 873			    "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
 874
 875			/* Report Queue Full
 876			 */
 877			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 878				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 879
 880			break;
 881
 882		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 883			scsi_set_resid(sc, 0);
 884			fallthrough;
 885		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
 886		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
 887			sc->result = (DID_OK << 16) | scsi_status;
 888			if (scsi_state == 0) {
 889				;
 890			} else if (scsi_state &
 891			    MPI_SCSI_STATE_AUTOSENSE_VALID) {
 892
 893				/*
 894				 * For potential trouble on LSI53C1030.
 895				 * (date:2007.xx.)
 896				 * It is checked whether the length of
 897				 * request data is equal to
 898				 * the length of transfer and residual.
 899				 * MEDIUM_ERROR is set by incorrect data.
 900				 */
 901				if ((ioc->bus_type == SPI) &&
 902					(sc->sense_buffer[2] & 0x20)) {
 903					u32	 difftransfer;
 904					difftransfer =
 905					sc->sense_buffer[3] << 24 |
 906					sc->sense_buffer[4] << 16 |
 907					sc->sense_buffer[5] << 8 |
 908					sc->sense_buffer[6];
 909					if (((sc->sense_buffer[3] & 0x80) ==
 910						0x80) && (scsi_bufflen(sc)
 911						!= xfer_cnt)) {
 912						sc->sense_buffer[2] =
 913						    MEDIUM_ERROR;
 914						sc->sense_buffer[12] = 0xff;
 915						sc->sense_buffer[13] = 0xff;
 916						printk(KERN_WARNING"Errata"
 917						"on LSI53C1030 occurred."
 918						"sc->req_bufflen=0x%02x,"
 919						"xfer_cnt=0x%02x\n" ,
 920						scsi_bufflen(sc),
 921						xfer_cnt);
 922					}
 923					if (((sc->sense_buffer[3] & 0x80)
 924						!= 0x80) &&
 925						(scsi_bufflen(sc) !=
 926						xfer_cnt + difftransfer)) {
 927						sc->sense_buffer[2] =
 928							MEDIUM_ERROR;
 929						sc->sense_buffer[12] = 0xff;
 930						sc->sense_buffer[13] = 0xff;
 931						printk(KERN_WARNING
 932						"Errata on LSI53C1030 occurred"
 933						"sc->req_bufflen=0x%02x,"
 934						" xfer_cnt=0x%02x,"
 935						"difftransfer=0x%02x\n",
 936						scsi_bufflen(sc),
 937						xfer_cnt,
 938						difftransfer);
 939					}
 940				}
 941
 942				/*
 943				 * If running against circa 200003dd 909 MPT f/w,
 944				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
 945				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
 946				 * and with SenseBytes set to 0.
 947				 */
 948				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
 949					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 950
 951			}
 952			else if (scsi_state &
 953			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
 954			   ) {
 955				/*
 956				 * What to do?
 957				 */
 958				sc->result = DID_SOFT_ERROR << 16;
 959			}
 960			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 961				/*  Not real sure here either...  */
 962				sc->result = DID_RESET << 16;
 963			}
 964			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
 965				/* Device Inq. data indicates that it supports
 966				 * QTags, but rejects QTag messages.
 967				 * This command completed OK.
 968				 *
 969				 * Not real sure here either so do nothing...  */
 970			}
 971
 972			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
 973				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 974
 975			/* Add handling of:
 976			 * Reservation Conflict, Busy,
 977			 * Command Terminated, CHECK
 978			 */
 979			break;
 980
 981		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
 982			sc->result = DID_SOFT_ERROR << 16;
 983			break;
 984
 985		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
 986		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
 987		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
 988		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
 989		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
 990		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
 991		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
 992		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
 993		default:
 994			/*
 995			 * What to do?
 996			 */
 997			sc->result = DID_SOFT_ERROR << 16;
 998			break;
 999
1000		}	/* switch(status) */
1001
1002#ifdef CONFIG_FUSION_LOGGING
1003		if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
1004			mptscsih_info_scsiio(ioc, sc, pScsiReply);
1005#endif
1006
1007	} /* end of address reply case */
1008out:
1009	/* Unmap the DMA buffers, if any. */
1010	scsi_dma_unmap(sc);
1011
1012	sc->scsi_done(sc);		/* Issue the command callback */
1013
1014	/* Free Chain buffers */
1015	mptscsih_freeChainBuffers(ioc, req_idx);
1016	return 1;
1017}
1018
1019/*
1020 *	mptscsih_flush_running_cmds - For each command found, search
1021 *		Scsi_Host instance taskQ and reply to OS.
1022 *		Called only if recovering from a FW reload.
1023 *	@hd: Pointer to a SCSI HOST structure
1024 *
1025 *	Returns: None.
1026 *
1027 *	Must be called while new I/Os are being queued.
1028 */
1029void
1030mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1031{
1032	MPT_ADAPTER *ioc = hd->ioc;
1033	struct scsi_cmnd *sc;
1034	SCSIIORequest_t	*mf = NULL;
1035	int		 ii;
1036	int		 channel, id;
1037
1038	for (ii= 0; ii < ioc->req_depth; ii++) {
1039		sc = mptscsih_getclear_scsi_lookup(ioc, ii);
1040		if (!sc)
1041			continue;
1042		mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1043		if (!mf)
1044			continue;
1045		channel = mf->Bus;
1046		id = mf->TargetID;
1047		mptscsih_freeChainBuffers(ioc, ii);
1048		mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1049		if ((unsigned char *)mf != sc->host_scribble)
1050			continue;
1051		scsi_dma_unmap(sc);
1052		sc->result = DID_RESET << 16;
1053		sc->host_scribble = NULL;
1054		dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
1055		    "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
1056		    "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
1057		sc->scsi_done(sc);
1058	}
1059}
1060EXPORT_SYMBOL(mptscsih_flush_running_cmds);
1061
1062/*
1063 *	mptscsih_search_running_cmds - Delete any commands associated
1064 *		with the specified target and lun. Function called only
1065 *		when a lun is disable by mid-layer.
1066 *		Do NOT access the referenced scsi_cmnd structure or
1067 *		members. Will cause either a paging or NULL ptr error.
1068 *		(BUT, BUT, BUT, the code does reference it! - mdr)
1069 *      @hd: Pointer to a SCSI HOST structure
1070 *	@vdevice: per device private data
1071 *
1072 *	Returns: None.
1073 *
1074 *	Called from slave_destroy.
1075 */
1076static void
1077mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1078{
1079	SCSIIORequest_t	*mf = NULL;
1080	int		 ii;
1081	struct scsi_cmnd *sc;
1082	struct scsi_lun  lun;
1083	MPT_ADAPTER *ioc = hd->ioc;
1084	unsigned long	flags;
1085
1086	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1087	for (ii = 0; ii < ioc->req_depth; ii++) {
1088		if ((sc = ioc->ScsiLookup[ii]) != NULL) {
1089
1090			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1091			if (mf == NULL)
1092				continue;
1093			/* If the device is a hidden raid component, then its
1094			 * expected that the mf->function will be RAID_SCSI_IO
1095			 */
1096			if (vdevice->vtarget->tflags &
1097			    MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1098			    MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1099				continue;
1100
1101			int_to_scsilun(vdevice->lun, &lun);
1102			if ((mf->Bus != vdevice->vtarget->channel) ||
1103			    (mf->TargetID != vdevice->vtarget->id) ||
1104			    memcmp(lun.scsi_lun, mf->LUN, 8))
1105				continue;
1106
1107			if ((unsigned char *)mf != sc->host_scribble)
1108				continue;
1109			ioc->ScsiLookup[ii] = NULL;
1110			spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1111			mptscsih_freeChainBuffers(ioc, ii);
1112			mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1113			scsi_dma_unmap(sc);
1114			sc->host_scribble = NULL;
1115			sc->result = DID_NO_CONNECT << 16;
1116			dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
1117			   MYIOC_s_FMT "completing cmds: fw_channel %d, "
1118			   "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1119			   vdevice->vtarget->channel, vdevice->vtarget->id,
1120			   sc, mf, ii));
1121			sc->scsi_done(sc);
1122			spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1123		}
1124	}
1125	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1126	return;
1127}
1128
1129/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1130
1131/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1132/*
1133 *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
1134 *	from a SCSI target device.
1135 *	@sc: Pointer to scsi_cmnd structure
1136 *	@pScsiReply: Pointer to SCSIIOReply_t
1137 *	@pScsiReq: Pointer to original SCSI request
1138 *
1139 *	This routine periodically reports QUEUE_FULL status returned from a
1140 *	SCSI target device.  It reports this to the console via kernel
1141 *	printk() API call, not more than once every 10 seconds.
1142 */
1143static void
1144mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1145{
1146	long time = jiffies;
1147	MPT_SCSI_HOST		*hd;
1148	MPT_ADAPTER	*ioc;
1149
1150	if (sc->device == NULL)
1151		return;
1152	if (sc->device->host == NULL)
1153		return;
1154	if ((hd = shost_priv(sc->device->host)) == NULL)
1155		return;
1156	ioc = hd->ioc;
1157	if (time - hd->last_queue_full > 10 * HZ) {
1158		dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
1159				ioc->name, 0, sc->device->id, sc->device->lun));
1160		hd->last_queue_full = time;
1161	}
1162}
1163
1164/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1165/*
1166 *	mptscsih_remove - Removed scsi devices
1167 *	@pdev: Pointer to pci_dev structure
1168 *
1169 *
1170 */
1171void
1172mptscsih_remove(struct pci_dev *pdev)
1173{
1174	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1175	struct Scsi_Host 	*host = ioc->sh;
1176	MPT_SCSI_HOST		*hd;
1177	int sz1;
1178
 
 
1179	if((hd = shost_priv(host)) == NULL)
1180		return;
1181
1182	mptscsih_shutdown(pdev);
1183
1184	sz1=0;
1185
1186	if (ioc->ScsiLookup != NULL) {
1187		sz1 = ioc->req_depth * sizeof(void *);
1188		kfree(ioc->ScsiLookup);
1189		ioc->ScsiLookup = NULL;
1190	}
1191
1192	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1193	    "Free'd ScsiLookup (%d) memory\n",
1194	    ioc->name, sz1));
1195
1196	kfree(hd->info_kbuf);
1197
1198	/* NULL the Scsi_Host pointer
1199	 */
1200	ioc->sh = NULL;
1201
1202	scsi_host_put(host);
1203
1204	mpt_detach(pdev);
1205
1206}
1207
1208/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1209/*
1210 *	mptscsih_shutdown - reboot notifier
1211 *
1212 */
1213void
1214mptscsih_shutdown(struct pci_dev *pdev)
1215{
1216}
1217
1218#ifdef CONFIG_PM
1219/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1220/*
1221 *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1222 *
1223 *
1224 */
1225int
1226mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1227{
1228	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1229
1230	scsi_block_requests(ioc->sh);
1231	flush_scheduled_work();
1232	mptscsih_shutdown(pdev);
1233	return mpt_suspend(pdev,state);
1234}
1235
1236/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1237/*
1238 *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1239 *
1240 *
1241 */
1242int
1243mptscsih_resume(struct pci_dev *pdev)
1244{
1245	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1246	int rc;
1247
1248	rc = mpt_resume(pdev);
1249	scsi_unblock_requests(ioc->sh);
1250	return rc;
1251}
1252
1253#endif
1254
1255/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1256/**
1257 *	mptscsih_info - Return information about MPT adapter
1258 *	@SChost: Pointer to Scsi_Host structure
1259 *
1260 *	(linux scsi_host_template.info routine)
1261 *
1262 *	Returns pointer to buffer where information was written.
1263 */
1264const char *
1265mptscsih_info(struct Scsi_Host *SChost)
1266{
1267	MPT_SCSI_HOST *h;
1268	int size = 0;
1269
1270	h = shost_priv(SChost);
1271
1272	if (h->info_kbuf == NULL)
1273		if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1274			return h->info_kbuf;
1275	h->info_kbuf[0] = '\0';
 
1276
1277	mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1278	h->info_kbuf[size-1] = '\0';
 
1279
1280	return h->info_kbuf;
1281}
1282
1283int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1284{
1285	MPT_SCSI_HOST	*hd = shost_priv(host);
1286	MPT_ADAPTER	*ioc = hd->ioc;
 
1287
1288	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1289	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1290	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1291	seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
 
 
 
1292
1293	return 0;
 
 
 
1294}
1295
1296/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1297#define ADD_INDEX_LOG(req_ent)	do { } while(0)
1298
1299/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300/**
1301 *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1302 *	@SCpnt: Pointer to scsi_cmnd structure
 
1303 *
1304 *	(linux scsi_host_template.queuecommand routine)
1305 *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1306 *	from a linux scsi_cmnd request and send it to the IOC.
1307 *
1308 *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1309 */
1310int
1311mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1312{
1313	MPT_SCSI_HOST		*hd;
1314	MPT_FRAME_HDR		*mf;
1315	SCSIIORequest_t		*pScsiReq;
1316	VirtDevice		*vdevice = SCpnt->device->hostdata;
1317	u32	 datalen;
1318	u32	 scsictl;
1319	u32	 scsidir;
1320	u32	 cmd_len;
1321	int	 my_idx;
1322	int	 ii;
1323	MPT_ADAPTER *ioc;
1324
1325	hd = shost_priv(SCpnt->device->host);
1326	ioc = hd->ioc;
 
1327
1328	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1329		ioc->name, SCpnt));
1330
1331	if (ioc->taskmgmt_quiesce_io)
1332		return SCSI_MLQUEUE_HOST_BUSY;
1333
1334	/*
1335	 *  Put together a MPT SCSI request...
1336	 */
1337	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1338		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1339				ioc->name));
1340		return SCSI_MLQUEUE_HOST_BUSY;
1341	}
1342
1343	pScsiReq = (SCSIIORequest_t *) mf;
1344
1345	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1346
1347	ADD_INDEX_LOG(my_idx);
1348
1349	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1350	 *    Seems we may receive a buffer (datalen>0) even when there
1351	 *    will be no data transfer!  GRRRRR...
1352	 */
1353	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1354		datalen = scsi_bufflen(SCpnt);
1355		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1356	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1357		datalen = scsi_bufflen(SCpnt);
1358		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1359	} else {
1360		datalen = 0;
1361		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1362	}
1363
1364	/* Default to untagged. Once a target structure has been allocated,
1365	 * use the Inquiry data to determine if device supports tagged.
1366	 */
1367	if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1368	    SCpnt->device->tagged_supported)
 
1369		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1370	else
 
 
 
 
 
1371		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1372
1373
1374	/* Use the above information to set up the message frame
1375	 */
1376	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1377	pScsiReq->Bus = vdevice->vtarget->channel;
1378	pScsiReq->ChainOffset = 0;
1379	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1380		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1381	else
1382		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1383	pScsiReq->CDBLength = SCpnt->cmd_len;
1384	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1385	pScsiReq->Reserved = 0;
1386	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1387	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1388	pScsiReq->Control = cpu_to_le32(scsictl);
1389
1390	/*
1391	 *  Write SCSI CDB into the message
1392	 */
1393	cmd_len = SCpnt->cmd_len;
1394	for (ii=0; ii < cmd_len; ii++)
1395		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1396
1397	for (ii=cmd_len; ii < 16; ii++)
1398		pScsiReq->CDB[ii] = 0;
1399
1400	/* DataLength */
1401	pScsiReq->DataLength = cpu_to_le32(datalen);
1402
1403	/* SenseBuffer low address */
1404	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1405					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1406
1407	/* Now add the SG list
1408	 * Always have a SGE even if null length.
1409	 */
1410	if (datalen == 0) {
1411		/* Add a NULL SGE */
1412		ioc->add_sge((char *)&pScsiReq->SGL,
1413			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1414			(dma_addr_t) -1);
1415	} else {
1416		/* Add a 32 or 64 bit SGE */
1417		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1418			goto fail;
1419	}
1420
1421	SCpnt->host_scribble = (unsigned char *)mf;
1422	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1423
1424	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1425	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1426			ioc->name, SCpnt, mf, my_idx));
1427	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1428	return 0;
1429
1430 fail:
1431	mptscsih_freeChainBuffers(ioc, my_idx);
1432	mpt_free_msg_frame(ioc, mf);
1433	return SCSI_MLQUEUE_HOST_BUSY;
1434}
1435
1436/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1437/*
1438 *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1439 *	with a SCSI IO request
1440 *	@hd: Pointer to the MPT_SCSI_HOST instance
1441 *	@req_idx: Index of the SCSI IO request frame.
1442 *
1443 *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1444 *	No return.
1445 */
1446static void
1447mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1448{
1449	MPT_FRAME_HDR *chain;
1450	unsigned long flags;
1451	int chain_idx;
1452	int next;
1453
1454	/* Get the first chain index and reset
1455	 * tracker state.
1456	 */
1457	chain_idx = ioc->ReqToChain[req_idx];
1458	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1459
1460	while (chain_idx != MPT_HOST_NO_CHAIN) {
1461
1462		/* Save the next chain buffer index */
1463		next = ioc->ChainToChain[chain_idx];
1464
1465		/* Free this chain buffer and reset
1466		 * tracker
1467		 */
1468		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1469
1470		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1471					+ (chain_idx * ioc->req_sz));
1472
1473		spin_lock_irqsave(&ioc->FreeQlock, flags);
1474		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1475		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1476
1477		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1478				ioc->name, chain_idx));
1479
1480		/* handle next */
1481		chain_idx = next;
1482	}
1483	return;
1484}
1485
1486/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487/*
1488 *	Reset Handling
1489 */
1490
1491/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492/**
1493 *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1494 *	@hd: Pointer to MPT_SCSI_HOST structure
1495 *	@type: Task Management type
1496 *	@channel: channel number for task management
1497 *	@id: Logical Target ID for reset (if appropriate)
1498 *	@lun: Logical Unit for reset (if appropriate)
1499 *	@ctx2abort: Context for the task to be aborted (if appropriate)
1500 *	@timeout: timeout for task management control
1501 *
1502 *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1503 *	or a non-interrupt thread.  In the former, must not call schedule().
1504 *
1505 *	Not all fields are meaningfull for all task types.
1506 *
1507 *	Returns 0 for SUCCESS, or FAILED.
1508 *
1509 **/
1510int
1511mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1512	int ctx2abort, ulong timeout)
1513{
1514	MPT_FRAME_HDR	*mf;
1515	SCSITaskMgmt_t	*pScsiTm;
1516	int		 ii;
1517	int		 retval;
1518	MPT_ADAPTER 	*ioc = hd->ioc;
1519	unsigned long	 timeleft;
1520	u8		 issue_hard_reset;
1521	u32		 ioc_raw_state;
1522	unsigned long	 time_count;
1523
1524	issue_hard_reset = 0;
1525	ioc_raw_state = mpt_GetIocState(ioc, 0);
1526
1527	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1528		printk(MYIOC_s_WARN_FMT
1529			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1530			ioc->name, type, ioc_raw_state);
1531		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1532		    ioc->name, __func__);
1533		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1534			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1535			    "FAILED!!\n", ioc->name);
1536		return 0;
1537	}
1538
1539	/* DOORBELL ACTIVE check is not required if
1540	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1541	*/
1542
1543	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1544		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1545		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1546		printk(MYIOC_s_WARN_FMT
1547			"TaskMgmt type=%x: ioc_state: "
1548			"DOORBELL_ACTIVE (0x%x)!\n",
1549			ioc->name, type, ioc_raw_state);
1550		return FAILED;
1551	}
1552
1553	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1554	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1555		mf = NULL;
1556		retval = FAILED;
1557		goto out;
1558	}
1559
1560	/* Return Fail to calling function if no message frames available.
1561	 */
1562	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1563		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1564			"TaskMgmt no msg frames!!\n", ioc->name));
1565		retval = FAILED;
1566		mpt_clear_taskmgmt_in_progress_flag(ioc);
1567		goto out;
1568	}
1569	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1570			ioc->name, mf));
1571
1572	/* Format the Request
1573	 */
1574	pScsiTm = (SCSITaskMgmt_t *) mf;
1575	pScsiTm->TargetID = id;
1576	pScsiTm->Bus = channel;
1577	pScsiTm->ChainOffset = 0;
1578	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1579
1580	pScsiTm->Reserved = 0;
1581	pScsiTm->TaskType = type;
1582	pScsiTm->Reserved1 = 0;
1583	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1584                    ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1585
1586	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1587
1588	for (ii=0; ii < 7; ii++)
1589		pScsiTm->Reserved2[ii] = 0;
1590
1591	pScsiTm->TaskMsgContext = ctx2abort;
1592
1593	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1594		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1595		type, timeout));
1596
1597	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1598
1599	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1600	time_count = jiffies;
1601	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1602	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1603		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1604	else {
1605		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1606			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1607		if (retval) {
1608			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1609				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1610				ioc->name, mf, retval));
1611			mpt_free_msg_frame(ioc, mf);
1612			mpt_clear_taskmgmt_in_progress_flag(ioc);
1613			goto out;
1614		}
1615	}
1616
1617	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1618		timeout*HZ);
1619	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1620		retval = FAILED;
1621		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1622		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1623		mpt_clear_taskmgmt_in_progress_flag(ioc);
1624		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1625			goto out;
1626		issue_hard_reset = 1;
1627		goto out;
1628	}
1629
1630	retval = mptscsih_taskmgmt_reply(ioc, type,
1631	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1632
1633	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1634	    "TaskMgmt completed (%d seconds)\n",
1635	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1636
1637 out:
1638
1639	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1640	if (issue_hard_reset) {
1641		printk(MYIOC_s_WARN_FMT
1642		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1643		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1644		retval = (ioc->bus_type == SAS) ?
1645			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1646			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1647		mpt_free_msg_frame(ioc, mf);
1648	}
1649
1650	retval = (retval == 0) ? 0 : FAILED;
1651	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1652	return retval;
1653}
1654EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1655
1656static int
1657mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1658{
1659	switch (ioc->bus_type) {
1660	case FC:
1661		return 40;
1662	case SAS:
1663		return 30;
1664	case SPI:
1665	default:
1666		return 10;
1667	}
1668}
1669
1670/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1671/**
1672 *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1673 *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1674 *
1675 *	(linux scsi_host_template.eh_abort_handler routine)
1676 *
1677 *	Returns SUCCESS or FAILED.
1678 **/
1679int
1680mptscsih_abort(struct scsi_cmnd * SCpnt)
1681{
1682	MPT_SCSI_HOST	*hd;
1683	MPT_FRAME_HDR	*mf;
1684	u32		 ctx2abort;
1685	int		 scpnt_idx;
1686	int		 retval;
1687	VirtDevice	 *vdevice;
1688	MPT_ADAPTER	*ioc;
1689
1690	/* If we can't locate our host adapter structure, return FAILED status.
1691	 */
1692	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1693		SCpnt->result = DID_RESET << 16;
1694		SCpnt->scsi_done(SCpnt);
1695		printk(KERN_ERR MYNAM ": task abort: "
1696		    "can't locate host! (sc=%p)\n", SCpnt);
1697		return FAILED;
1698	}
1699
1700	ioc = hd->ioc;
1701	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1702	       ioc->name, SCpnt);
1703	scsi_print_command(SCpnt);
1704
1705	vdevice = SCpnt->device->hostdata;
1706	if (!vdevice || !vdevice->vtarget) {
1707		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1708		    "task abort: device has been deleted (sc=%p)\n",
1709		    ioc->name, SCpnt));
1710		SCpnt->result = DID_NO_CONNECT << 16;
1711		SCpnt->scsi_done(SCpnt);
1712		retval = SUCCESS;
1713		goto out;
1714	}
1715
1716	/* Task aborts are not supported for hidden raid components.
1717	 */
1718	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1719		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1720		    "task abort: hidden raid component (sc=%p)\n",
1721		    ioc->name, SCpnt));
1722		SCpnt->result = DID_RESET << 16;
1723		retval = FAILED;
1724		goto out;
1725	}
1726
1727	/* Task aborts are not supported for volumes.
1728	 */
1729	if (vdevice->vtarget->raidVolume) {
1730		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1731		    "task abort: raid volume (sc=%p)\n",
1732		    ioc->name, SCpnt));
1733		SCpnt->result = DID_RESET << 16;
1734		retval = FAILED;
1735		goto out;
1736	}
1737
1738	/* Find this command
1739	 */
1740	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1741		/* Cmd not found in ScsiLookup.
1742		 * Do OS callback.
1743		 */
1744		SCpnt->result = DID_RESET << 16;
1745		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1746		   "Command not in the active list! (sc=%p)\n", ioc->name,
1747		   SCpnt));
1748		retval = SUCCESS;
1749		goto out;
1750	}
1751
1752	if (ioc->timeouts < -1)
1753		ioc->timeouts++;
1754
1755	if (mpt_fwfault_debug)
1756		mpt_halt_firmware(ioc);
1757
1758	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1759	 * (the IO to be ABORT'd)
1760	 *
1761	 * NOTE: Since we do not byteswap MsgContext, we do not
1762	 *	 swap it here either.  It is an opaque cookie to
1763	 *	 the controller, so it does not matter. -DaveM
1764	 */
1765	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1766	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1767	retval = mptscsih_IssueTaskMgmt(hd,
1768			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1769			 vdevice->vtarget->channel,
1770			 vdevice->vtarget->id, vdevice->lun,
1771			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1772
1773	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1774		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1775		    "task abort: command still in active list! (sc=%p)\n",
1776		    ioc->name, SCpnt));
1777		retval = FAILED;
1778	} else {
1779		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1780		    "task abort: command cleared from active list! (sc=%p)\n",
1781		    ioc->name, SCpnt));
1782		retval = SUCCESS;
1783	}
1784
1785 out:
1786	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1787	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1788	    SCpnt);
1789
1790	return retval;
1791}
1792
1793/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1794/**
1795 *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1796 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1797 *
1798 *	(linux scsi_host_template.eh_dev_reset_handler routine)
1799 *
1800 *	Returns SUCCESS or FAILED.
1801 **/
1802int
1803mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1804{
1805	MPT_SCSI_HOST	*hd;
1806	int		 retval;
1807	VirtDevice	 *vdevice;
1808	MPT_ADAPTER	*ioc;
1809
1810	/* If we can't locate our host adapter structure, return FAILED status.
1811	 */
1812	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1813		printk(KERN_ERR MYNAM ": target reset: "
1814		   "Can't locate host! (sc=%p)\n", SCpnt);
1815		return FAILED;
1816	}
1817
1818	ioc = hd->ioc;
1819	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1820	       ioc->name, SCpnt);
1821	scsi_print_command(SCpnt);
1822
1823	vdevice = SCpnt->device->hostdata;
1824	if (!vdevice || !vdevice->vtarget) {
1825		retval = 0;
1826		goto out;
1827	}
1828
1829	/* Target reset to hidden raid component is not supported
1830	 */
1831	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1832		retval = FAILED;
1833		goto out;
1834	}
1835
1836	retval = mptscsih_IssueTaskMgmt(hd,
1837				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1838				vdevice->vtarget->channel,
1839				vdevice->vtarget->id, 0, 0,
1840				mptscsih_get_tm_timeout(ioc));
1841
1842 out:
1843	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1844	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1845
1846	if (retval == 0)
1847		return SUCCESS;
1848	else
1849		return FAILED;
1850}
1851
1852
1853/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1854/**
1855 *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1856 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1857 *
1858 *	(linux scsi_host_template.eh_bus_reset_handler routine)
1859 *
1860 *	Returns SUCCESS or FAILED.
1861 **/
1862int
1863mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1864{
1865	MPT_SCSI_HOST	*hd;
1866	int		 retval;
1867	VirtDevice	 *vdevice;
1868	MPT_ADAPTER	*ioc;
1869
1870	/* If we can't locate our host adapter structure, return FAILED status.
1871	 */
1872	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1873		printk(KERN_ERR MYNAM ": bus reset: "
1874		   "Can't locate host! (sc=%p)\n", SCpnt);
1875		return FAILED;
1876	}
1877
1878	ioc = hd->ioc;
1879	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1880	       ioc->name, SCpnt);
1881	scsi_print_command(SCpnt);
1882
1883	if (ioc->timeouts < -1)
1884		ioc->timeouts++;
1885
1886	vdevice = SCpnt->device->hostdata;
1887	if (!vdevice || !vdevice->vtarget)
1888		return SUCCESS;
1889	retval = mptscsih_IssueTaskMgmt(hd,
1890					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1891					vdevice->vtarget->channel, 0, 0, 0,
1892					mptscsih_get_tm_timeout(ioc));
1893
1894	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1895	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1896
1897	if (retval == 0)
1898		return SUCCESS;
1899	else
1900		return FAILED;
1901}
1902
1903/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1904/**
1905 *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1906 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1907 *
1908 *	(linux scsi_host_template.eh_host_reset_handler routine)
1909 *
1910 *	Returns SUCCESS or FAILED.
1911 */
1912int
1913mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1914{
1915	MPT_SCSI_HOST *  hd;
1916	int              status = SUCCESS;
1917	MPT_ADAPTER	*ioc;
1918	int		retval;
1919
1920	/*  If we can't locate the host to reset, then we failed. */
1921	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1922		printk(KERN_ERR MYNAM ": host reset: "
1923		    "Can't locate host! (sc=%p)\n", SCpnt);
1924		return FAILED;
1925	}
1926
1927	/* make sure we have no outstanding commands at this stage */
1928	mptscsih_flush_running_cmds(hd);
1929
1930	ioc = hd->ioc;
1931	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1932	    ioc->name, SCpnt);
1933
1934	/*  If our attempts to reset the host failed, then return a failed
1935	 *  status.  The host will be taken off line by the SCSI mid-layer.
1936	 */
1937	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1938	if (retval < 0)
1939		status = FAILED;
1940	else
1941		status = SUCCESS;
1942
1943	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1944	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1945
1946	return status;
1947}
1948
1949static int
1950mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1951	SCSITaskMgmtReply_t *pScsiTmReply)
1952{
1953	u16			 iocstatus;
1954	u32			 termination_count;
1955	int			 retval;
1956
1957	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1958		retval = FAILED;
1959		goto out;
1960	}
1961
1962	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1963
1964	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1965	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1966
1967	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1968	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1969	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1970	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1971	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1972	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1973	    termination_count));
1974
1975	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1976	    pScsiTmReply->ResponseCode)
1977		mptscsih_taskmgmt_response_code(ioc,
1978		    pScsiTmReply->ResponseCode);
1979
1980	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1981		retval = 0;
1982		goto out;
1983	}
1984
1985	retval = FAILED;
1986	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1987		if (termination_count == 1)
1988			retval = 0;
1989		goto out;
1990	}
1991
1992	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1993	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1994		retval = 0;
1995
1996 out:
1997	return retval;
1998}
1999
2000/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2001void
2002mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2003{
2004	char *desc;
2005
2006	switch (response_code) {
2007	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2008		desc = "The task completed.";
2009		break;
2010	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2011		desc = "The IOC received an invalid frame status.";
2012		break;
2013	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2014		desc = "The task type is not supported.";
2015		break;
2016	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2017		desc = "The requested task failed.";
2018		break;
2019	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2020		desc = "The task completed successfully.";
2021		break;
2022	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2023		desc = "The LUN request is invalid.";
2024		break;
2025	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2026		desc = "The task is in the IOC queue and has not been sent to target.";
2027		break;
2028	default:
2029		desc = "unknown";
2030		break;
2031	}
2032	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2033		ioc->name, response_code, desc);
2034}
2035EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2036
2037/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2038/**
2039 *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2040 *	@ioc: Pointer to MPT_ADAPTER structure
2041 *	@mf: Pointer to SCSI task mgmt request frame
2042 *	@mr: Pointer to SCSI task mgmt reply frame
2043 *
2044 *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2045 *	of any SCSI task management request.
2046 *	This routine is registered with the MPT (base) driver at driver
2047 *	load/init time via the mpt_register() API call.
2048 *
2049 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2050 **/
2051int
2052mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2053	MPT_FRAME_HDR *mr)
2054{
2055	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2056		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2057
2058	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2059
2060	if (!mr)
2061		goto out;
2062
2063	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2064	memcpy(ioc->taskmgmt_cmds.reply, mr,
2065	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2066 out:
2067	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2068		mpt_clear_taskmgmt_in_progress_flag(ioc);
2069		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2070		complete(&ioc->taskmgmt_cmds.done);
2071		if (ioc->bus_type == SAS)
2072			ioc->schedule_target_reset(ioc);
2073		return 1;
2074	}
2075	return 0;
2076}
2077
2078/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2079/*
2080 *	This is anyones guess quite frankly.
2081 */
2082int
2083mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2084		sector_t capacity, int geom[])
2085{
2086	int		heads;
2087	int		sectors;
2088	sector_t	cylinders;
2089	ulong 		dummy;
2090
2091	heads = 64;
2092	sectors = 32;
2093
2094	dummy = heads * sectors;
2095	cylinders = capacity;
2096	sector_div(cylinders,dummy);
2097
2098	/*
2099	 * Handle extended translation size for logical drives
2100	 * > 1Gb
2101	 */
2102	if ((ulong)capacity >= 0x200000) {
2103		heads = 255;
2104		sectors = 63;
2105		dummy = heads * sectors;
2106		cylinders = capacity;
2107		sector_div(cylinders,dummy);
2108	}
2109
2110	/* return result */
2111	geom[0] = heads;
2112	geom[1] = sectors;
2113	geom[2] = cylinders;
2114
2115	return 0;
2116}
2117
2118/* Search IOC page 3 to determine if this is hidden physical disk
2119 *
2120 */
2121int
2122mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2123{
2124	struct inactive_raid_component_info *component_info;
2125	int i, j;
2126	RaidPhysDiskPage1_t *phys_disk;
2127	int rc = 0;
2128	int num_paths;
2129
2130	if (!ioc->raid_data.pIocPg3)
2131		goto out;
2132	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2133		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2134		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2135			rc = 1;
2136			goto out;
2137		}
2138	}
2139
2140	if (ioc->bus_type != SAS)
2141		goto out;
2142
2143	/*
2144	 * Check if dual path
2145	 */
2146	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2147		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2148		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2149		if (num_paths < 2)
2150			continue;
2151		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2152		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2153		if (!phys_disk)
2154			continue;
2155		if ((mpt_raid_phys_disk_pg1(ioc,
2156		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2157		    phys_disk))) {
2158			kfree(phys_disk);
2159			continue;
2160		}
2161		for (j = 0; j < num_paths; j++) {
2162			if ((phys_disk->Path[j].Flags &
2163			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2164				continue;
2165			if ((phys_disk->Path[j].Flags &
2166			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2167				continue;
2168			if ((id == phys_disk->Path[j].PhysDiskID) &&
2169			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2170				rc = 1;
2171				kfree(phys_disk);
2172				goto out;
2173			}
2174		}
2175		kfree(phys_disk);
2176	}
2177
2178
2179	/*
2180	 * Check inactive list for matching phys disks
2181	 */
2182	if (list_empty(&ioc->raid_data.inactive_list))
2183		goto out;
2184
2185	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2186	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2187	    list) {
2188		if ((component_info->d.PhysDiskID == id) &&
2189		    (component_info->d.PhysDiskBus == channel))
2190			rc = 1;
2191	}
2192	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2193
2194 out:
2195	return rc;
2196}
2197EXPORT_SYMBOL(mptscsih_is_phys_disk);
2198
2199u8
2200mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2201{
2202	struct inactive_raid_component_info *component_info;
2203	int i, j;
2204	RaidPhysDiskPage1_t *phys_disk;
2205	int rc = -ENXIO;
2206	int num_paths;
2207
2208	if (!ioc->raid_data.pIocPg3)
2209		goto out;
2210	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2211		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2212		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2213			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2214			goto out;
2215		}
2216	}
2217
2218	if (ioc->bus_type != SAS)
2219		goto out;
2220
2221	/*
2222	 * Check if dual path
2223	 */
2224	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2225		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2226		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2227		if (num_paths < 2)
2228			continue;
2229		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2230		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2231		if (!phys_disk)
2232			continue;
2233		if ((mpt_raid_phys_disk_pg1(ioc,
2234		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2235		    phys_disk))) {
2236			kfree(phys_disk);
2237			continue;
2238		}
2239		for (j = 0; j < num_paths; j++) {
2240			if ((phys_disk->Path[j].Flags &
2241			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2242				continue;
2243			if ((phys_disk->Path[j].Flags &
2244			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2245				continue;
2246			if ((id == phys_disk->Path[j].PhysDiskID) &&
2247			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2248				rc = phys_disk->PhysDiskNum;
2249				kfree(phys_disk);
2250				goto out;
2251			}
2252		}
2253		kfree(phys_disk);
2254	}
2255
2256	/*
2257	 * Check inactive list for matching phys disks
2258	 */
2259	if (list_empty(&ioc->raid_data.inactive_list))
2260		goto out;
2261
2262	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2263	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2264	    list) {
2265		if ((component_info->d.PhysDiskID == id) &&
2266		    (component_info->d.PhysDiskBus == channel))
2267			rc = component_info->d.PhysDiskNum;
2268	}
2269	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2270
2271 out:
2272	return rc;
2273}
2274EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2275
2276/*
2277 *	OS entry point to allow for host driver to free allocated memory
2278 *	Called if no device present or device being unloaded
2279 */
2280void
2281mptscsih_slave_destroy(struct scsi_device *sdev)
2282{
2283	struct Scsi_Host	*host = sdev->host;
2284	MPT_SCSI_HOST		*hd = shost_priv(host);
2285	VirtTarget		*vtarget;
2286	VirtDevice		*vdevice;
2287	struct scsi_target 	*starget;
2288
2289	starget = scsi_target(sdev);
2290	vtarget = starget->hostdata;
2291	vdevice = sdev->hostdata;
2292	if (!vdevice)
2293		return;
2294
2295	mptscsih_search_running_cmds(hd, vdevice);
2296	vtarget->num_luns--;
2297	mptscsih_synchronize_cache(hd, vdevice);
2298	kfree(vdevice);
2299	sdev->hostdata = NULL;
2300}
2301
2302/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2303/*
2304 *	mptscsih_change_queue_depth - This function will set a devices queue depth
2305 *	@sdev: per scsi_device pointer
2306 *	@qdepth: requested queue depth
 
2307 *
2308 *	Adding support for new 'change_queue_depth' api.
2309*/
2310int
2311mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2312{
2313	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2314	VirtTarget 		*vtarget;
2315	struct scsi_target 	*starget;
2316	int			max_depth;
 
2317	MPT_ADAPTER		*ioc = hd->ioc;
2318
2319	starget = scsi_target(sdev);
2320	vtarget = starget->hostdata;
2321
 
 
 
2322	if (ioc->bus_type == SPI) {
2323		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2324			max_depth = 1;
2325		else if (sdev->type == TYPE_DISK &&
2326			 vtarget->minSyncFactor <= MPT_ULTRA160)
2327			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2328		else
2329			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2330	} else
2331		 max_depth = ioc->sh->can_queue;
2332
2333	if (!sdev->tagged_supported)
2334		max_depth = 1;
2335
2336	if (qdepth > max_depth)
2337		qdepth = max_depth;
 
 
 
 
2338
2339	return scsi_change_queue_depth(sdev, qdepth);
 
2340}
2341
2342/*
2343 *	OS entry point to adjust the queue_depths on a per-device basis.
2344 *	Called once per device the bus scan. Use it to force the queue_depth
2345 *	member to 1 if a device does not support Q tags.
2346 *	Return non-zero if fails.
2347 */
2348int
2349mptscsih_slave_configure(struct scsi_device *sdev)
2350{
2351	struct Scsi_Host	*sh = sdev->host;
2352	VirtTarget		*vtarget;
2353	VirtDevice		*vdevice;
2354	struct scsi_target 	*starget;
2355	MPT_SCSI_HOST		*hd = shost_priv(sh);
2356	MPT_ADAPTER		*ioc = hd->ioc;
2357
2358	starget = scsi_target(sdev);
2359	vtarget = starget->hostdata;
2360	vdevice = sdev->hostdata;
2361
2362	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2363		"device @ %p, channel=%d, id=%d, lun=%llu\n",
2364		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2365	if (ioc->bus_type == SPI)
2366		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2367		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2368		    ioc->name, sdev->sdtr, sdev->wdtr,
2369		    sdev->ppr, sdev->inquiry_len));
2370
2371	vdevice->configured_lun = 1;
2372
2373	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2374		"Queue depth=%d, tflags=%x\n",
2375		ioc->name, sdev->queue_depth, vtarget->tflags));
2376
2377	if (ioc->bus_type == SPI)
2378		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2379		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2380		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2381		    vtarget->minSyncFactor));
2382
2383	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
 
2384	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2385		"tagged %d, simple %d\n",
2386		ioc->name,sdev->tagged_supported, sdev->simple_tags));
 
2387
2388	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2389
2390	return 0;
2391}
2392
2393/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2394/*
2395 *  Private routines...
2396 */
2397
2398/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2399/* Utility function to copy sense data from the scsi_cmnd buffer
2400 * to the FC and SCSI target structures.
2401 *
2402 */
2403static void
2404mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2405{
2406	VirtDevice	*vdevice;
2407	SCSIIORequest_t	*pReq;
2408	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2409	MPT_ADAPTER 	*ioc = hd->ioc;
2410
2411	/* Get target structure
2412	 */
2413	pReq = (SCSIIORequest_t *) mf;
2414	vdevice = sc->device->hostdata;
2415
2416	if (sense_count) {
2417		u8 *sense_data;
2418		int req_index;
2419
2420		/* Copy the sense received into the scsi command block. */
2421		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2422		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2423		memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
2424
2425		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2426		 */
2427		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2428			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2429				int idx;
2430
2431				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2432				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2433				ioc->events[idx].eventContext = ioc->eventContext;
2434
2435				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2436					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2437					(sc->device->channel << 8) | sc->device->id;
2438
2439				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2440
2441				ioc->eventContext++;
2442				if (ioc->pcidev->vendor ==
2443				    PCI_VENDOR_ID_IBM) {
2444					mptscsih_issue_sep_command(ioc,
2445					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2446					vdevice->vtarget->tflags |=
2447					    MPT_TARGET_FLAGS_LED_ON;
2448				}
2449			}
2450		}
2451	} else {
2452		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2453				ioc->name));
2454	}
2455}
2456
2457/**
2458 * mptscsih_get_scsi_lookup - retrieves scmd entry
2459 * @ioc: Pointer to MPT_ADAPTER structure
2460 * @i: index into the array
2461 *
2462 * Returns the scsi_cmd pointer
2463 */
2464struct scsi_cmnd *
2465mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2466{
2467	unsigned long	flags;
2468	struct scsi_cmnd *scmd;
2469
2470	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2471	scmd = ioc->ScsiLookup[i];
2472	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2473
2474	return scmd;
2475}
2476EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2477
2478/**
2479 * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2480 * @ioc: Pointer to MPT_ADAPTER structure
2481 * @i: index into the array
2482 *
2483 * Returns the scsi_cmd pointer
2484 *
2485 **/
2486static struct scsi_cmnd *
2487mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2488{
2489	unsigned long	flags;
2490	struct scsi_cmnd *scmd;
2491
2492	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2493	scmd = ioc->ScsiLookup[i];
2494	ioc->ScsiLookup[i] = NULL;
2495	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2496
2497	return scmd;
2498}
2499
2500/**
2501 * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2502 *
2503 * @ioc: Pointer to MPT_ADAPTER structure
2504 * @i: index into the array
2505 * @scmd: scsi_cmnd pointer
2506 *
2507 **/
2508static void
2509mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2510{
2511	unsigned long	flags;
2512
2513	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2514	ioc->ScsiLookup[i] = scmd;
2515	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2516}
2517
2518/**
2519 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2520 * @ioc: Pointer to MPT_ADAPTER structure
2521 * @sc: scsi_cmnd pointer
2522 */
2523static int
2524SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2525{
2526	unsigned long	flags;
2527	int i, index=-1;
2528
2529	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2530	for (i = 0; i < ioc->req_depth; i++) {
2531		if (ioc->ScsiLookup[i] == sc) {
2532			index = i;
2533			goto out;
2534		}
2535	}
2536
2537 out:
2538	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2539	return index;
2540}
2541
2542/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2543int
2544mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2545{
2546	MPT_SCSI_HOST	*hd;
2547
2548	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2549		return 0;
2550
2551	hd = shost_priv(ioc->sh);
2552	switch (reset_phase) {
2553	case MPT_IOC_SETUP_RESET:
2554		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2555		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2556		break;
2557	case MPT_IOC_PRE_RESET:
2558		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2559		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2560		mptscsih_flush_running_cmds(hd);
2561		break;
2562	case MPT_IOC_POST_RESET:
2563		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2564		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2565		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2566			ioc->internal_cmds.status |=
2567				MPT_MGMT_STATUS_DID_IOCRESET;
2568			complete(&ioc->internal_cmds.done);
2569		}
2570		break;
2571	default:
2572		break;
2573	}
2574	return 1;		/* currently means nothing really */
2575}
2576
2577/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2578int
2579mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2580{
2581	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2582
2583	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2584		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2585		ioc->name, event));
2586
2587	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2588	    event == MPI_EVENT_EXT_BUS_RESET) &&
2589	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2590			ioc->soft_resets++;
2591
2592	return 1;		/* currently means nothing really */
2593}
2594
2595/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2596/*
2597 *  Bus Scan and Domain Validation functionality ...
2598 */
2599
2600/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2601/*
2602 *	mptscsih_scandv_complete - Scan and DV callback routine registered
2603 *	to Fustion MPT (base) driver.
2604 *
2605 *	@ioc: Pointer to MPT_ADAPTER structure
2606 *	@mf: Pointer to original MPT request frame
2607 *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2608 *
2609 *	This routine is called from mpt.c::mpt_interrupt() at the completion
2610 *	of any SCSI IO request.
2611 *	This routine is registered with the Fusion MPT (base) driver at driver
2612 *	load/init time via the mpt_register() API call.
2613 *
2614 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2615 *
2616 *	Remark: Sets a completion code and (possibly) saves sense data
2617 *	in the IOC member localReply structure.
2618 *	Used ONLY for DV and other internal commands.
2619 */
2620int
2621mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2622				MPT_FRAME_HDR *reply)
2623{
2624	SCSIIORequest_t *pReq;
2625	SCSIIOReply_t	*pReply;
2626	u8		 cmd;
2627	u16		 req_idx;
2628	u8	*sense_data;
2629	int		 sz;
2630
2631	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2632	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2633	if (!reply)
2634		goto out;
2635
2636	pReply = (SCSIIOReply_t *) reply;
2637	pReq = (SCSIIORequest_t *) req;
2638	ioc->internal_cmds.completion_code =
2639	    mptscsih_get_completion_code(ioc, req, reply);
2640	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2641	memcpy(ioc->internal_cmds.reply, reply,
2642	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2643	cmd = reply->u.hdr.Function;
2644	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2645	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2646	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2647		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2648		sense_data = ((u8 *)ioc->sense_buf_pool +
2649		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2650		sz = min_t(int, pReq->SenseBufferLength,
2651		    MPT_SENSE_BUFFER_ALLOC);
2652		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2653	}
2654 out:
2655	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2656		return 0;
2657	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2658	complete(&ioc->internal_cmds.done);
2659	return 1;
2660}
2661
2662
2663/**
2664 *	mptscsih_get_completion_code - get completion code from MPT request
2665 *	@ioc: Pointer to MPT_ADAPTER structure
2666 *	@req: Pointer to original MPT request frame
2667 *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2668 *
2669 **/
2670static int
2671mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2672				MPT_FRAME_HDR *reply)
2673{
2674	SCSIIOReply_t	*pReply;
2675	MpiRaidActionReply_t *pr;
2676	u8		 scsi_status;
2677	u16		 status;
2678	int		 completion_code;
2679
2680	pReply = (SCSIIOReply_t *)reply;
2681	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2682	scsi_status = pReply->SCSIStatus;
2683
2684	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2685	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2686	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2687	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2688
2689	switch (status) {
2690
2691	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2692		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2693		break;
2694
2695	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2696	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2697	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2698	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2699		completion_code = MPT_SCANDV_DID_RESET;
2700		break;
2701
2702	case MPI_IOCSTATUS_BUSY:
2703	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2704		completion_code = MPT_SCANDV_BUSY;
2705		break;
2706
2707	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2708	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2709	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2710		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2711			completion_code = MPT_SCANDV_GOOD;
2712		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2713			pr = (MpiRaidActionReply_t *)reply;
2714			if (le16_to_cpu(pr->ActionStatus) ==
2715				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2716				completion_code = MPT_SCANDV_GOOD;
2717			else
2718				completion_code = MPT_SCANDV_SOME_ERROR;
2719		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2720			completion_code = MPT_SCANDV_SENSE;
2721		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2722			if (req->u.scsireq.CDB[0] == INQUIRY)
2723				completion_code = MPT_SCANDV_ISSUE_SENSE;
2724			else
2725				completion_code = MPT_SCANDV_DID_RESET;
2726		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2727			completion_code = MPT_SCANDV_DID_RESET;
2728		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2729			completion_code = MPT_SCANDV_DID_RESET;
2730		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2731			completion_code = MPT_SCANDV_BUSY;
2732		else
2733			completion_code = MPT_SCANDV_GOOD;
2734		break;
2735
2736	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2737		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2738			completion_code = MPT_SCANDV_DID_RESET;
2739		else
2740			completion_code = MPT_SCANDV_SOME_ERROR;
2741		break;
2742	default:
2743		completion_code = MPT_SCANDV_SOME_ERROR;
2744		break;
2745
2746	}	/* switch(status) */
2747
2748	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2749	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2750	return completion_code;
2751}
2752
2753/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2754/**
2755 *	mptscsih_do_cmd - Do internal command.
2756 *	@hd: MPT_SCSI_HOST pointer
2757 *	@io: INTERNAL_CMD pointer.
2758 *
2759 *	Issue the specified internally generated command and do command
2760 *	specific cleanup. For bus scan / DV only.
2761 *	NOTES: If command is Inquiry and status is good,
2762 *	initialize a target structure, save the data
2763 *
2764 *	Remark: Single threaded access only.
2765 *
2766 *	Return:
2767 *		< 0 if an illegal command or no resources
2768 *
2769 *		   0 if good
2770 *
2771 *		 > 0 if command complete but some type of completion error.
2772 */
2773static int
2774mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2775{
2776	MPT_FRAME_HDR	*mf;
2777	SCSIIORequest_t	*pScsiReq;
2778	int		 my_idx, ii, dir;
2779	int		 timeout;
2780	char		 cmdLen;
2781	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2782	u8		 cmd = io->cmd;
2783	MPT_ADAPTER *ioc = hd->ioc;
2784	int		 ret = 0;
2785	unsigned long	 timeleft;
2786	unsigned long	 flags;
2787
2788	/* don't send internal command during diag reset */
2789	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2790	if (ioc->ioc_reset_in_progress) {
2791		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2792		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2793			"%s: busy with host reset\n", ioc->name, __func__));
2794		return MPT_SCANDV_BUSY;
2795	}
2796	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2797
2798	mutex_lock(&ioc->internal_cmds.mutex);
2799
2800	/* Set command specific information
2801	 */
2802	switch (cmd) {
2803	case INQUIRY:
2804		cmdLen = 6;
2805		dir = MPI_SCSIIO_CONTROL_READ;
2806		CDB[0] = cmd;
2807		CDB[4] = io->size;
2808		timeout = 10;
2809		break;
2810
2811	case TEST_UNIT_READY:
2812		cmdLen = 6;
2813		dir = MPI_SCSIIO_CONTROL_READ;
2814		timeout = 10;
2815		break;
2816
2817	case START_STOP:
2818		cmdLen = 6;
2819		dir = MPI_SCSIIO_CONTROL_READ;
2820		CDB[0] = cmd;
2821		CDB[4] = 1;	/*Spin up the disk */
2822		timeout = 15;
2823		break;
2824
2825	case REQUEST_SENSE:
2826		cmdLen = 6;
2827		CDB[0] = cmd;
2828		CDB[4] = io->size;
2829		dir = MPI_SCSIIO_CONTROL_READ;
2830		timeout = 10;
2831		break;
2832
2833	case READ_BUFFER:
2834		cmdLen = 10;
2835		dir = MPI_SCSIIO_CONTROL_READ;
2836		CDB[0] = cmd;
2837		if (io->flags & MPT_ICFLAG_ECHO) {
2838			CDB[1] = 0x0A;
2839		} else {
2840			CDB[1] = 0x02;
2841		}
2842
2843		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2844			CDB[1] |= 0x01;
2845		}
2846		CDB[6] = (io->size >> 16) & 0xFF;
2847		CDB[7] = (io->size >>  8) & 0xFF;
2848		CDB[8] = io->size & 0xFF;
2849		timeout = 10;
2850		break;
2851
2852	case WRITE_BUFFER:
2853		cmdLen = 10;
2854		dir = MPI_SCSIIO_CONTROL_WRITE;
2855		CDB[0] = cmd;
2856		if (io->flags & MPT_ICFLAG_ECHO) {
2857			CDB[1] = 0x0A;
2858		} else {
2859			CDB[1] = 0x02;
2860		}
2861		CDB[6] = (io->size >> 16) & 0xFF;
2862		CDB[7] = (io->size >>  8) & 0xFF;
2863		CDB[8] = io->size & 0xFF;
2864		timeout = 10;
2865		break;
2866
2867	case RESERVE:
2868		cmdLen = 6;
2869		dir = MPI_SCSIIO_CONTROL_READ;
2870		CDB[0] = cmd;
2871		timeout = 10;
2872		break;
2873
2874	case RELEASE:
2875		cmdLen = 6;
2876		dir = MPI_SCSIIO_CONTROL_READ;
2877		CDB[0] = cmd;
2878		timeout = 10;
2879		break;
2880
2881	case SYNCHRONIZE_CACHE:
2882		cmdLen = 10;
2883		dir = MPI_SCSIIO_CONTROL_READ;
2884		CDB[0] = cmd;
2885//		CDB[1] = 0x02;	/* set immediate bit */
2886		timeout = 10;
2887		break;
2888
2889	default:
2890		/* Error Case */
2891		ret = -EFAULT;
2892		goto out;
2893	}
2894
2895	/* Get and Populate a free Frame
2896	 * MsgContext set in mpt_get_msg_frame call
2897	 */
2898	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2899		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2900		    ioc->name, __func__));
2901		ret = MPT_SCANDV_BUSY;
2902		goto out;
2903	}
2904
2905	pScsiReq = (SCSIIORequest_t *) mf;
2906
2907	/* Get the request index */
2908	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2909	ADD_INDEX_LOG(my_idx); /* for debug */
2910
2911	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2912		pScsiReq->TargetID = io->physDiskNum;
2913		pScsiReq->Bus = 0;
2914		pScsiReq->ChainOffset = 0;
2915		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2916	} else {
2917		pScsiReq->TargetID = io->id;
2918		pScsiReq->Bus = io->channel;
2919		pScsiReq->ChainOffset = 0;
2920		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2921	}
2922
2923	pScsiReq->CDBLength = cmdLen;
2924	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2925
2926	pScsiReq->Reserved = 0;
2927
2928	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2929	/* MsgContext set in mpt_get_msg_fram call  */
2930
2931	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2932
2933	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2934		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2935	else
2936		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2937
2938	if (cmd == REQUEST_SENSE) {
2939		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2940		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2941		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2942	}
2943
2944	for (ii = 0; ii < 16; ii++)
2945		pScsiReq->CDB[ii] = CDB[ii];
2946
2947	pScsiReq->DataLength = cpu_to_le32(io->size);
2948	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2949					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2950
2951	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2952	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2953	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2954
2955	if (dir == MPI_SCSIIO_CONTROL_READ)
2956		ioc->add_sge((char *) &pScsiReq->SGL,
2957		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2958	else
2959		ioc->add_sge((char *) &pScsiReq->SGL,
2960		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2961
2962	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2963	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2964	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2965	    timeout*HZ);
2966	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2967		ret = MPT_SCANDV_DID_RESET;
2968		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2969		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2970		    cmd));
2971		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2972			mpt_free_msg_frame(ioc, mf);
2973			goto out;
2974		}
2975		if (!timeleft) {
2976			printk(MYIOC_s_WARN_FMT
2977			       "Issuing Reset from %s!! doorbell=0x%08xh"
2978			       " cmd=0x%02x\n",
2979			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
2980			       cmd);
2981			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2982			mpt_free_msg_frame(ioc, mf);
2983		}
2984		goto out;
2985	}
2986
2987	ret = ioc->internal_cmds.completion_code;
2988	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2989			ioc->name, __func__, ret));
2990
2991 out:
2992	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2993	mutex_unlock(&ioc->internal_cmds.mutex);
2994	return ret;
2995}
2996
2997/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2998/**
2999 *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3000 *	@hd: Pointer to a SCSI HOST structure
3001 *	@vdevice: virtual target device
3002 *
3003 *	Uses the ISR, but with special processing.
3004 *	MUST be single-threaded.
3005 *
3006 */
3007static void
3008mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3009{
3010	INTERNAL_CMD		 iocmd;
3011
3012	/* Ignore hidden raid components, this is handled when the command
3013	 * is sent to the volume
3014	 */
3015	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3016		return;
3017
3018	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3019	    !vdevice->configured_lun)
3020		return;
3021
3022	/* Following parameters will not change
3023	 * in this routine.
3024	 */
3025	iocmd.cmd = SYNCHRONIZE_CACHE;
3026	iocmd.flags = 0;
3027	iocmd.physDiskNum = -1;
3028	iocmd.data = NULL;
3029	iocmd.data_dma = -1;
3030	iocmd.size = 0;
3031	iocmd.rsvd = iocmd.rsvd2 = 0;
3032	iocmd.channel = vdevice->vtarget->channel;
3033	iocmd.id = vdevice->vtarget->id;
3034	iocmd.lun = vdevice->lun;
3035
3036	mptscsih_do_cmd(hd, &iocmd);
3037}
3038
3039static ssize_t
3040mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3041			 char *buf)
3042{
3043	struct Scsi_Host *host = class_to_shost(dev);
3044	MPT_SCSI_HOST	*hd = shost_priv(host);
3045	MPT_ADAPTER *ioc = hd->ioc;
3046
3047	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3048	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3049	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3050	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3051	    ioc->facts.FWVersion.Word & 0x000000FF);
3052}
3053static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3054
3055static ssize_t
3056mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3057			   char *buf)
3058{
3059	struct Scsi_Host *host = class_to_shost(dev);
3060	MPT_SCSI_HOST	*hd = shost_priv(host);
3061	MPT_ADAPTER *ioc = hd->ioc;
3062
3063	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3064	    (ioc->biosVersion & 0xFF000000) >> 24,
3065	    (ioc->biosVersion & 0x00FF0000) >> 16,
3066	    (ioc->biosVersion & 0x0000FF00) >> 8,
3067	    ioc->biosVersion & 0x000000FF);
3068}
3069static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3070
3071static ssize_t
3072mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3073			  char *buf)
3074{
3075	struct Scsi_Host *host = class_to_shost(dev);
3076	MPT_SCSI_HOST	*hd = shost_priv(host);
3077	MPT_ADAPTER *ioc = hd->ioc;
3078
3079	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3080}
3081static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3082
3083static ssize_t
3084mptscsih_version_product_show(struct device *dev,
3085			      struct device_attribute *attr,
3086char *buf)
3087{
3088	struct Scsi_Host *host = class_to_shost(dev);
3089	MPT_SCSI_HOST	*hd = shost_priv(host);
3090	MPT_ADAPTER *ioc = hd->ioc;
3091
3092	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3093}
3094static DEVICE_ATTR(version_product, S_IRUGO,
3095    mptscsih_version_product_show, NULL);
3096
3097static ssize_t
3098mptscsih_version_nvdata_persistent_show(struct device *dev,
3099					struct device_attribute *attr,
3100					char *buf)
3101{
3102	struct Scsi_Host *host = class_to_shost(dev);
3103	MPT_SCSI_HOST	*hd = shost_priv(host);
3104	MPT_ADAPTER *ioc = hd->ioc;
3105
3106	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3107	    ioc->nvdata_version_persistent);
3108}
3109static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3110    mptscsih_version_nvdata_persistent_show, NULL);
3111
3112static ssize_t
3113mptscsih_version_nvdata_default_show(struct device *dev,
3114				     struct device_attribute *attr, char *buf)
3115{
3116	struct Scsi_Host *host = class_to_shost(dev);
3117	MPT_SCSI_HOST	*hd = shost_priv(host);
3118	MPT_ADAPTER *ioc = hd->ioc;
3119
3120	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3121}
3122static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3123    mptscsih_version_nvdata_default_show, NULL);
3124
3125static ssize_t
3126mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3127			 char *buf)
3128{
3129	struct Scsi_Host *host = class_to_shost(dev);
3130	MPT_SCSI_HOST	*hd = shost_priv(host);
3131	MPT_ADAPTER *ioc = hd->ioc;
3132
3133	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3134}
3135static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3136
3137static ssize_t
3138mptscsih_board_assembly_show(struct device *dev,
3139			     struct device_attribute *attr, char *buf)
3140{
3141	struct Scsi_Host *host = class_to_shost(dev);
3142	MPT_SCSI_HOST	*hd = shost_priv(host);
3143	MPT_ADAPTER *ioc = hd->ioc;
3144
3145	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3146}
3147static DEVICE_ATTR(board_assembly, S_IRUGO,
3148    mptscsih_board_assembly_show, NULL);
3149
3150static ssize_t
3151mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3152			   char *buf)
3153{
3154	struct Scsi_Host *host = class_to_shost(dev);
3155	MPT_SCSI_HOST	*hd = shost_priv(host);
3156	MPT_ADAPTER *ioc = hd->ioc;
3157
3158	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3159}
3160static DEVICE_ATTR(board_tracer, S_IRUGO,
3161    mptscsih_board_tracer_show, NULL);
3162
3163static ssize_t
3164mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3165		       char *buf)
3166{
3167	struct Scsi_Host *host = class_to_shost(dev);
3168	MPT_SCSI_HOST	*hd = shost_priv(host);
3169	MPT_ADAPTER *ioc = hd->ioc;
3170
3171	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3172}
3173static DEVICE_ATTR(io_delay, S_IRUGO,
3174    mptscsih_io_delay_show, NULL);
3175
3176static ssize_t
3177mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3178			   char *buf)
3179{
3180	struct Scsi_Host *host = class_to_shost(dev);
3181	MPT_SCSI_HOST	*hd = shost_priv(host);
3182	MPT_ADAPTER *ioc = hd->ioc;
3183
3184	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3185}
3186static DEVICE_ATTR(device_delay, S_IRUGO,
3187    mptscsih_device_delay_show, NULL);
3188
3189static ssize_t
3190mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3191			  char *buf)
3192{
3193	struct Scsi_Host *host = class_to_shost(dev);
3194	MPT_SCSI_HOST	*hd = shost_priv(host);
3195	MPT_ADAPTER *ioc = hd->ioc;
3196
3197	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3198}
3199static ssize_t
3200mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3201			   const char *buf, size_t count)
3202{
3203	struct Scsi_Host *host = class_to_shost(dev);
3204	MPT_SCSI_HOST	*hd = shost_priv(host);
3205	MPT_ADAPTER *ioc = hd->ioc;
3206	int val = 0;
3207
3208	if (sscanf(buf, "%x", &val) != 1)
3209		return -EINVAL;
3210
3211	ioc->debug_level = val;
3212	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3213				ioc->name, ioc->debug_level);
3214	return strlen(buf);
3215}
3216static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3217	mptscsih_debug_level_show, mptscsih_debug_level_store);
3218
3219struct device_attribute *mptscsih_host_attrs[] = {
3220	&dev_attr_version_fw,
3221	&dev_attr_version_bios,
3222	&dev_attr_version_mpi,
3223	&dev_attr_version_product,
3224	&dev_attr_version_nvdata_persistent,
3225	&dev_attr_version_nvdata_default,
3226	&dev_attr_board_name,
3227	&dev_attr_board_assembly,
3228	&dev_attr_board_tracer,
3229	&dev_attr_io_delay,
3230	&dev_attr_device_delay,
3231	&dev_attr_debug_level,
3232	NULL,
3233};
3234
3235EXPORT_SYMBOL(mptscsih_host_attrs);
3236
3237EXPORT_SYMBOL(mptscsih_remove);
3238EXPORT_SYMBOL(mptscsih_shutdown);
3239#ifdef CONFIG_PM
3240EXPORT_SYMBOL(mptscsih_suspend);
3241EXPORT_SYMBOL(mptscsih_resume);
3242#endif
3243EXPORT_SYMBOL(mptscsih_show_info);
3244EXPORT_SYMBOL(mptscsih_info);
3245EXPORT_SYMBOL(mptscsih_qcmd);
3246EXPORT_SYMBOL(mptscsih_slave_destroy);
3247EXPORT_SYMBOL(mptscsih_slave_configure);
3248EXPORT_SYMBOL(mptscsih_abort);
3249EXPORT_SYMBOL(mptscsih_dev_reset);
3250EXPORT_SYMBOL(mptscsih_bus_reset);
3251EXPORT_SYMBOL(mptscsih_host_reset);
3252EXPORT_SYMBOL(mptscsih_bios_param);
3253EXPORT_SYMBOL(mptscsih_io_done);
3254EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3255EXPORT_SYMBOL(mptscsih_scandv_complete);
3256EXPORT_SYMBOL(mptscsih_event_process);
3257EXPORT_SYMBOL(mptscsih_ioc_reset);
3258EXPORT_SYMBOL(mptscsih_change_queue_depth);
3259
3260/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
v3.5.6
   1/*
   2 *  linux/drivers/message/fusion/mptscsih.c
   3 *      For use with LSI PCI chip/adapter(s)
   4 *      running LSI Fusion MPT (Message Passing Technology) firmware.
   5 *
   6 *  Copyright (c) 1999-2008 LSI Corporation
   7 *  (mailto:DL-MPTFusionLinux@lsi.com)
   8 *
   9 */
  10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  11/*
  12    This program is free software; you can redistribute it and/or modify
  13    it under the terms of the GNU General Public License as published by
  14    the Free Software Foundation; version 2 of the License.
  15
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20
  21    NO WARRANTY
  22    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  23    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  24    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  25    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  26    solely responsible for determining the appropriateness of using and
  27    distributing the Program and assumes all risks associated with its
  28    exercise of rights under this Agreement, including but not limited to
  29    the risks and costs of program errors, damage to or loss of data,
  30    programs or equipment, and unavailability or interruption of operations.
  31
  32    DISCLAIMER OF LIABILITY
  33    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  34    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  36    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  37    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  38    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  39    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  40
  41    You should have received a copy of the GNU General Public License
  42    along with this program; if not, write to the Free Software
  43    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  44*/
  45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  46
  47#include <linux/module.h>
  48#include <linux/kernel.h>
  49#include <linux/slab.h>
  50#include <linux/init.h>
  51#include <linux/errno.h>
  52#include <linux/kdev_t.h>
  53#include <linux/blkdev.h>
  54#include <linux/delay.h>	/* for mdelay */
  55#include <linux/interrupt.h>	/* needed for in_interrupt() proto */
  56#include <linux/reboot.h>	/* notifier code */
  57#include <linux/workqueue.h>
  58
  59#include <scsi/scsi.h>
  60#include <scsi/scsi_cmnd.h>
  61#include <scsi/scsi_device.h>
  62#include <scsi/scsi_host.h>
  63#include <scsi/scsi_tcq.h>
  64#include <scsi/scsi_dbg.h>
  65
  66#include "mptbase.h"
  67#include "mptscsih.h"
  68#include "lsi/mpi_log_sas.h"
  69
  70/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  71#define my_NAME		"Fusion MPT SCSI Host driver"
  72#define my_VERSION	MPT_LINUX_VERSION_COMMON
  73#define MYNAM		"mptscsih"
  74
  75MODULE_AUTHOR(MODULEAUTHOR);
  76MODULE_DESCRIPTION(my_NAME);
  77MODULE_LICENSE("GPL");
  78MODULE_VERSION(my_VERSION);
  79
  80/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  81/*
  82 *  Other private/forward protos...
  83 */
  84struct scsi_cmnd	*mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
  85static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
  86static void	mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
  87static int	SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
  88int		mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  89static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
  90int		mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  91
  92static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  93				 SCSIIORequest_t *pReq, int req_idx);
  94static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
  95static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
  96
  97int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
  98		int lun, int ctx2abort, ulong timeout);
  99
 100int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 101int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 102
 103void
 104mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
 105static int	mptscsih_get_completion_code(MPT_ADAPTER *ioc,
 106		MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 107int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 108static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 109static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 110
 111static int
 112mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
 113				SCSITaskMgmtReply_t *pScsiTmReply);
 114void 		mptscsih_remove(struct pci_dev *);
 115void 		mptscsih_shutdown(struct pci_dev *);
 116#ifdef CONFIG_PM
 117int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 118int 		mptscsih_resume(struct pci_dev *pdev);
 119#endif
 120
 121#define SNS_LEN(scp)	SCSI_SENSE_BUFFERSIZE
 122
 123
 124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 125/*
 126 *	mptscsih_getFreeChainBuffer - Function to get a free chain
 127 *	from the MPT_SCSI_HOST FreeChainQ.
 128 *	@ioc: Pointer to MPT_ADAPTER structure
 129 *	@req_idx: Index of the SCSI IO request frame. (output)
 130 *
 131 *	return SUCCESS or FAILED
 132 */
 133static inline int
 134mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
 135{
 136	MPT_FRAME_HDR *chainBuf;
 137	unsigned long flags;
 138	int rc;
 139	int chain_idx;
 140
 141	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
 142	    ioc->name));
 143	spin_lock_irqsave(&ioc->FreeQlock, flags);
 144	if (!list_empty(&ioc->FreeChainQ)) {
 145		int offset;
 146
 147		chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
 148				u.frame.linkage.list);
 149		list_del(&chainBuf->u.frame.linkage.list);
 150		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
 151		chain_idx = offset / ioc->req_sz;
 152		rc = SUCCESS;
 153		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 154		    "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
 155		    ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
 156	} else {
 157		rc = FAILED;
 158		chain_idx = MPT_HOST_NO_CHAIN;
 159		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
 160		    ioc->name));
 161	}
 162	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 163
 164	*retIndex = chain_idx;
 165	return rc;
 166} /* mptscsih_getFreeChainBuffer() */
 167
 168/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 169/*
 170 *	mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
 171 *	SCSIIORequest_t Message Frame.
 172 *	@ioc: Pointer to MPT_ADAPTER structure
 173 *	@SCpnt: Pointer to scsi_cmnd structure
 174 *	@pReq: Pointer to SCSIIORequest_t structure
 175 *
 176 *	Returns ...
 177 */
 178static int
 179mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
 180		SCSIIORequest_t *pReq, int req_idx)
 181{
 182	char 	*psge;
 183	char	*chainSge;
 184	struct scatterlist *sg;
 185	int	 frm_sz;
 186	int	 sges_left, sg_done;
 187	int	 chain_idx = MPT_HOST_NO_CHAIN;
 188	int	 sgeOffset;
 189	int	 numSgeSlots, numSgeThisFrame;
 190	u32	 sgflags, sgdir, thisxfer = 0;
 191	int	 chain_dma_off = 0;
 192	int	 newIndex;
 193	int	 ii;
 194	dma_addr_t v2;
 195	u32	RequestNB;
 196
 197	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
 198	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
 199		sgdir = MPT_TRANSFER_HOST_TO_IOC;
 200	} else {
 201		sgdir = MPT_TRANSFER_IOC_TO_HOST;
 202	}
 203
 204	psge = (char *) &pReq->SGL;
 205	frm_sz = ioc->req_sz;
 206
 207	/* Map the data portion, if any.
 208	 * sges_left  = 0 if no data transfer.
 209	 */
 210	sges_left = scsi_dma_map(SCpnt);
 211	if (sges_left < 0)
 212		return FAILED;
 213
 214	/* Handle the SG case.
 215	 */
 216	sg = scsi_sglist(SCpnt);
 217	sg_done  = 0;
 218	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
 219	chainSge = NULL;
 220
 221	/* Prior to entering this loop - the following must be set
 222	 * current MF:  sgeOffset (bytes)
 223	 *              chainSge (Null if original MF is not a chain buffer)
 224	 *              sg_done (num SGE done for this MF)
 225	 */
 226
 227nextSGEset:
 228	numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
 229	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
 230
 231	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
 232
 233	/* Get first (num - 1) SG elements
 234	 * Skip any SG entries with a length of 0
 235	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
 236	 */
 237	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
 238		thisxfer = sg_dma_len(sg);
 239		if (thisxfer == 0) {
 240			/* Get next SG element from the OS */
 241			sg = sg_next(sg);
 242			sg_done++;
 243			continue;
 244		}
 245
 246		v2 = sg_dma_address(sg);
 247		ioc->add_sge(psge, sgflags | thisxfer, v2);
 248
 249		/* Get next SG element from the OS */
 250		sg = sg_next(sg);
 251		psge += ioc->SGE_size;
 252		sgeOffset += ioc->SGE_size;
 253		sg_done++;
 254	}
 255
 256	if (numSgeThisFrame == sges_left) {
 257		/* Add last element, end of buffer and end of list flags.
 258		 */
 259		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
 260				MPT_SGE_FLAGS_END_OF_BUFFER |
 261				MPT_SGE_FLAGS_END_OF_LIST;
 262
 263		/* Add last SGE and set termination flags.
 264		 * Note: Last SGE may have a length of 0 - which should be ok.
 265		 */
 266		thisxfer = sg_dma_len(sg);
 267
 268		v2 = sg_dma_address(sg);
 269		ioc->add_sge(psge, sgflags | thisxfer, v2);
 270		sgeOffset += ioc->SGE_size;
 271		sg_done++;
 272
 273		if (chainSge) {
 274			/* The current buffer is a chain buffer,
 275			 * but there is not another one.
 276			 * Update the chain element
 277			 * Offset and Length fields.
 278			 */
 279			ioc->add_chain((char *)chainSge, 0, sgeOffset,
 280				ioc->ChainBufferDMA + chain_dma_off);
 281		} else {
 282			/* The current buffer is the original MF
 283			 * and there is no Chain buffer.
 284			 */
 285			pReq->ChainOffset = 0;
 286			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 287			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 288			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 289			ioc->RequestNB[req_idx] = RequestNB;
 290		}
 291	} else {
 292		/* At least one chain buffer is needed.
 293		 * Complete the first MF
 294		 *  - last SGE element, set the LastElement bit
 295		 *  - set ChainOffset (words) for orig MF
 296		 *             (OR finish previous MF chain buffer)
 297		 *  - update MFStructPtr ChainIndex
 298		 *  - Populate chain element
 299		 * Also
 300		 * Loop until done.
 301		 */
 302
 303		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
 304				ioc->name, sg_done));
 305
 306		/* Set LAST_ELEMENT flag for last non-chain element
 307		 * in the buffer. Since psge points at the NEXT
 308		 * SGE element, go back one SGE element, update the flags
 309		 * and reset the pointer. (Note: sgflags & thisxfer are already
 310		 * set properly).
 311		 */
 312		if (sg_done) {
 313			u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
 314			sgflags = le32_to_cpu(*ptmp);
 315			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
 316			*ptmp = cpu_to_le32(sgflags);
 317		}
 318
 319		if (chainSge) {
 320			/* The current buffer is a chain buffer.
 321			 * chainSge points to the previous Chain Element.
 322			 * Update its chain element Offset and Length (must
 323			 * include chain element size) fields.
 324			 * Old chain element is now complete.
 325			 */
 326			u8 nextChain = (u8) (sgeOffset >> 2);
 327			sgeOffset += ioc->SGE_size;
 328			ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
 329					 ioc->ChainBufferDMA + chain_dma_off);
 330		} else {
 331			/* The original MF buffer requires a chain buffer -
 332			 * set the offset.
 333			 * Last element in this MF is a chain element.
 334			 */
 335			pReq->ChainOffset = (u8) (sgeOffset >> 2);
 336			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 337			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 338			ioc->RequestNB[req_idx] = RequestNB;
 339		}
 340
 341		sges_left -= sg_done;
 342
 343
 344		/* NOTE: psge points to the beginning of the chain element
 345		 * in current buffer. Get a chain buffer.
 346		 */
 347		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
 348			dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 349			    "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
 350 			    ioc->name, pReq->CDB[0], SCpnt));
 351			return FAILED;
 352		}
 353
 354		/* Update the tracking arrays.
 355		 * If chainSge == NULL, update ReqToChain, else ChainToChain
 356		 */
 357		if (chainSge) {
 358			ioc->ChainToChain[chain_idx] = newIndex;
 359		} else {
 360			ioc->ReqToChain[req_idx] = newIndex;
 361		}
 362		chain_idx = newIndex;
 363		chain_dma_off = ioc->req_sz * chain_idx;
 364
 365		/* Populate the chainSGE for the current buffer.
 366		 * - Set chain buffer pointer to psge and fill
 367		 *   out the Address and Flags fields.
 368		 */
 369		chainSge = (char *) psge;
 370		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Current buff @ %p (index 0x%x)",
 371		    ioc->name, psge, req_idx));
 372
 373		/* Start the SGE for the next buffer
 374		 */
 375		psge = (char *) (ioc->ChainBuffer + chain_dma_off);
 376		sgeOffset = 0;
 377		sg_done = 0;
 378
 379		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Chain buff @ %p (index 0x%x)\n",
 380		    ioc->name, psge, chain_idx));
 381
 382		/* Start the SGE for the next buffer
 383		 */
 384
 385		goto nextSGEset;
 386	}
 387
 388	return SUCCESS;
 389} /* mptscsih_AddSGE() */
 390
 391static void
 392mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
 393    U32 SlotStatus)
 394{
 395	MPT_FRAME_HDR *mf;
 396	SEPRequest_t 	 *SEPMsg;
 397
 398	if (ioc->bus_type != SAS)
 399		return;
 400
 401	/* Not supported for hidden raid components
 402	 */
 403	if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
 404		return;
 405
 406	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
 407		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
 408		    ioc->name,__func__));
 409		return;
 410	}
 411
 412	SEPMsg = (SEPRequest_t *)mf;
 413	SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
 414	SEPMsg->Bus = vtarget->channel;
 415	SEPMsg->TargetID = vtarget->id;
 416	SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
 417	SEPMsg->SlotStatus = SlotStatus;
 418	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 419	    "Sending SEP cmd=%x channel=%d id=%d\n",
 420	    ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
 421	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 422}
 423
 424#ifdef CONFIG_FUSION_LOGGING
 425/**
 426 *	mptscsih_info_scsiio - debug print info on reply frame
 427 *	@ioc: Pointer to MPT_ADAPTER structure
 428 *	@sc: original scsi cmnd pointer
 429 *	@pScsiReply: Pointer to MPT reply frame
 430 *
 431 *	MPT_DEBUG_REPLY needs to be enabled to obtain this info
 432 *
 433 *	Refer to lsi/mpi.h.
 434 **/
 435static void
 436mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
 437{
 438	char	*desc = NULL;
 439	char	*desc1 = NULL;
 440	u16	ioc_status;
 441	u8	skey, asc, ascq;
 442
 443	ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 444
 445	switch (ioc_status) {
 446
 447	case MPI_IOCSTATUS_SUCCESS:
 448		desc = "success";
 449		break;
 450	case MPI_IOCSTATUS_SCSI_INVALID_BUS:
 451		desc = "invalid bus";
 452		break;
 453	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
 454		desc = "invalid target_id";
 455		break;
 456	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
 457		desc = "device not there";
 458		break;
 459	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
 460		desc = "data overrun";
 461		break;
 462	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
 463		desc = "data underrun";
 464		break;
 465	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
 466		desc = "I/O data error";
 467		break;
 468	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
 469		desc = "protocol error";
 470		break;
 471	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
 472		desc = "task terminated";
 473		break;
 474	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
 475		desc = "residual mismatch";
 476		break;
 477	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
 478		desc = "task management failed";
 479		break;
 480	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
 481		desc = "IOC terminated";
 482		break;
 483	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
 484		desc = "ext terminated";
 485		break;
 486	default:
 487		desc = "";
 488		break;
 489	}
 490
 491	switch (pScsiReply->SCSIStatus)
 492	{
 493
 494	case MPI_SCSI_STATUS_SUCCESS:
 495		desc1 = "success";
 496		break;
 497	case MPI_SCSI_STATUS_CHECK_CONDITION:
 498		desc1 = "check condition";
 499		break;
 500	case MPI_SCSI_STATUS_CONDITION_MET:
 501		desc1 = "condition met";
 502		break;
 503	case MPI_SCSI_STATUS_BUSY:
 504		desc1 = "busy";
 505		break;
 506	case MPI_SCSI_STATUS_INTERMEDIATE:
 507		desc1 = "intermediate";
 508		break;
 509	case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
 510		desc1 = "intermediate condmet";
 511		break;
 512	case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
 513		desc1 = "reservation conflict";
 514		break;
 515	case MPI_SCSI_STATUS_COMMAND_TERMINATED:
 516		desc1 = "command terminated";
 517		break;
 518	case MPI_SCSI_STATUS_TASK_SET_FULL:
 519		desc1 = "task set full";
 520		break;
 521	case MPI_SCSI_STATUS_ACA_ACTIVE:
 522		desc1 = "aca active";
 523		break;
 524	case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
 525		desc1 = "fcpext device logged out";
 526		break;
 527	case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
 528		desc1 = "fcpext no link";
 529		break;
 530	case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
 531		desc1 = "fcpext unassigned";
 532		break;
 533	default:
 534		desc1 = "";
 535		break;
 536	}
 537
 538	scsi_print_command(sc);
 539	printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %d\n",
 540	    ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
 541	printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
 542	    "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
 543	    scsi_get_resid(sc));
 544	printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
 545	    "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
 546	    le32_to_cpu(pScsiReply->TransferCount), sc->result);
 547
 548	printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
 549	    "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
 550	    ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
 551	    pScsiReply->SCSIState);
 552
 553	if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
 554		skey = sc->sense_buffer[2] & 0x0F;
 555		asc = sc->sense_buffer[12];
 556		ascq = sc->sense_buffer[13];
 557
 558		printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
 559		    "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
 560	}
 561
 562	/*
 563	 *  Look for + dump FCP ResponseInfo[]!
 564	 */
 565	if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 566	    pScsiReply->ResponseInfo)
 567		printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
 568		    ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
 569}
 570#endif
 571
 572/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 573/*
 574 *	mptscsih_io_done - Main SCSI IO callback routine registered to
 575 *	Fusion MPT (base) driver
 576 *	@ioc: Pointer to MPT_ADAPTER structure
 577 *	@mf: Pointer to original MPT request frame
 578 *	@r: Pointer to MPT reply frame (NULL if TurboReply)
 579 *
 580 *	This routine is called from mpt.c::mpt_interrupt() at the completion
 581 *	of any SCSI IO request.
 582 *	This routine is registered with the Fusion MPT (base) driver at driver
 583 *	load/init time via the mpt_register() API call.
 584 *
 585 *	Returns 1 indicating alloc'd request frame ptr should be freed.
 586 */
 587int
 588mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 589{
 590	struct scsi_cmnd	*sc;
 591	MPT_SCSI_HOST	*hd;
 592	SCSIIORequest_t	*pScsiReq;
 593	SCSIIOReply_t	*pScsiReply;
 594	u16		 req_idx, req_idx_MR;
 595	VirtDevice	 *vdevice;
 596	VirtTarget	 *vtarget;
 597
 598	hd = shost_priv(ioc->sh);
 599	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 600	req_idx_MR = (mr != NULL) ?
 601	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
 602
 603	/* Special case, where already freed message frame is received from
 604	 * Firmware. It happens with Resetting IOC.
 605	 * Return immediately. Do not care
 606	 */
 607	if ((req_idx != req_idx_MR) ||
 608	    (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
 609		return 0;
 610
 611	sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
 612	if (sc == NULL) {
 613		MPIHeader_t *hdr = (MPIHeader_t *)mf;
 614
 615		/* Remark: writeSDP1 will use the ScsiDoneCtx
 616		 * If a SCSI I/O cmd, device disabled by OS and
 617		 * completion done. Cannot touch sc struct. Just free mem.
 618		 */
 619		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
 620			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
 621			ioc->name);
 622
 623		mptscsih_freeChainBuffers(ioc, req_idx);
 624		return 1;
 625	}
 626
 627	if ((unsigned char *)mf != sc->host_scribble) {
 628		mptscsih_freeChainBuffers(ioc, req_idx);
 629		return 1;
 630	}
 631
 632	if (ioc->bus_type == SAS) {
 633		VirtDevice *vdevice = sc->device->hostdata;
 634
 635		if (!vdevice || !vdevice->vtarget ||
 636		    vdevice->vtarget->deleted) {
 637			sc->result = DID_NO_CONNECT << 16;
 638			goto out;
 639		}
 640	}
 641
 642	sc->host_scribble = NULL;
 643	sc->result = DID_OK << 16;		/* Set default reply as OK */
 644	pScsiReq = (SCSIIORequest_t *) mf;
 645	pScsiReply = (SCSIIOReply_t *) mr;
 646
 647	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
 648		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 649			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
 650			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
 651	}else{
 652		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 653			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
 654			ioc->name, mf, mr, sc, req_idx));
 655	}
 656
 657	if (pScsiReply == NULL) {
 658		/* special context reply handling */
 659		;
 660	} else {
 661		u32	 xfer_cnt;
 662		u16	 status;
 663		u8	 scsi_state, scsi_status;
 664		u32	 log_info;
 665
 666		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 667
 668		scsi_state = pScsiReply->SCSIState;
 669		scsi_status = pScsiReply->SCSIStatus;
 670		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
 671		scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 672		log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
 673
 674		/*
 675		 *  if we get a data underrun indication, yet no data was
 676		 *  transferred and the SCSI status indicates that the
 677		 *  command was never started, change the data underrun
 678		 *  to success
 679		 */
 680		if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
 681		    (scsi_status == MPI_SCSI_STATUS_BUSY ||
 682		     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
 683		     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
 684			status = MPI_IOCSTATUS_SUCCESS;
 685		}
 686
 687		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
 688			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
 689
 690		/*
 691		 *  Look for + dump FCP ResponseInfo[]!
 692		 */
 693		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 694		    pScsiReply->ResponseInfo) {
 695			printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
 696			"FCP_ResponseInfo=%08xh\n", ioc->name,
 697			sc->device->host->host_no, sc->device->channel,
 698			sc->device->id, sc->device->lun,
 699			le32_to_cpu(pScsiReply->ResponseInfo));
 700		}
 701
 702		switch(status) {
 703		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
 704		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 705			/* CHECKME!
 706			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
 707			 * But not: DID_BUS_BUSY lest one risk
 708			 * killing interrupt handler:-(
 709			 */
 710			sc->result = SAM_STAT_BUSY;
 711			break;
 712
 713		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
 714		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
 715			sc->result = DID_BAD_TARGET << 16;
 716			break;
 717
 718		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
 719			/* Spoof to SCSI Selection Timeout! */
 720			if (ioc->bus_type != FC)
 721				sc->result = DID_NO_CONNECT << 16;
 722			/* else fibre, just stall until rescan event */
 723			else
 724				sc->result = DID_REQUEUE << 16;
 725
 726			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
 727				hd->sel_timeout[pScsiReq->TargetID]++;
 728
 729			vdevice = sc->device->hostdata;
 730			if (!vdevice)
 731				break;
 732			vtarget = vdevice->vtarget;
 733			if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
 734				mptscsih_issue_sep_command(ioc, vtarget,
 735				    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
 736				vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
 737			}
 738			break;
 739
 740		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
 741			if ( ioc->bus_type == SAS ) {
 742				u16 ioc_status =
 743				    le16_to_cpu(pScsiReply->IOCStatus);
 744				if ((ioc_status &
 745					MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
 746					&&
 747					((log_info & SAS_LOGINFO_MASK) ==
 748					SAS_LOGINFO_NEXUS_LOSS)) {
 749						VirtDevice *vdevice =
 750						sc->device->hostdata;
 751
 752					    /* flag the device as being in
 753					     * device removal delay so we can
 754					     * notify the midlayer to hold off
 755					     * on timeout eh */
 756						if (vdevice && vdevice->
 757							vtarget &&
 758							vdevice->vtarget->
 759							raidVolume)
 760							printk(KERN_INFO
 761							"Skipping Raid Volume"
 762							"for inDMD\n");
 763						else if (vdevice &&
 764							vdevice->vtarget)
 765							vdevice->vtarget->
 766								inDMD = 1;
 767
 768					    sc->result =
 769						    (DID_TRANSPORT_DISRUPTED
 770						    << 16);
 771					    break;
 772				}
 773			} else if (ioc->bus_type == FC) {
 774				/*
 775				 * The FC IOC may kill a request for variety of
 776				 * reasons, some of which may be recovered by a
 777				 * retry, some which are unlikely to be
 778				 * recovered. Return DID_ERROR instead of
 779				 * DID_RESET to permit retry of the command,
 780				 * just not an infinite number of them
 781				 */
 782				sc->result = DID_ERROR << 16;
 783				break;
 784			}
 785
 786			/*
 787			 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
 788			 */
 
 789
 790		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
 791			/* Linux handles an unsolicited DID_RESET better
 792			 * than an unsolicited DID_ABORT.
 793			 */
 794			sc->result = DID_RESET << 16;
 
 795
 796		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
 797			if (ioc->bus_type == FC)
 798				sc->result = DID_ERROR << 16;
 799			else
 800				sc->result = DID_RESET << 16;
 801			break;
 802
 803		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 804			scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 805			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
 806				sc->result=DID_SOFT_ERROR << 16;
 807			else /* Sufficient data transfer occurred */
 808				sc->result = (DID_OK << 16) | scsi_status;
 809			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 810			    "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
 811			    ioc->name, sc->result, sc->device->channel, sc->device->id));
 812			break;
 813
 814		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 815			/*
 816			 *  Do upfront check for valid SenseData and give it
 817			 *  precedence!
 818			 */
 819			sc->result = (DID_OK << 16) | scsi_status;
 820			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
 821
 822				/*
 823				 * For an Errata on LSI53C1030
 824				 * When the length of request data
 825				 * and transfer data are different
 826				 * with result of command (READ or VERIFY),
 827				 * DID_SOFT_ERROR is set.
 828				 */
 829				if (ioc->bus_type == SPI) {
 830					if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
 831					    pScsiReq->CDB[0] == READ_10 ||
 832					    pScsiReq->CDB[0] == READ_12 ||
 833						(pScsiReq->CDB[0] == READ_16 &&
 834						((pScsiReq->CDB[1] & 0x02) == 0)) ||
 835					    pScsiReq->CDB[0] == VERIFY  ||
 836					    pScsiReq->CDB[0] == VERIFY_16) {
 837						if (scsi_bufflen(sc) !=
 838							xfer_cnt) {
 839							sc->result =
 840							DID_SOFT_ERROR << 16;
 841						    printk(KERN_WARNING "Errata"
 842						    "on LSI53C1030 occurred."
 843						    "sc->req_bufflen=0x%02x,"
 844						    "xfer_cnt=0x%02x\n",
 845						    scsi_bufflen(sc),
 846						    xfer_cnt);
 847						}
 848					}
 849				}
 850
 851				if (xfer_cnt < sc->underflow) {
 852					if (scsi_status == SAM_STAT_BUSY)
 853						sc->result = SAM_STAT_BUSY;
 854					else
 855						sc->result = DID_SOFT_ERROR << 16;
 856				}
 857				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
 858					/* What to do?
 859				 	*/
 860					sc->result = DID_SOFT_ERROR << 16;
 861				}
 862				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 863					/*  Not real sure here either...  */
 864					sc->result = DID_RESET << 16;
 865				}
 866			}
 867
 868
 869			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 870			    "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
 871			    ioc->name, sc->underflow));
 872			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 873			    "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
 874
 875			/* Report Queue Full
 876			 */
 877			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 878				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 879
 880			break;
 881
 882		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 883			scsi_set_resid(sc, 0);
 
 884		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
 885		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
 886			sc->result = (DID_OK << 16) | scsi_status;
 887			if (scsi_state == 0) {
 888				;
 889			} else if (scsi_state &
 890			    MPI_SCSI_STATE_AUTOSENSE_VALID) {
 891
 892				/*
 893				 * For potential trouble on LSI53C1030.
 894				 * (date:2007.xx.)
 895				 * It is checked whether the length of
 896				 * request data is equal to
 897				 * the length of transfer and residual.
 898				 * MEDIUM_ERROR is set by incorrect data.
 899				 */
 900				if ((ioc->bus_type == SPI) &&
 901					(sc->sense_buffer[2] & 0x20)) {
 902					u32	 difftransfer;
 903					difftransfer =
 904					sc->sense_buffer[3] << 24 |
 905					sc->sense_buffer[4] << 16 |
 906					sc->sense_buffer[5] << 8 |
 907					sc->sense_buffer[6];
 908					if (((sc->sense_buffer[3] & 0x80) ==
 909						0x80) && (scsi_bufflen(sc)
 910						!= xfer_cnt)) {
 911						sc->sense_buffer[2] =
 912						    MEDIUM_ERROR;
 913						sc->sense_buffer[12] = 0xff;
 914						sc->sense_buffer[13] = 0xff;
 915						printk(KERN_WARNING"Errata"
 916						"on LSI53C1030 occurred."
 917						"sc->req_bufflen=0x%02x,"
 918						"xfer_cnt=0x%02x\n" ,
 919						scsi_bufflen(sc),
 920						xfer_cnt);
 921					}
 922					if (((sc->sense_buffer[3] & 0x80)
 923						!= 0x80) &&
 924						(scsi_bufflen(sc) !=
 925						xfer_cnt + difftransfer)) {
 926						sc->sense_buffer[2] =
 927							MEDIUM_ERROR;
 928						sc->sense_buffer[12] = 0xff;
 929						sc->sense_buffer[13] = 0xff;
 930						printk(KERN_WARNING
 931						"Errata on LSI53C1030 occurred"
 932						"sc->req_bufflen=0x%02x,"
 933						" xfer_cnt=0x%02x,"
 934						"difftransfer=0x%02x\n",
 935						scsi_bufflen(sc),
 936						xfer_cnt,
 937						difftransfer);
 938					}
 939				}
 940
 941				/*
 942				 * If running against circa 200003dd 909 MPT f/w,
 943				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
 944				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
 945				 * and with SenseBytes set to 0.
 946				 */
 947				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
 948					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 949
 950			}
 951			else if (scsi_state &
 952			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
 953			   ) {
 954				/*
 955				 * What to do?
 956				 */
 957				sc->result = DID_SOFT_ERROR << 16;
 958			}
 959			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 960				/*  Not real sure here either...  */
 961				sc->result = DID_RESET << 16;
 962			}
 963			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
 964				/* Device Inq. data indicates that it supports
 965				 * QTags, but rejects QTag messages.
 966				 * This command completed OK.
 967				 *
 968				 * Not real sure here either so do nothing...  */
 969			}
 970
 971			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
 972				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 973
 974			/* Add handling of:
 975			 * Reservation Conflict, Busy,
 976			 * Command Terminated, CHECK
 977			 */
 978			break;
 979
 980		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
 981			sc->result = DID_SOFT_ERROR << 16;
 982			break;
 983
 984		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
 985		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
 986		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
 987		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
 988		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
 989		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
 990		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
 991		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
 992		default:
 993			/*
 994			 * What to do?
 995			 */
 996			sc->result = DID_SOFT_ERROR << 16;
 997			break;
 998
 999		}	/* switch(status) */
1000
1001#ifdef CONFIG_FUSION_LOGGING
1002		if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
1003			mptscsih_info_scsiio(ioc, sc, pScsiReply);
1004#endif
1005
1006	} /* end of address reply case */
1007out:
1008	/* Unmap the DMA buffers, if any. */
1009	scsi_dma_unmap(sc);
1010
1011	sc->scsi_done(sc);		/* Issue the command callback */
1012
1013	/* Free Chain buffers */
1014	mptscsih_freeChainBuffers(ioc, req_idx);
1015	return 1;
1016}
1017
1018/*
1019 *	mptscsih_flush_running_cmds - For each command found, search
1020 *		Scsi_Host instance taskQ and reply to OS.
1021 *		Called only if recovering from a FW reload.
1022 *	@hd: Pointer to a SCSI HOST structure
1023 *
1024 *	Returns: None.
1025 *
1026 *	Must be called while new I/Os are being queued.
1027 */
1028void
1029mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1030{
1031	MPT_ADAPTER *ioc = hd->ioc;
1032	struct scsi_cmnd *sc;
1033	SCSIIORequest_t	*mf = NULL;
1034	int		 ii;
1035	int		 channel, id;
1036
1037	for (ii= 0; ii < ioc->req_depth; ii++) {
1038		sc = mptscsih_getclear_scsi_lookup(ioc, ii);
1039		if (!sc)
1040			continue;
1041		mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1042		if (!mf)
1043			continue;
1044		channel = mf->Bus;
1045		id = mf->TargetID;
1046		mptscsih_freeChainBuffers(ioc, ii);
1047		mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1048		if ((unsigned char *)mf != sc->host_scribble)
1049			continue;
1050		scsi_dma_unmap(sc);
1051		sc->result = DID_RESET << 16;
1052		sc->host_scribble = NULL;
1053		dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
1054		    "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
1055		    "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
1056		sc->scsi_done(sc);
1057	}
1058}
1059EXPORT_SYMBOL(mptscsih_flush_running_cmds);
1060
1061/*
1062 *	mptscsih_search_running_cmds - Delete any commands associated
1063 *		with the specified target and lun. Function called only
1064 *		when a lun is disable by mid-layer.
1065 *		Do NOT access the referenced scsi_cmnd structure or
1066 *		members. Will cause either a paging or NULL ptr error.
1067 *		(BUT, BUT, BUT, the code does reference it! - mdr)
1068 *      @hd: Pointer to a SCSI HOST structure
1069 *	@vdevice: per device private data
1070 *
1071 *	Returns: None.
1072 *
1073 *	Called from slave_destroy.
1074 */
1075static void
1076mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1077{
1078	SCSIIORequest_t	*mf = NULL;
1079	int		 ii;
1080	struct scsi_cmnd *sc;
1081	struct scsi_lun  lun;
1082	MPT_ADAPTER *ioc = hd->ioc;
1083	unsigned long	flags;
1084
1085	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1086	for (ii = 0; ii < ioc->req_depth; ii++) {
1087		if ((sc = ioc->ScsiLookup[ii]) != NULL) {
1088
1089			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1090			if (mf == NULL)
1091				continue;
1092			/* If the device is a hidden raid component, then its
1093			 * expected that the mf->function will be RAID_SCSI_IO
1094			 */
1095			if (vdevice->vtarget->tflags &
1096			    MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1097			    MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1098				continue;
1099
1100			int_to_scsilun(vdevice->lun, &lun);
1101			if ((mf->Bus != vdevice->vtarget->channel) ||
1102			    (mf->TargetID != vdevice->vtarget->id) ||
1103			    memcmp(lun.scsi_lun, mf->LUN, 8))
1104				continue;
1105
1106			if ((unsigned char *)mf != sc->host_scribble)
1107				continue;
1108			ioc->ScsiLookup[ii] = NULL;
1109			spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1110			mptscsih_freeChainBuffers(ioc, ii);
1111			mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1112			scsi_dma_unmap(sc);
1113			sc->host_scribble = NULL;
1114			sc->result = DID_NO_CONNECT << 16;
1115			dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
1116			   MYIOC_s_FMT "completing cmds: fw_channel %d, "
1117			   "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1118			   vdevice->vtarget->channel, vdevice->vtarget->id,
1119			   sc, mf, ii));
1120			sc->scsi_done(sc);
1121			spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1122		}
1123	}
1124	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1125	return;
1126}
1127
1128/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1129
1130/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1131/*
1132 *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
1133 *	from a SCSI target device.
1134 *	@sc: Pointer to scsi_cmnd structure
1135 *	@pScsiReply: Pointer to SCSIIOReply_t
1136 *	@pScsiReq: Pointer to original SCSI request
1137 *
1138 *	This routine periodically reports QUEUE_FULL status returned from a
1139 *	SCSI target device.  It reports this to the console via kernel
1140 *	printk() API call, not more than once every 10 seconds.
1141 */
1142static void
1143mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1144{
1145	long time = jiffies;
1146	MPT_SCSI_HOST		*hd;
1147	MPT_ADAPTER	*ioc;
1148
1149	if (sc->device == NULL)
1150		return;
1151	if (sc->device->host == NULL)
1152		return;
1153	if ((hd = shost_priv(sc->device->host)) == NULL)
1154		return;
1155	ioc = hd->ioc;
1156	if (time - hd->last_queue_full > 10 * HZ) {
1157		dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1158				ioc->name, 0, sc->device->id, sc->device->lun));
1159		hd->last_queue_full = time;
1160	}
1161}
1162
1163/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1164/*
1165 *	mptscsih_remove - Removed scsi devices
1166 *	@pdev: Pointer to pci_dev structure
1167 *
1168 *
1169 */
1170void
1171mptscsih_remove(struct pci_dev *pdev)
1172{
1173	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1174	struct Scsi_Host 	*host = ioc->sh;
1175	MPT_SCSI_HOST		*hd;
1176	int sz1;
1177
1178	scsi_remove_host(host);
1179
1180	if((hd = shost_priv(host)) == NULL)
1181		return;
1182
1183	mptscsih_shutdown(pdev);
1184
1185	sz1=0;
1186
1187	if (ioc->ScsiLookup != NULL) {
1188		sz1 = ioc->req_depth * sizeof(void *);
1189		kfree(ioc->ScsiLookup);
1190		ioc->ScsiLookup = NULL;
1191	}
1192
1193	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1194	    "Free'd ScsiLookup (%d) memory\n",
1195	    ioc->name, sz1));
1196
1197	kfree(hd->info_kbuf);
1198
1199	/* NULL the Scsi_Host pointer
1200	 */
1201	ioc->sh = NULL;
1202
1203	scsi_host_put(host);
1204
1205	mpt_detach(pdev);
1206
1207}
1208
1209/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1210/*
1211 *	mptscsih_shutdown - reboot notifier
1212 *
1213 */
1214void
1215mptscsih_shutdown(struct pci_dev *pdev)
1216{
1217}
1218
1219#ifdef CONFIG_PM
1220/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1221/*
1222 *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1223 *
1224 *
1225 */
1226int
1227mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1228{
1229	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1230
1231	scsi_block_requests(ioc->sh);
1232	flush_scheduled_work();
1233	mptscsih_shutdown(pdev);
1234	return mpt_suspend(pdev,state);
1235}
1236
1237/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1238/*
1239 *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1240 *
1241 *
1242 */
1243int
1244mptscsih_resume(struct pci_dev *pdev)
1245{
1246	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1247	int rc;
1248
1249	rc = mpt_resume(pdev);
1250	scsi_unblock_requests(ioc->sh);
1251	return rc;
1252}
1253
1254#endif
1255
1256/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1257/**
1258 *	mptscsih_info - Return information about MPT adapter
1259 *	@SChost: Pointer to Scsi_Host structure
1260 *
1261 *	(linux scsi_host_template.info routine)
1262 *
1263 *	Returns pointer to buffer where information was written.
1264 */
1265const char *
1266mptscsih_info(struct Scsi_Host *SChost)
1267{
1268	MPT_SCSI_HOST *h;
1269	int size = 0;
1270
1271	h = shost_priv(SChost);
1272
1273	if (h) {
1274		if (h->info_kbuf == NULL)
1275			if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1276				return h->info_kbuf;
1277		h->info_kbuf[0] = '\0';
1278
1279		mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1280		h->info_kbuf[size-1] = '\0';
1281	}
1282
1283	return h->info_kbuf;
1284}
1285
1286struct info_str {
1287	char *buffer;
1288	int   length;
1289	int   offset;
1290	int   pos;
1291};
1292
1293static void
1294mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1295{
1296	if (info->pos + len > info->length)
1297		len = info->length - info->pos;
1298
1299	if (info->pos + len < info->offset) {
1300		info->pos += len;
1301		return;
1302	}
1303
1304	if (info->pos < info->offset) {
1305	        data += (info->offset - info->pos);
1306	        len  -= (info->offset - info->pos);
1307	}
1308
1309	if (len > 0) {
1310                memcpy(info->buffer + info->pos, data, len);
1311                info->pos += len;
1312	}
1313}
1314
1315static int
1316mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1317{
1318	va_list args;
1319	char buf[81];
1320	int len;
1321
1322	va_start(args, fmt);
1323	len = vsprintf(buf, fmt, args);
1324	va_end(args);
1325
1326	mptscsih_copy_mem_info(info, buf, len);
1327	return len;
1328}
1329
1330static int
1331mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1332{
1333	struct info_str info;
1334
1335	info.buffer	= pbuf;
1336	info.length	= len;
1337	info.offset	= offset;
1338	info.pos	= 0;
1339
1340	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1341	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1342	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1343	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1344
1345	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1346}
1347
1348/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1349/**
1350 *	mptscsih_proc_info - Return information about MPT adapter
1351 * 	@host:   scsi host struct
1352 * 	@buffer: if write, user data; if read, buffer for user
1353 *	@start: returns the buffer address
1354 * 	@offset: if write, 0; if read, the current offset into the buffer from
1355 * 		 the previous read.
1356 * 	@length: if write, return length;
1357 *	@func:   write = 1; read = 0
1358 *
1359 *	(linux scsi_host_template.info routine)
1360 */
1361int
1362mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1363			int length, int func)
1364{
1365	MPT_SCSI_HOST	*hd = shost_priv(host);
1366	MPT_ADAPTER	*ioc = hd->ioc;
1367	int size = 0;
1368
1369	if (func) {
1370		/*
1371		 * write is not supported
1372		 */
1373	} else {
1374		if (start)
1375			*start = buffer;
1376
1377		size = mptscsih_host_info(ioc, buffer, offset, length);
1378	}
1379
1380	return size;
1381}
1382
1383/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1384#define ADD_INDEX_LOG(req_ent)	do { } while(0)
1385
1386/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1387/**
1388 *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1389 *	@SCpnt: Pointer to scsi_cmnd structure
1390 *	@done: Pointer SCSI mid-layer IO completion function
1391 *
1392 *	(linux scsi_host_template.queuecommand routine)
1393 *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1394 *	from a linux scsi_cmnd request and send it to the IOC.
1395 *
1396 *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1397 */
1398int
1399mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1400{
1401	MPT_SCSI_HOST		*hd;
1402	MPT_FRAME_HDR		*mf;
1403	SCSIIORequest_t		*pScsiReq;
1404	VirtDevice		*vdevice = SCpnt->device->hostdata;
1405	u32	 datalen;
1406	u32	 scsictl;
1407	u32	 scsidir;
1408	u32	 cmd_len;
1409	int	 my_idx;
1410	int	 ii;
1411	MPT_ADAPTER *ioc;
1412
1413	hd = shost_priv(SCpnt->device->host);
1414	ioc = hd->ioc;
1415	SCpnt->scsi_done = done;
1416
1417	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
1418		ioc->name, SCpnt, done));
1419
1420	if (ioc->taskmgmt_quiesce_io)
1421		return SCSI_MLQUEUE_HOST_BUSY;
1422
1423	/*
1424	 *  Put together a MPT SCSI request...
1425	 */
1426	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1427		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1428				ioc->name));
1429		return SCSI_MLQUEUE_HOST_BUSY;
1430	}
1431
1432	pScsiReq = (SCSIIORequest_t *) mf;
1433
1434	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1435
1436	ADD_INDEX_LOG(my_idx);
1437
1438	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1439	 *    Seems we may receive a buffer (datalen>0) even when there
1440	 *    will be no data transfer!  GRRRRR...
1441	 */
1442	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1443		datalen = scsi_bufflen(SCpnt);
1444		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1445	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1446		datalen = scsi_bufflen(SCpnt);
1447		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1448	} else {
1449		datalen = 0;
1450		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1451	}
1452
1453	/* Default to untagged. Once a target structure has been allocated,
1454	 * use the Inquiry data to determine if device supports tagged.
1455	 */
1456	if (vdevice
1457	    && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1458	    && (SCpnt->device->tagged_supported)) {
1459		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1460		if (SCpnt->request && SCpnt->request->ioprio) {
1461			if (((SCpnt->request->ioprio & 0x7) == 1) ||
1462				!(SCpnt->request->ioprio & 0x7))
1463				scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
1464		}
1465	} else
1466		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1467
1468
1469	/* Use the above information to set up the message frame
1470	 */
1471	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1472	pScsiReq->Bus = vdevice->vtarget->channel;
1473	pScsiReq->ChainOffset = 0;
1474	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1475		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1476	else
1477		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1478	pScsiReq->CDBLength = SCpnt->cmd_len;
1479	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1480	pScsiReq->Reserved = 0;
1481	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1482	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1483	pScsiReq->Control = cpu_to_le32(scsictl);
1484
1485	/*
1486	 *  Write SCSI CDB into the message
1487	 */
1488	cmd_len = SCpnt->cmd_len;
1489	for (ii=0; ii < cmd_len; ii++)
1490		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1491
1492	for (ii=cmd_len; ii < 16; ii++)
1493		pScsiReq->CDB[ii] = 0;
1494
1495	/* DataLength */
1496	pScsiReq->DataLength = cpu_to_le32(datalen);
1497
1498	/* SenseBuffer low address */
1499	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1500					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1501
1502	/* Now add the SG list
1503	 * Always have a SGE even if null length.
1504	 */
1505	if (datalen == 0) {
1506		/* Add a NULL SGE */
1507		ioc->add_sge((char *)&pScsiReq->SGL,
1508			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1509			(dma_addr_t) -1);
1510	} else {
1511		/* Add a 32 or 64 bit SGE */
1512		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1513			goto fail;
1514	}
1515
1516	SCpnt->host_scribble = (unsigned char *)mf;
1517	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1518
1519	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1520	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1521			ioc->name, SCpnt, mf, my_idx));
1522	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1523	return 0;
1524
1525 fail:
1526	mptscsih_freeChainBuffers(ioc, my_idx);
1527	mpt_free_msg_frame(ioc, mf);
1528	return SCSI_MLQUEUE_HOST_BUSY;
1529}
1530
1531/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1532/*
1533 *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1534 *	with a SCSI IO request
1535 *	@hd: Pointer to the MPT_SCSI_HOST instance
1536 *	@req_idx: Index of the SCSI IO request frame.
1537 *
1538 *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1539 *	No return.
1540 */
1541static void
1542mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1543{
1544	MPT_FRAME_HDR *chain;
1545	unsigned long flags;
1546	int chain_idx;
1547	int next;
1548
1549	/* Get the first chain index and reset
1550	 * tracker state.
1551	 */
1552	chain_idx = ioc->ReqToChain[req_idx];
1553	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1554
1555	while (chain_idx != MPT_HOST_NO_CHAIN) {
1556
1557		/* Save the next chain buffer index */
1558		next = ioc->ChainToChain[chain_idx];
1559
1560		/* Free this chain buffer and reset
1561		 * tracker
1562		 */
1563		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1564
1565		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1566					+ (chain_idx * ioc->req_sz));
1567
1568		spin_lock_irqsave(&ioc->FreeQlock, flags);
1569		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1570		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1571
1572		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1573				ioc->name, chain_idx));
1574
1575		/* handle next */
1576		chain_idx = next;
1577	}
1578	return;
1579}
1580
1581/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1582/*
1583 *	Reset Handling
1584 */
1585
1586/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1587/**
1588 *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1589 *	@hd: Pointer to MPT_SCSI_HOST structure
1590 *	@type: Task Management type
1591 *	@channel: channel number for task management
1592 *	@id: Logical Target ID for reset (if appropriate)
1593 *	@lun: Logical Unit for reset (if appropriate)
1594 *	@ctx2abort: Context for the task to be aborted (if appropriate)
1595 *	@timeout: timeout for task management control
1596 *
1597 *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1598 *	or a non-interrupt thread.  In the former, must not call schedule().
1599 *
1600 *	Not all fields are meaningfull for all task types.
1601 *
1602 *	Returns 0 for SUCCESS, or FAILED.
1603 *
1604 **/
1605int
1606mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1607	int ctx2abort, ulong timeout)
1608{
1609	MPT_FRAME_HDR	*mf;
1610	SCSITaskMgmt_t	*pScsiTm;
1611	int		 ii;
1612	int		 retval;
1613	MPT_ADAPTER 	*ioc = hd->ioc;
1614	unsigned long	 timeleft;
1615	u8		 issue_hard_reset;
1616	u32		 ioc_raw_state;
1617	unsigned long	 time_count;
1618
1619	issue_hard_reset = 0;
1620	ioc_raw_state = mpt_GetIocState(ioc, 0);
1621
1622	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1623		printk(MYIOC_s_WARN_FMT
1624			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1625			ioc->name, type, ioc_raw_state);
1626		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1627		    ioc->name, __func__);
1628		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1629			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1630			    "FAILED!!\n", ioc->name);
1631		return 0;
1632	}
1633
1634	/* DOORBELL ACTIVE check is not required if
1635	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1636	*/
1637
1638	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1639		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1640		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1641		printk(MYIOC_s_WARN_FMT
1642			"TaskMgmt type=%x: ioc_state: "
1643			"DOORBELL_ACTIVE (0x%x)!\n",
1644			ioc->name, type, ioc_raw_state);
1645		return FAILED;
1646	}
1647
1648	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1649	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1650		mf = NULL;
1651		retval = FAILED;
1652		goto out;
1653	}
1654
1655	/* Return Fail to calling function if no message frames available.
1656	 */
1657	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1658		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1659			"TaskMgmt no msg frames!!\n", ioc->name));
1660		retval = FAILED;
1661		mpt_clear_taskmgmt_in_progress_flag(ioc);
1662		goto out;
1663	}
1664	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1665			ioc->name, mf));
1666
1667	/* Format the Request
1668	 */
1669	pScsiTm = (SCSITaskMgmt_t *) mf;
1670	pScsiTm->TargetID = id;
1671	pScsiTm->Bus = channel;
1672	pScsiTm->ChainOffset = 0;
1673	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1674
1675	pScsiTm->Reserved = 0;
1676	pScsiTm->TaskType = type;
1677	pScsiTm->Reserved1 = 0;
1678	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1679                    ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1680
1681	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1682
1683	for (ii=0; ii < 7; ii++)
1684		pScsiTm->Reserved2[ii] = 0;
1685
1686	pScsiTm->TaskMsgContext = ctx2abort;
1687
1688	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1689		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1690		type, timeout));
1691
1692	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1693
1694	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1695	time_count = jiffies;
1696	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1697	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1698		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1699	else {
1700		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1701			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1702		if (retval) {
1703			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1704				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1705				ioc->name, mf, retval));
1706			mpt_free_msg_frame(ioc, mf);
1707			mpt_clear_taskmgmt_in_progress_flag(ioc);
1708			goto out;
1709		}
1710	}
1711
1712	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1713		timeout*HZ);
1714	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1715		retval = FAILED;
1716		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1717		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1718		mpt_clear_taskmgmt_in_progress_flag(ioc);
1719		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1720			goto out;
1721		issue_hard_reset = 1;
1722		goto out;
1723	}
1724
1725	retval = mptscsih_taskmgmt_reply(ioc, type,
1726	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1727
1728	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1729	    "TaskMgmt completed (%d seconds)\n",
1730	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1731
1732 out:
1733
1734	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1735	if (issue_hard_reset) {
1736		printk(MYIOC_s_WARN_FMT
1737		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1738		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1739		retval = (ioc->bus_type == SAS) ?
1740			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1741			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1742		mpt_free_msg_frame(ioc, mf);
1743	}
1744
1745	retval = (retval == 0) ? 0 : FAILED;
1746	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1747	return retval;
1748}
1749EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1750
1751static int
1752mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1753{
1754	switch (ioc->bus_type) {
1755	case FC:
1756		return 40;
1757	case SAS:
1758		return 30;
1759	case SPI:
1760	default:
1761		return 10;
1762	}
1763}
1764
1765/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1766/**
1767 *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1768 *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1769 *
1770 *	(linux scsi_host_template.eh_abort_handler routine)
1771 *
1772 *	Returns SUCCESS or FAILED.
1773 **/
1774int
1775mptscsih_abort(struct scsi_cmnd * SCpnt)
1776{
1777	MPT_SCSI_HOST	*hd;
1778	MPT_FRAME_HDR	*mf;
1779	u32		 ctx2abort;
1780	int		 scpnt_idx;
1781	int		 retval;
1782	VirtDevice	 *vdevice;
1783	MPT_ADAPTER	*ioc;
1784
1785	/* If we can't locate our host adapter structure, return FAILED status.
1786	 */
1787	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1788		SCpnt->result = DID_RESET << 16;
1789		SCpnt->scsi_done(SCpnt);
1790		printk(KERN_ERR MYNAM ": task abort: "
1791		    "can't locate host! (sc=%p)\n", SCpnt);
1792		return FAILED;
1793	}
1794
1795	ioc = hd->ioc;
1796	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1797	       ioc->name, SCpnt);
1798	scsi_print_command(SCpnt);
1799
1800	vdevice = SCpnt->device->hostdata;
1801	if (!vdevice || !vdevice->vtarget) {
1802		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1803		    "task abort: device has been deleted (sc=%p)\n",
1804		    ioc->name, SCpnt));
1805		SCpnt->result = DID_NO_CONNECT << 16;
1806		SCpnt->scsi_done(SCpnt);
1807		retval = SUCCESS;
1808		goto out;
1809	}
1810
1811	/* Task aborts are not supported for hidden raid components.
1812	 */
1813	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1814		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1815		    "task abort: hidden raid component (sc=%p)\n",
1816		    ioc->name, SCpnt));
1817		SCpnt->result = DID_RESET << 16;
1818		retval = FAILED;
1819		goto out;
1820	}
1821
1822	/* Task aborts are not supported for volumes.
1823	 */
1824	if (vdevice->vtarget->raidVolume) {
1825		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1826		    "task abort: raid volume (sc=%p)\n",
1827		    ioc->name, SCpnt));
1828		SCpnt->result = DID_RESET << 16;
1829		retval = FAILED;
1830		goto out;
1831	}
1832
1833	/* Find this command
1834	 */
1835	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1836		/* Cmd not found in ScsiLookup.
1837		 * Do OS callback.
1838		 */
1839		SCpnt->result = DID_RESET << 16;
1840		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1841		   "Command not in the active list! (sc=%p)\n", ioc->name,
1842		   SCpnt));
1843		retval = SUCCESS;
1844		goto out;
1845	}
1846
1847	if (ioc->timeouts < -1)
1848		ioc->timeouts++;
1849
1850	if (mpt_fwfault_debug)
1851		mpt_halt_firmware(ioc);
1852
1853	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1854	 * (the IO to be ABORT'd)
1855	 *
1856	 * NOTE: Since we do not byteswap MsgContext, we do not
1857	 *	 swap it here either.  It is an opaque cookie to
1858	 *	 the controller, so it does not matter. -DaveM
1859	 */
1860	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1861	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1862	retval = mptscsih_IssueTaskMgmt(hd,
1863			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1864			 vdevice->vtarget->channel,
1865			 vdevice->vtarget->id, vdevice->lun,
1866			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1867
1868	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1869		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1870		    "task abort: command still in active list! (sc=%p)\n",
1871		    ioc->name, SCpnt));
1872		retval = FAILED;
1873	} else {
1874		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1875		    "task abort: command cleared from active list! (sc=%p)\n",
1876		    ioc->name, SCpnt));
1877		retval = SUCCESS;
1878	}
1879
1880 out:
1881	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1882	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1883	    SCpnt);
1884
1885	return retval;
1886}
1887
1888/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1889/**
1890 *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1891 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1892 *
1893 *	(linux scsi_host_template.eh_dev_reset_handler routine)
1894 *
1895 *	Returns SUCCESS or FAILED.
1896 **/
1897int
1898mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1899{
1900	MPT_SCSI_HOST	*hd;
1901	int		 retval;
1902	VirtDevice	 *vdevice;
1903	MPT_ADAPTER	*ioc;
1904
1905	/* If we can't locate our host adapter structure, return FAILED status.
1906	 */
1907	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1908		printk(KERN_ERR MYNAM ": target reset: "
1909		   "Can't locate host! (sc=%p)\n", SCpnt);
1910		return FAILED;
1911	}
1912
1913	ioc = hd->ioc;
1914	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1915	       ioc->name, SCpnt);
1916	scsi_print_command(SCpnt);
1917
1918	vdevice = SCpnt->device->hostdata;
1919	if (!vdevice || !vdevice->vtarget) {
1920		retval = 0;
1921		goto out;
1922	}
1923
1924	/* Target reset to hidden raid component is not supported
1925	 */
1926	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1927		retval = FAILED;
1928		goto out;
1929	}
1930
1931	retval = mptscsih_IssueTaskMgmt(hd,
1932				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1933				vdevice->vtarget->channel,
1934				vdevice->vtarget->id, 0, 0,
1935				mptscsih_get_tm_timeout(ioc));
1936
1937 out:
1938	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1939	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1940
1941	if (retval == 0)
1942		return SUCCESS;
1943	else
1944		return FAILED;
1945}
1946
1947
1948/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1949/**
1950 *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1951 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1952 *
1953 *	(linux scsi_host_template.eh_bus_reset_handler routine)
1954 *
1955 *	Returns SUCCESS or FAILED.
1956 **/
1957int
1958mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1959{
1960	MPT_SCSI_HOST	*hd;
1961	int		 retval;
1962	VirtDevice	 *vdevice;
1963	MPT_ADAPTER	*ioc;
1964
1965	/* If we can't locate our host adapter structure, return FAILED status.
1966	 */
1967	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1968		printk(KERN_ERR MYNAM ": bus reset: "
1969		   "Can't locate host! (sc=%p)\n", SCpnt);
1970		return FAILED;
1971	}
1972
1973	ioc = hd->ioc;
1974	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1975	       ioc->name, SCpnt);
1976	scsi_print_command(SCpnt);
1977
1978	if (ioc->timeouts < -1)
1979		ioc->timeouts++;
1980
1981	vdevice = SCpnt->device->hostdata;
1982	if (!vdevice || !vdevice->vtarget)
1983		return SUCCESS;
1984	retval = mptscsih_IssueTaskMgmt(hd,
1985					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1986					vdevice->vtarget->channel, 0, 0, 0,
1987					mptscsih_get_tm_timeout(ioc));
1988
1989	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1990	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1991
1992	if (retval == 0)
1993		return SUCCESS;
1994	else
1995		return FAILED;
1996}
1997
1998/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1999/**
2000 *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
2001 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2002 *
2003 *	(linux scsi_host_template.eh_host_reset_handler routine)
2004 *
2005 *	Returns SUCCESS or FAILED.
2006 */
2007int
2008mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2009{
2010	MPT_SCSI_HOST *  hd;
2011	int              status = SUCCESS;
2012	MPT_ADAPTER	*ioc;
2013	int		retval;
2014
2015	/*  If we can't locate the host to reset, then we failed. */
2016	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
2017		printk(KERN_ERR MYNAM ": host reset: "
2018		    "Can't locate host! (sc=%p)\n", SCpnt);
2019		return FAILED;
2020	}
2021
2022	/* make sure we have no outstanding commands at this stage */
2023	mptscsih_flush_running_cmds(hd);
2024
2025	ioc = hd->ioc;
2026	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
2027	    ioc->name, SCpnt);
2028
2029	/*  If our attempts to reset the host failed, then return a failed
2030	 *  status.  The host will be taken off line by the SCSI mid-layer.
2031	 */
2032    retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2033	if (retval < 0)
2034		status = FAILED;
2035	else
2036		status = SUCCESS;
2037
2038	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
2039	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
2040
2041	return status;
2042}
2043
2044static int
2045mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
2046	SCSITaskMgmtReply_t *pScsiTmReply)
2047{
2048	u16			 iocstatus;
2049	u32			 termination_count;
2050	int			 retval;
2051
2052	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
2053		retval = FAILED;
2054		goto out;
2055	}
2056
2057	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2058
2059	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2060	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2061
2062	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2063	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
2064	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
2065	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
2066	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
2067	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
2068	    termination_count));
2069
2070	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2071	    pScsiTmReply->ResponseCode)
2072		mptscsih_taskmgmt_response_code(ioc,
2073		    pScsiTmReply->ResponseCode);
2074
2075	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
2076		retval = 0;
2077		goto out;
2078	}
2079
2080	retval = FAILED;
2081	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
2082		if (termination_count == 1)
2083			retval = 0;
2084		goto out;
2085	}
2086
2087	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
2088	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
2089		retval = 0;
2090
2091 out:
2092	return retval;
2093}
2094
2095/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2096void
2097mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2098{
2099	char *desc;
2100
2101	switch (response_code) {
2102	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2103		desc = "The task completed.";
2104		break;
2105	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2106		desc = "The IOC received an invalid frame status.";
2107		break;
2108	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2109		desc = "The task type is not supported.";
2110		break;
2111	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2112		desc = "The requested task failed.";
2113		break;
2114	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2115		desc = "The task completed successfully.";
2116		break;
2117	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2118		desc = "The LUN request is invalid.";
2119		break;
2120	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2121		desc = "The task is in the IOC queue and has not been sent to target.";
2122		break;
2123	default:
2124		desc = "unknown";
2125		break;
2126	}
2127	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2128		ioc->name, response_code, desc);
2129}
2130EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2131
2132/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2133/**
2134 *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2135 *	@ioc: Pointer to MPT_ADAPTER structure
2136 *	@mf: Pointer to SCSI task mgmt request frame
2137 *	@mr: Pointer to SCSI task mgmt reply frame
2138 *
2139 *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2140 *	of any SCSI task management request.
2141 *	This routine is registered with the MPT (base) driver at driver
2142 *	load/init time via the mpt_register() API call.
2143 *
2144 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2145 **/
2146int
2147mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2148	MPT_FRAME_HDR *mr)
2149{
2150	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2151		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2152
2153	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2154
2155	if (!mr)
2156		goto out;
2157
2158	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2159	memcpy(ioc->taskmgmt_cmds.reply, mr,
2160	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2161 out:
2162	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2163		mpt_clear_taskmgmt_in_progress_flag(ioc);
2164		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2165		complete(&ioc->taskmgmt_cmds.done);
2166		if (ioc->bus_type == SAS)
2167			ioc->schedule_target_reset(ioc);
2168		return 1;
2169	}
2170	return 0;
2171}
2172
2173/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2174/*
2175 *	This is anyones guess quite frankly.
2176 */
2177int
2178mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2179		sector_t capacity, int geom[])
2180{
2181	int		heads;
2182	int		sectors;
2183	sector_t	cylinders;
2184	ulong 		dummy;
2185
2186	heads = 64;
2187	sectors = 32;
2188
2189	dummy = heads * sectors;
2190	cylinders = capacity;
2191	sector_div(cylinders,dummy);
2192
2193	/*
2194	 * Handle extended translation size for logical drives
2195	 * > 1Gb
2196	 */
2197	if ((ulong)capacity >= 0x200000) {
2198		heads = 255;
2199		sectors = 63;
2200		dummy = heads * sectors;
2201		cylinders = capacity;
2202		sector_div(cylinders,dummy);
2203	}
2204
2205	/* return result */
2206	geom[0] = heads;
2207	geom[1] = sectors;
2208	geom[2] = cylinders;
2209
2210	return 0;
2211}
2212
2213/* Search IOC page 3 to determine if this is hidden physical disk
2214 *
2215 */
2216int
2217mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2218{
2219	struct inactive_raid_component_info *component_info;
2220	int i, j;
2221	RaidPhysDiskPage1_t *phys_disk;
2222	int rc = 0;
2223	int num_paths;
2224
2225	if (!ioc->raid_data.pIocPg3)
2226		goto out;
2227	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2228		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2229		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2230			rc = 1;
2231			goto out;
2232		}
2233	}
2234
2235	if (ioc->bus_type != SAS)
2236		goto out;
2237
2238	/*
2239	 * Check if dual path
2240	 */
2241	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2242		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2243		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2244		if (num_paths < 2)
2245			continue;
2246		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2247		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2248		if (!phys_disk)
2249			continue;
2250		if ((mpt_raid_phys_disk_pg1(ioc,
2251		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2252		    phys_disk))) {
2253			kfree(phys_disk);
2254			continue;
2255		}
2256		for (j = 0; j < num_paths; j++) {
2257			if ((phys_disk->Path[j].Flags &
2258			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2259				continue;
2260			if ((phys_disk->Path[j].Flags &
2261			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2262				continue;
2263			if ((id == phys_disk->Path[j].PhysDiskID) &&
2264			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2265				rc = 1;
2266				kfree(phys_disk);
2267				goto out;
2268			}
2269		}
2270		kfree(phys_disk);
2271	}
2272
2273
2274	/*
2275	 * Check inactive list for matching phys disks
2276	 */
2277	if (list_empty(&ioc->raid_data.inactive_list))
2278		goto out;
2279
2280	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2281	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2282	    list) {
2283		if ((component_info->d.PhysDiskID == id) &&
2284		    (component_info->d.PhysDiskBus == channel))
2285			rc = 1;
2286	}
2287	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2288
2289 out:
2290	return rc;
2291}
2292EXPORT_SYMBOL(mptscsih_is_phys_disk);
2293
2294u8
2295mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2296{
2297	struct inactive_raid_component_info *component_info;
2298	int i, j;
2299	RaidPhysDiskPage1_t *phys_disk;
2300	int rc = -ENXIO;
2301	int num_paths;
2302
2303	if (!ioc->raid_data.pIocPg3)
2304		goto out;
2305	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2306		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2307		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2308			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2309			goto out;
2310		}
2311	}
2312
2313	if (ioc->bus_type != SAS)
2314		goto out;
2315
2316	/*
2317	 * Check if dual path
2318	 */
2319	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2320		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2321		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2322		if (num_paths < 2)
2323			continue;
2324		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2325		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2326		if (!phys_disk)
2327			continue;
2328		if ((mpt_raid_phys_disk_pg1(ioc,
2329		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2330		    phys_disk))) {
2331			kfree(phys_disk);
2332			continue;
2333		}
2334		for (j = 0; j < num_paths; j++) {
2335			if ((phys_disk->Path[j].Flags &
2336			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2337				continue;
2338			if ((phys_disk->Path[j].Flags &
2339			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2340				continue;
2341			if ((id == phys_disk->Path[j].PhysDiskID) &&
2342			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2343				rc = phys_disk->PhysDiskNum;
2344				kfree(phys_disk);
2345				goto out;
2346			}
2347		}
2348		kfree(phys_disk);
2349	}
2350
2351	/*
2352	 * Check inactive list for matching phys disks
2353	 */
2354	if (list_empty(&ioc->raid_data.inactive_list))
2355		goto out;
2356
2357	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2358	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2359	    list) {
2360		if ((component_info->d.PhysDiskID == id) &&
2361		    (component_info->d.PhysDiskBus == channel))
2362			rc = component_info->d.PhysDiskNum;
2363	}
2364	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2365
2366 out:
2367	return rc;
2368}
2369EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2370
2371/*
2372 *	OS entry point to allow for host driver to free allocated memory
2373 *	Called if no device present or device being unloaded
2374 */
2375void
2376mptscsih_slave_destroy(struct scsi_device *sdev)
2377{
2378	struct Scsi_Host	*host = sdev->host;
2379	MPT_SCSI_HOST		*hd = shost_priv(host);
2380	VirtTarget		*vtarget;
2381	VirtDevice		*vdevice;
2382	struct scsi_target 	*starget;
2383
2384	starget = scsi_target(sdev);
2385	vtarget = starget->hostdata;
2386	vdevice = sdev->hostdata;
2387	if (!vdevice)
2388		return;
2389
2390	mptscsih_search_running_cmds(hd, vdevice);
2391	vtarget->num_luns--;
2392	mptscsih_synchronize_cache(hd, vdevice);
2393	kfree(vdevice);
2394	sdev->hostdata = NULL;
2395}
2396
2397/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2398/*
2399 *	mptscsih_change_queue_depth - This function will set a devices queue depth
2400 *	@sdev: per scsi_device pointer
2401 *	@qdepth: requested queue depth
2402 *	@reason: calling context
2403 *
2404 *	Adding support for new 'change_queue_depth' api.
2405*/
2406int
2407mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
2408{
2409	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2410	VirtTarget 		*vtarget;
2411	struct scsi_target 	*starget;
2412	int			max_depth;
2413	int			tagged;
2414	MPT_ADAPTER		*ioc = hd->ioc;
2415
2416	starget = scsi_target(sdev);
2417	vtarget = starget->hostdata;
2418
2419	if (reason != SCSI_QDEPTH_DEFAULT)
2420		return -EOPNOTSUPP;
2421
2422	if (ioc->bus_type == SPI) {
2423		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2424			max_depth = 1;
2425		else if (sdev->type == TYPE_DISK &&
2426			 vtarget->minSyncFactor <= MPT_ULTRA160)
2427			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2428		else
2429			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2430	} else
2431		 max_depth = ioc->sh->can_queue;
2432
2433	if (!sdev->tagged_supported)
2434		max_depth = 1;
2435
2436	if (qdepth > max_depth)
2437		qdepth = max_depth;
2438	if (qdepth == 1)
2439		tagged = 0;
2440	else
2441		tagged = MSG_SIMPLE_TAG;
2442
2443	scsi_adjust_queue_depth(sdev, tagged, qdepth);
2444	return sdev->queue_depth;
2445}
2446
2447/*
2448 *	OS entry point to adjust the queue_depths on a per-device basis.
2449 *	Called once per device the bus scan. Use it to force the queue_depth
2450 *	member to 1 if a device does not support Q tags.
2451 *	Return non-zero if fails.
2452 */
2453int
2454mptscsih_slave_configure(struct scsi_device *sdev)
2455{
2456	struct Scsi_Host	*sh = sdev->host;
2457	VirtTarget		*vtarget;
2458	VirtDevice		*vdevice;
2459	struct scsi_target 	*starget;
2460	MPT_SCSI_HOST		*hd = shost_priv(sh);
2461	MPT_ADAPTER		*ioc = hd->ioc;
2462
2463	starget = scsi_target(sdev);
2464	vtarget = starget->hostdata;
2465	vdevice = sdev->hostdata;
2466
2467	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2468		"device @ %p, channel=%d, id=%d, lun=%d\n",
2469		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2470	if (ioc->bus_type == SPI)
2471		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2472		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2473		    ioc->name, sdev->sdtr, sdev->wdtr,
2474		    sdev->ppr, sdev->inquiry_len));
2475
2476	vdevice->configured_lun = 1;
2477
2478	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2479		"Queue depth=%d, tflags=%x\n",
2480		ioc->name, sdev->queue_depth, vtarget->tflags));
2481
2482	if (ioc->bus_type == SPI)
2483		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2484		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2485		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2486		    vtarget->minSyncFactor));
2487
2488	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
2489				    SCSI_QDEPTH_DEFAULT);
2490	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2491		"tagged %d, simple %d, ordered %d\n",
2492		ioc->name,sdev->tagged_supported, sdev->simple_tags,
2493		sdev->ordered_tags));
2494
2495	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2496
2497	return 0;
2498}
2499
2500/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2501/*
2502 *  Private routines...
2503 */
2504
2505/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2506/* Utility function to copy sense data from the scsi_cmnd buffer
2507 * to the FC and SCSI target structures.
2508 *
2509 */
2510static void
2511mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2512{
2513	VirtDevice	*vdevice;
2514	SCSIIORequest_t	*pReq;
2515	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2516	MPT_ADAPTER 	*ioc = hd->ioc;
2517
2518	/* Get target structure
2519	 */
2520	pReq = (SCSIIORequest_t *) mf;
2521	vdevice = sc->device->hostdata;
2522
2523	if (sense_count) {
2524		u8 *sense_data;
2525		int req_index;
2526
2527		/* Copy the sense received into the scsi command block. */
2528		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2529		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2530		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2531
2532		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2533		 */
2534		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2535			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2536				int idx;
2537
2538				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2539				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2540				ioc->events[idx].eventContext = ioc->eventContext;
2541
2542				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2543					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2544					(sc->device->channel << 8) | sc->device->id;
2545
2546				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2547
2548				ioc->eventContext++;
2549				if (ioc->pcidev->vendor ==
2550				    PCI_VENDOR_ID_IBM) {
2551					mptscsih_issue_sep_command(ioc,
2552					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2553					vdevice->vtarget->tflags |=
2554					    MPT_TARGET_FLAGS_LED_ON;
2555				}
2556			}
2557		}
2558	} else {
2559		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2560				ioc->name));
2561	}
2562}
2563
2564/**
2565 * mptscsih_get_scsi_lookup - retrieves scmd entry
2566 * @ioc: Pointer to MPT_ADAPTER structure
2567 * @i: index into the array
2568 *
2569 * Returns the scsi_cmd pointer
2570 */
2571struct scsi_cmnd *
2572mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2573{
2574	unsigned long	flags;
2575	struct scsi_cmnd *scmd;
2576
2577	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2578	scmd = ioc->ScsiLookup[i];
2579	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2580
2581	return scmd;
2582}
2583EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2584
2585/**
2586 * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2587 * @ioc: Pointer to MPT_ADAPTER structure
2588 * @i: index into the array
2589 *
2590 * Returns the scsi_cmd pointer
2591 *
2592 **/
2593static struct scsi_cmnd *
2594mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2595{
2596	unsigned long	flags;
2597	struct scsi_cmnd *scmd;
2598
2599	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2600	scmd = ioc->ScsiLookup[i];
2601	ioc->ScsiLookup[i] = NULL;
2602	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2603
2604	return scmd;
2605}
2606
2607/**
2608 * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2609 *
2610 * @ioc: Pointer to MPT_ADAPTER structure
2611 * @i: index into the array
2612 * @scmd: scsi_cmnd pointer
2613 *
2614 **/
2615static void
2616mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2617{
2618	unsigned long	flags;
2619
2620	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2621	ioc->ScsiLookup[i] = scmd;
2622	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2623}
2624
2625/**
2626 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2627 * @ioc: Pointer to MPT_ADAPTER structure
2628 * @sc: scsi_cmnd pointer
2629 */
2630static int
2631SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2632{
2633	unsigned long	flags;
2634	int i, index=-1;
2635
2636	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2637	for (i = 0; i < ioc->req_depth; i++) {
2638		if (ioc->ScsiLookup[i] == sc) {
2639			index = i;
2640			goto out;
2641		}
2642	}
2643
2644 out:
2645	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2646	return index;
2647}
2648
2649/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2650int
2651mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2652{
2653	MPT_SCSI_HOST	*hd;
2654
2655	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2656		return 0;
2657
2658	hd = shost_priv(ioc->sh);
2659	switch (reset_phase) {
2660	case MPT_IOC_SETUP_RESET:
2661		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2662		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2663		break;
2664	case MPT_IOC_PRE_RESET:
2665		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2666		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2667		mptscsih_flush_running_cmds(hd);
2668		break;
2669	case MPT_IOC_POST_RESET:
2670		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2671		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2672		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2673			ioc->internal_cmds.status |=
2674				MPT_MGMT_STATUS_DID_IOCRESET;
2675			complete(&ioc->internal_cmds.done);
2676		}
2677		break;
2678	default:
2679		break;
2680	}
2681	return 1;		/* currently means nothing really */
2682}
2683
2684/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2685int
2686mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2687{
2688	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2689
2690	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2691		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2692		ioc->name, event));
2693
2694	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2695	    event == MPI_EVENT_EXT_BUS_RESET) &&
2696	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2697			ioc->soft_resets++;
2698
2699	return 1;		/* currently means nothing really */
2700}
2701
2702/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2703/*
2704 *  Bus Scan and Domain Validation functionality ...
2705 */
2706
2707/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2708/*
2709 *	mptscsih_scandv_complete - Scan and DV callback routine registered
2710 *	to Fustion MPT (base) driver.
2711 *
2712 *	@ioc: Pointer to MPT_ADAPTER structure
2713 *	@mf: Pointer to original MPT request frame
2714 *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2715 *
2716 *	This routine is called from mpt.c::mpt_interrupt() at the completion
2717 *	of any SCSI IO request.
2718 *	This routine is registered with the Fusion MPT (base) driver at driver
2719 *	load/init time via the mpt_register() API call.
2720 *
2721 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2722 *
2723 *	Remark: Sets a completion code and (possibly) saves sense data
2724 *	in the IOC member localReply structure.
2725 *	Used ONLY for DV and other internal commands.
2726 */
2727int
2728mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2729				MPT_FRAME_HDR *reply)
2730{
2731	SCSIIORequest_t *pReq;
2732	SCSIIOReply_t	*pReply;
2733	u8		 cmd;
2734	u16		 req_idx;
2735	u8	*sense_data;
2736	int		 sz;
2737
2738	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2739	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2740	if (!reply)
2741		goto out;
2742
2743	pReply = (SCSIIOReply_t *) reply;
2744	pReq = (SCSIIORequest_t *) req;
2745	ioc->internal_cmds.completion_code =
2746	    mptscsih_get_completion_code(ioc, req, reply);
2747	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2748	memcpy(ioc->internal_cmds.reply, reply,
2749	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2750	cmd = reply->u.hdr.Function;
2751	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2752	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2753	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2754		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2755		sense_data = ((u8 *)ioc->sense_buf_pool +
2756		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2757		sz = min_t(int, pReq->SenseBufferLength,
2758		    MPT_SENSE_BUFFER_ALLOC);
2759		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2760	}
2761 out:
2762	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2763		return 0;
2764	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2765	complete(&ioc->internal_cmds.done);
2766	return 1;
2767}
2768
2769
2770/**
2771 *	mptscsih_get_completion_code - get completion code from MPT request
2772 *	@ioc: Pointer to MPT_ADAPTER structure
2773 *	@req: Pointer to original MPT request frame
2774 *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2775 *
2776 **/
2777static int
2778mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2779				MPT_FRAME_HDR *reply)
2780{
2781	SCSIIOReply_t	*pReply;
2782	MpiRaidActionReply_t *pr;
2783	u8		 scsi_status;
2784	u16		 status;
2785	int		 completion_code;
2786
2787	pReply = (SCSIIOReply_t *)reply;
2788	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2789	scsi_status = pReply->SCSIStatus;
2790
2791	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2792	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2793	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2794	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2795
2796	switch (status) {
2797
2798	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2799		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2800		break;
2801
2802	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2803	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2804	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2805	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2806		completion_code = MPT_SCANDV_DID_RESET;
2807		break;
2808
2809	case MPI_IOCSTATUS_BUSY:
2810	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2811		completion_code = MPT_SCANDV_BUSY;
2812		break;
2813
2814	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2815	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2816	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2817		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2818			completion_code = MPT_SCANDV_GOOD;
2819		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2820			pr = (MpiRaidActionReply_t *)reply;
2821			if (le16_to_cpu(pr->ActionStatus) ==
2822				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2823				completion_code = MPT_SCANDV_GOOD;
2824			else
2825				completion_code = MPT_SCANDV_SOME_ERROR;
2826		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2827			completion_code = MPT_SCANDV_SENSE;
2828		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2829			if (req->u.scsireq.CDB[0] == INQUIRY)
2830				completion_code = MPT_SCANDV_ISSUE_SENSE;
2831			else
2832				completion_code = MPT_SCANDV_DID_RESET;
2833		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2834			completion_code = MPT_SCANDV_DID_RESET;
2835		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2836			completion_code = MPT_SCANDV_DID_RESET;
2837		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2838			completion_code = MPT_SCANDV_BUSY;
2839		else
2840			completion_code = MPT_SCANDV_GOOD;
2841		break;
2842
2843	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2844		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2845			completion_code = MPT_SCANDV_DID_RESET;
2846		else
2847			completion_code = MPT_SCANDV_SOME_ERROR;
2848		break;
2849	default:
2850		completion_code = MPT_SCANDV_SOME_ERROR;
2851		break;
2852
2853	}	/* switch(status) */
2854
2855	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2856	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2857	return completion_code;
2858}
2859
2860/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2861/**
2862 *	mptscsih_do_cmd - Do internal command.
2863 *	@hd: MPT_SCSI_HOST pointer
2864 *	@io: INTERNAL_CMD pointer.
2865 *
2866 *	Issue the specified internally generated command and do command
2867 *	specific cleanup. For bus scan / DV only.
2868 *	NOTES: If command is Inquiry and status is good,
2869 *	initialize a target structure, save the data
2870 *
2871 *	Remark: Single threaded access only.
2872 *
2873 *	Return:
2874 *		< 0 if an illegal command or no resources
2875 *
2876 *		   0 if good
2877 *
2878 *		 > 0 if command complete but some type of completion error.
2879 */
2880static int
2881mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2882{
2883	MPT_FRAME_HDR	*mf;
2884	SCSIIORequest_t	*pScsiReq;
2885	int		 my_idx, ii, dir;
2886	int		 timeout;
2887	char		 cmdLen;
2888	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2889	u8		 cmd = io->cmd;
2890	MPT_ADAPTER *ioc = hd->ioc;
2891	int		 ret = 0;
2892	unsigned long	 timeleft;
2893	unsigned long	 flags;
2894
2895	/* don't send internal command during diag reset */
2896	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2897	if (ioc->ioc_reset_in_progress) {
2898		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2899		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2900			"%s: busy with host reset\n", ioc->name, __func__));
2901		return MPT_SCANDV_BUSY;
2902	}
2903	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2904
2905	mutex_lock(&ioc->internal_cmds.mutex);
2906
2907	/* Set command specific information
2908	 */
2909	switch (cmd) {
2910	case INQUIRY:
2911		cmdLen = 6;
2912		dir = MPI_SCSIIO_CONTROL_READ;
2913		CDB[0] = cmd;
2914		CDB[4] = io->size;
2915		timeout = 10;
2916		break;
2917
2918	case TEST_UNIT_READY:
2919		cmdLen = 6;
2920		dir = MPI_SCSIIO_CONTROL_READ;
2921		timeout = 10;
2922		break;
2923
2924	case START_STOP:
2925		cmdLen = 6;
2926		dir = MPI_SCSIIO_CONTROL_READ;
2927		CDB[0] = cmd;
2928		CDB[4] = 1;	/*Spin up the disk */
2929		timeout = 15;
2930		break;
2931
2932	case REQUEST_SENSE:
2933		cmdLen = 6;
2934		CDB[0] = cmd;
2935		CDB[4] = io->size;
2936		dir = MPI_SCSIIO_CONTROL_READ;
2937		timeout = 10;
2938		break;
2939
2940	case READ_BUFFER:
2941		cmdLen = 10;
2942		dir = MPI_SCSIIO_CONTROL_READ;
2943		CDB[0] = cmd;
2944		if (io->flags & MPT_ICFLAG_ECHO) {
2945			CDB[1] = 0x0A;
2946		} else {
2947			CDB[1] = 0x02;
2948		}
2949
2950		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2951			CDB[1] |= 0x01;
2952		}
2953		CDB[6] = (io->size >> 16) & 0xFF;
2954		CDB[7] = (io->size >>  8) & 0xFF;
2955		CDB[8] = io->size & 0xFF;
2956		timeout = 10;
2957		break;
2958
2959	case WRITE_BUFFER:
2960		cmdLen = 10;
2961		dir = MPI_SCSIIO_CONTROL_WRITE;
2962		CDB[0] = cmd;
2963		if (io->flags & MPT_ICFLAG_ECHO) {
2964			CDB[1] = 0x0A;
2965		} else {
2966			CDB[1] = 0x02;
2967		}
2968		CDB[6] = (io->size >> 16) & 0xFF;
2969		CDB[7] = (io->size >>  8) & 0xFF;
2970		CDB[8] = io->size & 0xFF;
2971		timeout = 10;
2972		break;
2973
2974	case RESERVE:
2975		cmdLen = 6;
2976		dir = MPI_SCSIIO_CONTROL_READ;
2977		CDB[0] = cmd;
2978		timeout = 10;
2979		break;
2980
2981	case RELEASE:
2982		cmdLen = 6;
2983		dir = MPI_SCSIIO_CONTROL_READ;
2984		CDB[0] = cmd;
2985		timeout = 10;
2986		break;
2987
2988	case SYNCHRONIZE_CACHE:
2989		cmdLen = 10;
2990		dir = MPI_SCSIIO_CONTROL_READ;
2991		CDB[0] = cmd;
2992//		CDB[1] = 0x02;	/* set immediate bit */
2993		timeout = 10;
2994		break;
2995
2996	default:
2997		/* Error Case */
2998		ret = -EFAULT;
2999		goto out;
3000	}
3001
3002	/* Get and Populate a free Frame
3003	 * MsgContext set in mpt_get_msg_frame call
3004	 */
3005	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3006		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
3007		    ioc->name, __func__));
3008		ret = MPT_SCANDV_BUSY;
3009		goto out;
3010	}
3011
3012	pScsiReq = (SCSIIORequest_t *) mf;
3013
3014	/* Get the request index */
3015	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3016	ADD_INDEX_LOG(my_idx); /* for debug */
3017
3018	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3019		pScsiReq->TargetID = io->physDiskNum;
3020		pScsiReq->Bus = 0;
3021		pScsiReq->ChainOffset = 0;
3022		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3023	} else {
3024		pScsiReq->TargetID = io->id;
3025		pScsiReq->Bus = io->channel;
3026		pScsiReq->ChainOffset = 0;
3027		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3028	}
3029
3030	pScsiReq->CDBLength = cmdLen;
3031	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3032
3033	pScsiReq->Reserved = 0;
3034
3035	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
3036	/* MsgContext set in mpt_get_msg_fram call  */
3037
3038	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3039
3040	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3041		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3042	else
3043		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3044
3045	if (cmd == REQUEST_SENSE) {
3046		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3047		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3048		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
3049	}
3050
3051	for (ii = 0; ii < 16; ii++)
3052		pScsiReq->CDB[ii] = CDB[ii];
3053
3054	pScsiReq->DataLength = cpu_to_le32(io->size);
3055	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3056					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3057
3058	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3059	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
3060	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
3061
3062	if (dir == MPI_SCSIIO_CONTROL_READ)
3063		ioc->add_sge((char *) &pScsiReq->SGL,
3064		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
3065	else
3066		ioc->add_sge((char *) &pScsiReq->SGL,
3067		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
3068
3069	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
3070	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3071	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
3072	    timeout*HZ);
3073	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
3074		ret = MPT_SCANDV_DID_RESET;
3075		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3076		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
3077		    cmd));
3078		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
3079			mpt_free_msg_frame(ioc, mf);
3080			goto out;
3081		}
3082		if (!timeleft) {
3083			printk(MYIOC_s_WARN_FMT
3084			       "Issuing Reset from %s!! doorbell=0x%08xh"
3085			       " cmd=0x%02x\n",
3086			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
3087			       cmd);
3088			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
3089			mpt_free_msg_frame(ioc, mf);
3090		}
3091		goto out;
3092	}
3093
3094	ret = ioc->internal_cmds.completion_code;
3095	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
3096			ioc->name, __func__, ret));
3097
3098 out:
3099	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
3100	mutex_unlock(&ioc->internal_cmds.mutex);
3101	return ret;
3102}
3103
3104/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3105/**
3106 *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3107 *	@hd: Pointer to a SCSI HOST structure
3108 *	@vdevice: virtual target device
3109 *
3110 *	Uses the ISR, but with special processing.
3111 *	MUST be single-threaded.
3112 *
3113 */
3114static void
3115mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3116{
3117	INTERNAL_CMD		 iocmd;
3118
3119	/* Ignore hidden raid components, this is handled when the command
3120	 * is sent to the volume
3121	 */
3122	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3123		return;
3124
3125	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3126	    !vdevice->configured_lun)
3127		return;
3128
3129	/* Following parameters will not change
3130	 * in this routine.
3131	 */
3132	iocmd.cmd = SYNCHRONIZE_CACHE;
3133	iocmd.flags = 0;
3134	iocmd.physDiskNum = -1;
3135	iocmd.data = NULL;
3136	iocmd.data_dma = -1;
3137	iocmd.size = 0;
3138	iocmd.rsvd = iocmd.rsvd2 = 0;
3139	iocmd.channel = vdevice->vtarget->channel;
3140	iocmd.id = vdevice->vtarget->id;
3141	iocmd.lun = vdevice->lun;
3142
3143	mptscsih_do_cmd(hd, &iocmd);
3144}
3145
3146static ssize_t
3147mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3148			 char *buf)
3149{
3150	struct Scsi_Host *host = class_to_shost(dev);
3151	MPT_SCSI_HOST	*hd = shost_priv(host);
3152	MPT_ADAPTER *ioc = hd->ioc;
3153
3154	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3155	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3156	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3157	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3158	    ioc->facts.FWVersion.Word & 0x000000FF);
3159}
3160static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3161
3162static ssize_t
3163mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3164			   char *buf)
3165{
3166	struct Scsi_Host *host = class_to_shost(dev);
3167	MPT_SCSI_HOST	*hd = shost_priv(host);
3168	MPT_ADAPTER *ioc = hd->ioc;
3169
3170	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3171	    (ioc->biosVersion & 0xFF000000) >> 24,
3172	    (ioc->biosVersion & 0x00FF0000) >> 16,
3173	    (ioc->biosVersion & 0x0000FF00) >> 8,
3174	    ioc->biosVersion & 0x000000FF);
3175}
3176static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3177
3178static ssize_t
3179mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3180			  char *buf)
3181{
3182	struct Scsi_Host *host = class_to_shost(dev);
3183	MPT_SCSI_HOST	*hd = shost_priv(host);
3184	MPT_ADAPTER *ioc = hd->ioc;
3185
3186	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3187}
3188static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3189
3190static ssize_t
3191mptscsih_version_product_show(struct device *dev,
3192			      struct device_attribute *attr,
3193char *buf)
3194{
3195	struct Scsi_Host *host = class_to_shost(dev);
3196	MPT_SCSI_HOST	*hd = shost_priv(host);
3197	MPT_ADAPTER *ioc = hd->ioc;
3198
3199	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3200}
3201static DEVICE_ATTR(version_product, S_IRUGO,
3202    mptscsih_version_product_show, NULL);
3203
3204static ssize_t
3205mptscsih_version_nvdata_persistent_show(struct device *dev,
3206					struct device_attribute *attr,
3207					char *buf)
3208{
3209	struct Scsi_Host *host = class_to_shost(dev);
3210	MPT_SCSI_HOST	*hd = shost_priv(host);
3211	MPT_ADAPTER *ioc = hd->ioc;
3212
3213	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3214	    ioc->nvdata_version_persistent);
3215}
3216static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3217    mptscsih_version_nvdata_persistent_show, NULL);
3218
3219static ssize_t
3220mptscsih_version_nvdata_default_show(struct device *dev,
3221				     struct device_attribute *attr, char *buf)
3222{
3223	struct Scsi_Host *host = class_to_shost(dev);
3224	MPT_SCSI_HOST	*hd = shost_priv(host);
3225	MPT_ADAPTER *ioc = hd->ioc;
3226
3227	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3228}
3229static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3230    mptscsih_version_nvdata_default_show, NULL);
3231
3232static ssize_t
3233mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3234			 char *buf)
3235{
3236	struct Scsi_Host *host = class_to_shost(dev);
3237	MPT_SCSI_HOST	*hd = shost_priv(host);
3238	MPT_ADAPTER *ioc = hd->ioc;
3239
3240	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3241}
3242static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3243
3244static ssize_t
3245mptscsih_board_assembly_show(struct device *dev,
3246			     struct device_attribute *attr, char *buf)
3247{
3248	struct Scsi_Host *host = class_to_shost(dev);
3249	MPT_SCSI_HOST	*hd = shost_priv(host);
3250	MPT_ADAPTER *ioc = hd->ioc;
3251
3252	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3253}
3254static DEVICE_ATTR(board_assembly, S_IRUGO,
3255    mptscsih_board_assembly_show, NULL);
3256
3257static ssize_t
3258mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3259			   char *buf)
3260{
3261	struct Scsi_Host *host = class_to_shost(dev);
3262	MPT_SCSI_HOST	*hd = shost_priv(host);
3263	MPT_ADAPTER *ioc = hd->ioc;
3264
3265	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3266}
3267static DEVICE_ATTR(board_tracer, S_IRUGO,
3268    mptscsih_board_tracer_show, NULL);
3269
3270static ssize_t
3271mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3272		       char *buf)
3273{
3274	struct Scsi_Host *host = class_to_shost(dev);
3275	MPT_SCSI_HOST	*hd = shost_priv(host);
3276	MPT_ADAPTER *ioc = hd->ioc;
3277
3278	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3279}
3280static DEVICE_ATTR(io_delay, S_IRUGO,
3281    mptscsih_io_delay_show, NULL);
3282
3283static ssize_t
3284mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3285			   char *buf)
3286{
3287	struct Scsi_Host *host = class_to_shost(dev);
3288	MPT_SCSI_HOST	*hd = shost_priv(host);
3289	MPT_ADAPTER *ioc = hd->ioc;
3290
3291	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3292}
3293static DEVICE_ATTR(device_delay, S_IRUGO,
3294    mptscsih_device_delay_show, NULL);
3295
3296static ssize_t
3297mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3298			  char *buf)
3299{
3300	struct Scsi_Host *host = class_to_shost(dev);
3301	MPT_SCSI_HOST	*hd = shost_priv(host);
3302	MPT_ADAPTER *ioc = hd->ioc;
3303
3304	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3305}
3306static ssize_t
3307mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3308			   const char *buf, size_t count)
3309{
3310	struct Scsi_Host *host = class_to_shost(dev);
3311	MPT_SCSI_HOST	*hd = shost_priv(host);
3312	MPT_ADAPTER *ioc = hd->ioc;
3313	int val = 0;
3314
3315	if (sscanf(buf, "%x", &val) != 1)
3316		return -EINVAL;
3317
3318	ioc->debug_level = val;
3319	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3320				ioc->name, ioc->debug_level);
3321	return strlen(buf);
3322}
3323static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3324	mptscsih_debug_level_show, mptscsih_debug_level_store);
3325
3326struct device_attribute *mptscsih_host_attrs[] = {
3327	&dev_attr_version_fw,
3328	&dev_attr_version_bios,
3329	&dev_attr_version_mpi,
3330	&dev_attr_version_product,
3331	&dev_attr_version_nvdata_persistent,
3332	&dev_attr_version_nvdata_default,
3333	&dev_attr_board_name,
3334	&dev_attr_board_assembly,
3335	&dev_attr_board_tracer,
3336	&dev_attr_io_delay,
3337	&dev_attr_device_delay,
3338	&dev_attr_debug_level,
3339	NULL,
3340};
3341
3342EXPORT_SYMBOL(mptscsih_host_attrs);
3343
3344EXPORT_SYMBOL(mptscsih_remove);
3345EXPORT_SYMBOL(mptscsih_shutdown);
3346#ifdef CONFIG_PM
3347EXPORT_SYMBOL(mptscsih_suspend);
3348EXPORT_SYMBOL(mptscsih_resume);
3349#endif
3350EXPORT_SYMBOL(mptscsih_proc_info);
3351EXPORT_SYMBOL(mptscsih_info);
3352EXPORT_SYMBOL(mptscsih_qcmd);
3353EXPORT_SYMBOL(mptscsih_slave_destroy);
3354EXPORT_SYMBOL(mptscsih_slave_configure);
3355EXPORT_SYMBOL(mptscsih_abort);
3356EXPORT_SYMBOL(mptscsih_dev_reset);
3357EXPORT_SYMBOL(mptscsih_bus_reset);
3358EXPORT_SYMBOL(mptscsih_host_reset);
3359EXPORT_SYMBOL(mptscsih_bios_param);
3360EXPORT_SYMBOL(mptscsih_io_done);
3361EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3362EXPORT_SYMBOL(mptscsih_scandv_complete);
3363EXPORT_SYMBOL(mptscsih_event_process);
3364EXPORT_SYMBOL(mptscsih_ioc_reset);
3365EXPORT_SYMBOL(mptscsih_change_queue_depth);
3366
3367/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/