Linux Audio

Check our new training course

Loading...
v6.2
   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>
  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	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		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			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 (host == NULL)
1180		hd = NULL;
1181	else
1182		hd = shost_priv(host);
1183
1184	mptscsih_shutdown(pdev);
1185
1186	sz1=0;
1187
1188	if (ioc->ScsiLookup != NULL) {
1189		sz1 = ioc->req_depth * sizeof(void *);
1190		kfree(ioc->ScsiLookup);
1191		ioc->ScsiLookup = NULL;
1192	}
1193
1194	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1195	    "Free'd ScsiLookup (%d) memory\n",
1196	    ioc->name, sz1));
1197
1198	if (hd)
1199		kfree(hd->info_kbuf);
1200
1201	/* NULL the Scsi_Host pointer
1202	 */
1203	ioc->sh = NULL;
1204
1205	if (host)
1206		scsi_host_put(host);
1207	mpt_detach(pdev);
1208
1209}
1210
1211/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1212/*
1213 *	mptscsih_shutdown - reboot notifier
1214 *
1215 */
1216void
1217mptscsih_shutdown(struct pci_dev *pdev)
1218{
1219}
1220
1221#ifdef CONFIG_PM
1222/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1223/*
1224 *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1225 *
1226 *
1227 */
1228int
1229mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1230{
1231	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1232
1233	scsi_block_requests(ioc->sh);
1234	flush_scheduled_work();
1235	mptscsih_shutdown(pdev);
1236	return mpt_suspend(pdev,state);
1237}
1238
1239/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1240/*
1241 *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1242 *
1243 *
1244 */
1245int
1246mptscsih_resume(struct pci_dev *pdev)
1247{
1248	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1249	int rc;
1250
1251	rc = mpt_resume(pdev);
1252	scsi_unblock_requests(ioc->sh);
1253	return rc;
1254}
1255
1256#endif
1257
1258/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1259/**
1260 *	mptscsih_info - Return information about MPT adapter
1261 *	@SChost: Pointer to Scsi_Host structure
1262 *
1263 *	(linux scsi_host_template.info routine)
1264 *
1265 *	Returns pointer to buffer where information was written.
1266 */
1267const char *
1268mptscsih_info(struct Scsi_Host *SChost)
1269{
1270	MPT_SCSI_HOST *h;
1271	int size = 0;
1272
1273	h = shost_priv(SChost);
1274
1275	if (h->info_kbuf == NULL)
1276		if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1277			return h->info_kbuf;
1278	h->info_kbuf[0] = '\0';
1279
1280	mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1281	h->info_kbuf[size-1] = '\0';
1282
1283	return h->info_kbuf;
1284}
1285
1286int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1287{
1288	MPT_SCSI_HOST	*hd = shost_priv(host);
1289	MPT_ADAPTER	*ioc = hd->ioc;
1290
1291	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1292	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1293	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1294	seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1295
1296	return 0;
1297}
1298
1299/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300#define ADD_INDEX_LOG(req_ent)	do { } while(0)
1301
1302/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1303/**
1304 *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1305 *	@SCpnt: Pointer to scsi_cmnd structure
1306 *
1307 *	(linux scsi_host_template.queuecommand routine)
1308 *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1309 *	from a linux scsi_cmnd request and send it to the IOC.
1310 *
1311 *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1312 */
1313int
1314mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1315{
1316	MPT_SCSI_HOST		*hd;
1317	MPT_FRAME_HDR		*mf;
1318	SCSIIORequest_t		*pScsiReq;
1319	VirtDevice		*vdevice = SCpnt->device->hostdata;
1320	u32	 datalen;
1321	u32	 scsictl;
1322	u32	 scsidir;
1323	u32	 cmd_len;
1324	int	 my_idx;
1325	int	 ii;
1326	MPT_ADAPTER *ioc;
1327
1328	hd = shost_priv(SCpnt->device->host);
1329	ioc = hd->ioc;
1330
1331	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1332		ioc->name, SCpnt));
1333
1334	if (ioc->taskmgmt_quiesce_io)
1335		return SCSI_MLQUEUE_HOST_BUSY;
1336
1337	/*
1338	 *  Put together a MPT SCSI request...
1339	 */
1340	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1341		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1342				ioc->name));
1343		return SCSI_MLQUEUE_HOST_BUSY;
1344	}
1345
1346	pScsiReq = (SCSIIORequest_t *) mf;
1347
1348	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1349
1350	ADD_INDEX_LOG(my_idx);
1351
1352	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1353	 *    Seems we may receive a buffer (datalen>0) even when there
1354	 *    will be no data transfer!  GRRRRR...
1355	 */
1356	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1357		datalen = scsi_bufflen(SCpnt);
1358		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1359	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1360		datalen = scsi_bufflen(SCpnt);
1361		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1362	} else {
1363		datalen = 0;
1364		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1365	}
1366
1367	/* Default to untagged. Once a target structure has been allocated,
1368	 * use the Inquiry data to determine if device supports tagged.
1369	 */
1370	if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1371	    SCpnt->device->tagged_supported)
1372		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1373	else
1374		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1375
1376
1377	/* Use the above information to set up the message frame
1378	 */
1379	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1380	pScsiReq->Bus = vdevice->vtarget->channel;
1381	pScsiReq->ChainOffset = 0;
1382	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1383		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1384	else
1385		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1386	pScsiReq->CDBLength = SCpnt->cmd_len;
1387	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1388	pScsiReq->Reserved = 0;
1389	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1390	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1391	pScsiReq->Control = cpu_to_le32(scsictl);
1392
1393	/*
1394	 *  Write SCSI CDB into the message
1395	 */
1396	cmd_len = SCpnt->cmd_len;
1397	for (ii=0; ii < cmd_len; ii++)
1398		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1399
1400	for (ii=cmd_len; ii < 16; ii++)
1401		pScsiReq->CDB[ii] = 0;
1402
1403	/* DataLength */
1404	pScsiReq->DataLength = cpu_to_le32(datalen);
1405
1406	/* SenseBuffer low address */
1407	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1408					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1409
1410	/* Now add the SG list
1411	 * Always have a SGE even if null length.
1412	 */
1413	if (datalen == 0) {
1414		/* Add a NULL SGE */
1415		ioc->add_sge((char *)&pScsiReq->SGL,
1416			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1417			(dma_addr_t) -1);
1418	} else {
1419		/* Add a 32 or 64 bit SGE */
1420		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1421			goto fail;
1422	}
1423
1424	SCpnt->host_scribble = (unsigned char *)mf;
1425	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1426
1427	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1428	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1429			ioc->name, SCpnt, mf, my_idx));
1430	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1431	return 0;
1432
1433 fail:
1434	mptscsih_freeChainBuffers(ioc, my_idx);
1435	mpt_free_msg_frame(ioc, mf);
1436	return SCSI_MLQUEUE_HOST_BUSY;
1437}
1438
1439/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1440/*
1441 *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1442 *	with a SCSI IO request
1443 *	@hd: Pointer to the MPT_SCSI_HOST instance
1444 *	@req_idx: Index of the SCSI IO request frame.
1445 *
1446 *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1447 *	No return.
1448 */
1449static void
1450mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1451{
1452	MPT_FRAME_HDR *chain;
1453	unsigned long flags;
1454	int chain_idx;
1455	int next;
1456
1457	/* Get the first chain index and reset
1458	 * tracker state.
1459	 */
1460	chain_idx = ioc->ReqToChain[req_idx];
1461	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1462
1463	while (chain_idx != MPT_HOST_NO_CHAIN) {
1464
1465		/* Save the next chain buffer index */
1466		next = ioc->ChainToChain[chain_idx];
1467
1468		/* Free this chain buffer and reset
1469		 * tracker
1470		 */
1471		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1472
1473		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1474					+ (chain_idx * ioc->req_sz));
1475
1476		spin_lock_irqsave(&ioc->FreeQlock, flags);
1477		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1478		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1479
1480		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1481				ioc->name, chain_idx));
1482
1483		/* handle next */
1484		chain_idx = next;
1485	}
1486	return;
1487}
1488
1489/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1490/*
1491 *	Reset Handling
1492 */
1493
1494/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1495/**
1496 *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1497 *	@hd: Pointer to MPT_SCSI_HOST structure
1498 *	@type: Task Management type
1499 *	@channel: channel number for task management
1500 *	@id: Logical Target ID for reset (if appropriate)
1501 *	@lun: Logical Unit for reset (if appropriate)
1502 *	@ctx2abort: Context for the task to be aborted (if appropriate)
1503 *	@timeout: timeout for task management control
1504 *
1505 *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1506 *	or a non-interrupt thread.  In the former, must not call schedule().
1507 *
1508 *	Not all fields are meaningfull for all task types.
1509 *
1510 *	Returns 0 for SUCCESS, or FAILED.
1511 *
1512 **/
1513int
1514mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1515	int ctx2abort, ulong timeout)
1516{
1517	MPT_FRAME_HDR	*mf;
1518	SCSITaskMgmt_t	*pScsiTm;
1519	int		 ii;
1520	int		 retval;
1521	MPT_ADAPTER 	*ioc = hd->ioc;
 
1522	u8		 issue_hard_reset;
1523	u32		 ioc_raw_state;
1524	unsigned long	 time_count;
1525
1526	issue_hard_reset = 0;
1527	ioc_raw_state = mpt_GetIocState(ioc, 0);
1528
1529	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1530		printk(MYIOC_s_WARN_FMT
1531			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1532			ioc->name, type, ioc_raw_state);
1533		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1534		    ioc->name, __func__);
1535		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1536			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1537			    "FAILED!!\n", ioc->name);
1538		return 0;
1539	}
1540
1541	/* DOORBELL ACTIVE check is not required if
1542	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1543	*/
1544
1545	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1546		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1547		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1548		printk(MYIOC_s_WARN_FMT
1549			"TaskMgmt type=%x: ioc_state: "
1550			"DOORBELL_ACTIVE (0x%x)!\n",
1551			ioc->name, type, ioc_raw_state);
1552		return FAILED;
1553	}
1554
1555	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1556	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1557		mf = NULL;
1558		retval = FAILED;
1559		goto out;
1560	}
1561
1562	/* Return Fail to calling function if no message frames available.
1563	 */
1564	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1565		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1566			"TaskMgmt no msg frames!!\n", ioc->name));
1567		retval = FAILED;
1568		mpt_clear_taskmgmt_in_progress_flag(ioc);
1569		goto out;
1570	}
1571	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1572			ioc->name, mf));
1573
1574	/* Format the Request
1575	 */
1576	pScsiTm = (SCSITaskMgmt_t *) mf;
1577	pScsiTm->TargetID = id;
1578	pScsiTm->Bus = channel;
1579	pScsiTm->ChainOffset = 0;
1580	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1581
1582	pScsiTm->Reserved = 0;
1583	pScsiTm->TaskType = type;
1584	pScsiTm->Reserved1 = 0;
1585	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1586                    ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1587
1588	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1589
1590	for (ii=0; ii < 7; ii++)
1591		pScsiTm->Reserved2[ii] = 0;
1592
1593	pScsiTm->TaskMsgContext = ctx2abort;
1594
1595	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1596		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1597		type, timeout));
1598
1599	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1600
1601	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1602	time_count = jiffies;
1603	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1604	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1605		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1606	else {
1607		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1608			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1609		if (retval) {
1610			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1611				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1612				ioc->name, mf, retval));
1613			mpt_free_msg_frame(ioc, mf);
1614			mpt_clear_taskmgmt_in_progress_flag(ioc);
1615			goto out;
1616		}
1617	}
1618
1619	wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1620		timeout*HZ);
1621	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1622		retval = FAILED;
1623		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1624		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1625		mpt_clear_taskmgmt_in_progress_flag(ioc);
1626		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1627			goto out;
1628		issue_hard_reset = 1;
1629		goto out;
1630	}
1631
1632	retval = mptscsih_taskmgmt_reply(ioc, type,
1633	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1634
1635	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1636	    "TaskMgmt completed (%d seconds)\n",
1637	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1638
1639 out:
1640
1641	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1642	if (issue_hard_reset) {
1643		printk(MYIOC_s_WARN_FMT
1644		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1645		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1646		retval = (ioc->bus_type == SAS) ?
1647			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1648			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1649		mpt_free_msg_frame(ioc, mf);
1650	}
1651
1652	retval = (retval == 0) ? 0 : FAILED;
1653	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1654	return retval;
1655}
1656EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1657
1658static int
1659mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1660{
1661	switch (ioc->bus_type) {
1662	case FC:
1663		return 40;
1664	case SAS:
1665		return 30;
1666	case SPI:
1667	default:
1668		return 10;
1669	}
1670}
1671
1672/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1673/**
1674 *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1675 *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1676 *
1677 *	(linux scsi_host_template.eh_abort_handler routine)
1678 *
1679 *	Returns SUCCESS or FAILED.
1680 **/
1681int
1682mptscsih_abort(struct scsi_cmnd * SCpnt)
1683{
1684	MPT_SCSI_HOST	*hd;
1685	MPT_FRAME_HDR	*mf;
1686	u32		 ctx2abort;
1687	int		 scpnt_idx;
1688	int		 retval;
1689	VirtDevice	 *vdevice;
1690	MPT_ADAPTER	*ioc;
1691
1692	/* If we can't locate our host adapter structure, return FAILED status.
1693	 */
1694	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1695		SCpnt->result = DID_RESET << 16;
1696		scsi_done(SCpnt);
1697		printk(KERN_ERR MYNAM ": task abort: "
1698		    "can't locate host! (sc=%p)\n", SCpnt);
1699		return FAILED;
1700	}
1701
1702	ioc = hd->ioc;
1703	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1704	       ioc->name, SCpnt);
1705	scsi_print_command(SCpnt);
1706
1707	vdevice = SCpnt->device->hostdata;
1708	if (!vdevice || !vdevice->vtarget) {
1709		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1710		    "task abort: device has been deleted (sc=%p)\n",
1711		    ioc->name, SCpnt));
1712		SCpnt->result = DID_NO_CONNECT << 16;
1713		scsi_done(SCpnt);
1714		retval = SUCCESS;
1715		goto out;
1716	}
1717
1718	/* Task aborts are not supported for hidden raid components.
1719	 */
1720	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1721		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1722		    "task abort: hidden raid component (sc=%p)\n",
1723		    ioc->name, SCpnt));
1724		SCpnt->result = DID_RESET << 16;
1725		retval = FAILED;
1726		goto out;
1727	}
1728
1729	/* Task aborts are not supported for volumes.
1730	 */
1731	if (vdevice->vtarget->raidVolume) {
1732		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1733		    "task abort: raid volume (sc=%p)\n",
1734		    ioc->name, SCpnt));
1735		SCpnt->result = DID_RESET << 16;
1736		retval = FAILED;
1737		goto out;
1738	}
1739
1740	/* Find this command
1741	 */
1742	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1743		/* Cmd not found in ScsiLookup.
1744		 * Do OS callback.
1745		 */
1746		SCpnt->result = DID_RESET << 16;
1747		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1748		   "Command not in the active list! (sc=%p)\n", ioc->name,
1749		   SCpnt));
1750		retval = SUCCESS;
1751		goto out;
1752	}
1753
1754	if (ioc->timeouts < -1)
1755		ioc->timeouts++;
1756
1757	if (mpt_fwfault_debug)
1758		mpt_halt_firmware(ioc);
1759
1760	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1761	 * (the IO to be ABORT'd)
1762	 *
1763	 * NOTE: Since we do not byteswap MsgContext, we do not
1764	 *	 swap it here either.  It is an opaque cookie to
1765	 *	 the controller, so it does not matter. -DaveM
1766	 */
1767	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1768	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1769	retval = mptscsih_IssueTaskMgmt(hd,
1770			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1771			 vdevice->vtarget->channel,
1772			 vdevice->vtarget->id, vdevice->lun,
1773			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1774
1775	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1776		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1777		    "task abort: command still in active list! (sc=%p)\n",
1778		    ioc->name, SCpnt));
1779		retval = FAILED;
1780	} else {
1781		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1782		    "task abort: command cleared from active list! (sc=%p)\n",
1783		    ioc->name, SCpnt));
1784		retval = SUCCESS;
1785	}
1786
1787 out:
1788	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1789	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1790	    SCpnt);
1791
1792	return retval;
1793}
1794
1795/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1796/**
1797 *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1798 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1799 *
1800 *	(linux scsi_host_template.eh_dev_reset_handler routine)
1801 *
1802 *	Returns SUCCESS or FAILED.
1803 **/
1804int
1805mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1806{
1807	MPT_SCSI_HOST	*hd;
1808	int		 retval;
1809	VirtDevice	 *vdevice;
1810	MPT_ADAPTER	*ioc;
1811
1812	/* If we can't locate our host adapter structure, return FAILED status.
1813	 */
1814	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1815		printk(KERN_ERR MYNAM ": target reset: "
1816		   "Can't locate host! (sc=%p)\n", SCpnt);
1817		return FAILED;
1818	}
1819
1820	ioc = hd->ioc;
1821	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1822	       ioc->name, SCpnt);
1823	scsi_print_command(SCpnt);
1824
1825	vdevice = SCpnt->device->hostdata;
1826	if (!vdevice || !vdevice->vtarget) {
1827		retval = 0;
1828		goto out;
1829	}
1830
1831	/* Target reset to hidden raid component is not supported
1832	 */
1833	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1834		retval = FAILED;
1835		goto out;
1836	}
1837
1838	retval = mptscsih_IssueTaskMgmt(hd,
1839				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1840				vdevice->vtarget->channel,
1841				vdevice->vtarget->id, 0, 0,
1842				mptscsih_get_tm_timeout(ioc));
1843
1844 out:
1845	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1846	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1847
1848	if (retval == 0)
1849		return SUCCESS;
1850	else
1851		return FAILED;
1852}
1853
1854
1855/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1856/**
1857 *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1858 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1859 *
1860 *	(linux scsi_host_template.eh_bus_reset_handler routine)
1861 *
1862 *	Returns SUCCESS or FAILED.
1863 **/
1864int
1865mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1866{
1867	MPT_SCSI_HOST	*hd;
1868	int		 retval;
1869	VirtDevice	 *vdevice;
1870	MPT_ADAPTER	*ioc;
1871
1872	/* If we can't locate our host adapter structure, return FAILED status.
1873	 */
1874	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1875		printk(KERN_ERR MYNAM ": bus reset: "
1876		   "Can't locate host! (sc=%p)\n", SCpnt);
1877		return FAILED;
1878	}
1879
1880	ioc = hd->ioc;
1881	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1882	       ioc->name, SCpnt);
1883	scsi_print_command(SCpnt);
1884
1885	if (ioc->timeouts < -1)
1886		ioc->timeouts++;
1887
1888	vdevice = SCpnt->device->hostdata;
1889	if (!vdevice || !vdevice->vtarget)
1890		return SUCCESS;
1891	retval = mptscsih_IssueTaskMgmt(hd,
1892					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1893					vdevice->vtarget->channel, 0, 0, 0,
1894					mptscsih_get_tm_timeout(ioc));
1895
1896	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1897	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1898
1899	if (retval == 0)
1900		return SUCCESS;
1901	else
1902		return FAILED;
1903}
1904
1905/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1906/**
1907 *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1908 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1909 *
1910 *	(linux scsi_host_template.eh_host_reset_handler routine)
1911 *
1912 *	Returns SUCCESS or FAILED.
1913 */
1914int
1915mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1916{
1917	MPT_SCSI_HOST *  hd;
1918	int              status = SUCCESS;
1919	MPT_ADAPTER	*ioc;
1920	int		retval;
1921
1922	/*  If we can't locate the host to reset, then we failed. */
1923	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1924		printk(KERN_ERR MYNAM ": host reset: "
1925		    "Can't locate host! (sc=%p)\n", SCpnt);
1926		return FAILED;
1927	}
1928
1929	/* make sure we have no outstanding commands at this stage */
1930	mptscsih_flush_running_cmds(hd);
1931
1932	ioc = hd->ioc;
1933	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1934	    ioc->name, SCpnt);
1935
1936	/*  If our attempts to reset the host failed, then return a failed
1937	 *  status.  The host will be taken off line by the SCSI mid-layer.
1938	 */
1939	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1940	if (retval < 0)
1941		status = FAILED;
1942	else
1943		status = SUCCESS;
1944
1945	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1946	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1947
1948	return status;
1949}
1950
1951static int
1952mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1953	SCSITaskMgmtReply_t *pScsiTmReply)
1954{
1955	u16			 iocstatus;
1956	u32			 termination_count;
1957	int			 retval;
1958
1959	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1960		retval = FAILED;
1961		goto out;
1962	}
1963
1964	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1965
1966	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1967	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1968
1969	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1970	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1971	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1972	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1973	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1974	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1975	    termination_count));
1976
1977	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1978	    pScsiTmReply->ResponseCode)
1979		mptscsih_taskmgmt_response_code(ioc,
1980		    pScsiTmReply->ResponseCode);
1981
1982	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1983		retval = 0;
1984		goto out;
1985	}
1986
1987	retval = FAILED;
1988	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1989		if (termination_count == 1)
1990			retval = 0;
1991		goto out;
1992	}
1993
1994	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1995	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1996		retval = 0;
1997
1998 out:
1999	return retval;
2000}
2001
2002/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2003void
2004mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2005{
2006	char *desc;
2007
2008	switch (response_code) {
2009	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2010		desc = "The task completed.";
2011		break;
2012	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2013		desc = "The IOC received an invalid frame status.";
2014		break;
2015	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2016		desc = "The task type is not supported.";
2017		break;
2018	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2019		desc = "The requested task failed.";
2020		break;
2021	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2022		desc = "The task completed successfully.";
2023		break;
2024	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2025		desc = "The LUN request is invalid.";
2026		break;
2027	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2028		desc = "The task is in the IOC queue and has not been sent to target.";
2029		break;
2030	default:
2031		desc = "unknown";
2032		break;
2033	}
2034	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2035		ioc->name, response_code, desc);
2036}
2037EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2038
2039/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2040/**
2041 *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2042 *	@ioc: Pointer to MPT_ADAPTER structure
2043 *	@mf: Pointer to SCSI task mgmt request frame
2044 *	@mr: Pointer to SCSI task mgmt reply frame
2045 *
2046 *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2047 *	of any SCSI task management request.
2048 *	This routine is registered with the MPT (base) driver at driver
2049 *	load/init time via the mpt_register() API call.
2050 *
2051 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2052 **/
2053int
2054mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2055	MPT_FRAME_HDR *mr)
2056{
2057	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2058		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2059
2060	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2061
2062	if (!mr)
2063		goto out;
2064
2065	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2066	memcpy(ioc->taskmgmt_cmds.reply, mr,
2067	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2068 out:
2069	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2070		mpt_clear_taskmgmt_in_progress_flag(ioc);
2071		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2072		complete(&ioc->taskmgmt_cmds.done);
2073		if (ioc->bus_type == SAS)
2074			ioc->schedule_target_reset(ioc);
2075		return 1;
2076	}
2077	return 0;
2078}
2079
2080/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2081/*
2082 *	This is anyones guess quite frankly.
2083 */
2084int
2085mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2086		sector_t capacity, int geom[])
2087{
2088	int		heads;
2089	int		sectors;
2090	sector_t	cylinders;
2091	ulong 		dummy;
2092
2093	heads = 64;
2094	sectors = 32;
2095
2096	dummy = heads * sectors;
2097	cylinders = capacity;
2098	sector_div(cylinders,dummy);
2099
2100	/*
2101	 * Handle extended translation size for logical drives
2102	 * > 1Gb
2103	 */
2104	if ((ulong)capacity >= 0x200000) {
2105		heads = 255;
2106		sectors = 63;
2107		dummy = heads * sectors;
2108		cylinders = capacity;
2109		sector_div(cylinders,dummy);
2110	}
2111
2112	/* return result */
2113	geom[0] = heads;
2114	geom[1] = sectors;
2115	geom[2] = cylinders;
2116
2117	return 0;
2118}
2119
2120/* Search IOC page 3 to determine if this is hidden physical disk
2121 *
2122 */
2123int
2124mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2125{
2126	struct inactive_raid_component_info *component_info;
2127	int i, j;
2128	RaidPhysDiskPage1_t *phys_disk;
2129	int rc = 0;
2130	int num_paths;
2131
2132	if (!ioc->raid_data.pIocPg3)
2133		goto out;
2134	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2135		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2136		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2137			rc = 1;
2138			goto out;
2139		}
2140	}
2141
2142	if (ioc->bus_type != SAS)
2143		goto out;
2144
2145	/*
2146	 * Check if dual path
2147	 */
2148	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2149		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2150		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2151		if (num_paths < 2)
2152			continue;
2153		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2154		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2155		if (!phys_disk)
2156			continue;
2157		if ((mpt_raid_phys_disk_pg1(ioc,
2158		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2159		    phys_disk))) {
2160			kfree(phys_disk);
2161			continue;
2162		}
2163		for (j = 0; j < num_paths; j++) {
2164			if ((phys_disk->Path[j].Flags &
2165			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2166				continue;
2167			if ((phys_disk->Path[j].Flags &
2168			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2169				continue;
2170			if ((id == phys_disk->Path[j].PhysDiskID) &&
2171			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2172				rc = 1;
2173				kfree(phys_disk);
2174				goto out;
2175			}
2176		}
2177		kfree(phys_disk);
2178	}
2179
2180
2181	/*
2182	 * Check inactive list for matching phys disks
2183	 */
2184	if (list_empty(&ioc->raid_data.inactive_list))
2185		goto out;
2186
2187	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2188	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2189	    list) {
2190		if ((component_info->d.PhysDiskID == id) &&
2191		    (component_info->d.PhysDiskBus == channel))
2192			rc = 1;
2193	}
2194	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2195
2196 out:
2197	return rc;
2198}
2199EXPORT_SYMBOL(mptscsih_is_phys_disk);
2200
2201u8
2202mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2203{
2204	struct inactive_raid_component_info *component_info;
2205	int i, j;
2206	RaidPhysDiskPage1_t *phys_disk;
2207	int rc = -ENXIO;
2208	int num_paths;
2209
2210	if (!ioc->raid_data.pIocPg3)
2211		goto out;
2212	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2213		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2214		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2215			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2216			goto out;
2217		}
2218	}
2219
2220	if (ioc->bus_type != SAS)
2221		goto out;
2222
2223	/*
2224	 * Check if dual path
2225	 */
2226	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2227		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2228		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2229		if (num_paths < 2)
2230			continue;
2231		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2232		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2233		if (!phys_disk)
2234			continue;
2235		if ((mpt_raid_phys_disk_pg1(ioc,
2236		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2237		    phys_disk))) {
2238			kfree(phys_disk);
2239			continue;
2240		}
2241		for (j = 0; j < num_paths; j++) {
2242			if ((phys_disk->Path[j].Flags &
2243			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2244				continue;
2245			if ((phys_disk->Path[j].Flags &
2246			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2247				continue;
2248			if ((id == phys_disk->Path[j].PhysDiskID) &&
2249			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2250				rc = phys_disk->PhysDiskNum;
2251				kfree(phys_disk);
2252				goto out;
2253			}
2254		}
2255		kfree(phys_disk);
2256	}
2257
2258	/*
2259	 * Check inactive list for matching phys disks
2260	 */
2261	if (list_empty(&ioc->raid_data.inactive_list))
2262		goto out;
2263
2264	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2265	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2266	    list) {
2267		if ((component_info->d.PhysDiskID == id) &&
2268		    (component_info->d.PhysDiskBus == channel))
2269			rc = component_info->d.PhysDiskNum;
2270	}
2271	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2272
2273 out:
2274	return rc;
2275}
2276EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2277
2278/*
2279 *	OS entry point to allow for host driver to free allocated memory
2280 *	Called if no device present or device being unloaded
2281 */
2282void
2283mptscsih_slave_destroy(struct scsi_device *sdev)
2284{
2285	struct Scsi_Host	*host = sdev->host;
2286	MPT_SCSI_HOST		*hd = shost_priv(host);
2287	VirtTarget		*vtarget;
2288	VirtDevice		*vdevice;
2289	struct scsi_target 	*starget;
2290
2291	starget = scsi_target(sdev);
2292	vtarget = starget->hostdata;
2293	vdevice = sdev->hostdata;
2294	if (!vdevice)
2295		return;
2296
2297	mptscsih_search_running_cmds(hd, vdevice);
2298	vtarget->num_luns--;
2299	mptscsih_synchronize_cache(hd, vdevice);
2300	kfree(vdevice);
2301	sdev->hostdata = NULL;
2302}
2303
2304/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2305/*
2306 *	mptscsih_change_queue_depth - This function will set a devices queue depth
2307 *	@sdev: per scsi_device pointer
2308 *	@qdepth: requested queue depth
2309 *
2310 *	Adding support for new 'change_queue_depth' api.
2311*/
2312int
2313mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2314{
2315	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2316	VirtTarget 		*vtarget;
2317	struct scsi_target 	*starget;
2318	int			max_depth;
2319	MPT_ADAPTER		*ioc = hd->ioc;
2320
2321	starget = scsi_target(sdev);
2322	vtarget = starget->hostdata;
2323
2324	if (ioc->bus_type == SPI) {
2325		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2326			max_depth = 1;
2327		else if (sdev->type == TYPE_DISK &&
2328			 vtarget->minSyncFactor <= MPT_ULTRA160)
2329			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2330		else
2331			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2332	} else
2333		 max_depth = ioc->sh->can_queue;
2334
2335	if (!sdev->tagged_supported)
2336		max_depth = 1;
2337
2338	if (qdepth > max_depth)
2339		qdepth = max_depth;
2340
2341	return scsi_change_queue_depth(sdev, qdepth);
2342}
2343
2344/*
2345 *	OS entry point to adjust the queue_depths on a per-device basis.
2346 *	Called once per device the bus scan. Use it to force the queue_depth
2347 *	member to 1 if a device does not support Q tags.
2348 *	Return non-zero if fails.
2349 */
2350int
2351mptscsih_slave_configure(struct scsi_device *sdev)
2352{
2353	struct Scsi_Host	*sh = sdev->host;
2354	VirtTarget		*vtarget;
2355	VirtDevice		*vdevice;
2356	struct scsi_target 	*starget;
2357	MPT_SCSI_HOST		*hd = shost_priv(sh);
2358	MPT_ADAPTER		*ioc = hd->ioc;
2359
2360	starget = scsi_target(sdev);
2361	vtarget = starget->hostdata;
2362	vdevice = sdev->hostdata;
2363
2364	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2365		"device @ %p, channel=%d, id=%d, lun=%llu\n",
2366		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2367	if (ioc->bus_type == SPI)
2368		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2369		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2370		    ioc->name, sdev->sdtr, sdev->wdtr,
2371		    sdev->ppr, sdev->inquiry_len));
2372
2373	vdevice->configured_lun = 1;
2374
2375	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2376		"Queue depth=%d, tflags=%x\n",
2377		ioc->name, sdev->queue_depth, vtarget->tflags));
2378
2379	if (ioc->bus_type == SPI)
2380		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2381		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2382		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2383		    vtarget->minSyncFactor));
2384
2385	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2386	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2387		"tagged %d, simple %d\n",
2388		ioc->name,sdev->tagged_supported, sdev->simple_tags));
2389
2390	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2391
2392	return 0;
2393}
2394
2395/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2396/*
2397 *  Private routines...
2398 */
2399
2400/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2401/* Utility function to copy sense data from the scsi_cmnd buffer
2402 * to the FC and SCSI target structures.
2403 *
2404 */
2405static void
2406mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2407{
2408	VirtDevice	*vdevice;
2409	SCSIIORequest_t	*pReq;
2410	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2411	MPT_ADAPTER 	*ioc = hd->ioc;
2412
2413	/* Get target structure
2414	 */
2415	pReq = (SCSIIORequest_t *) mf;
2416	vdevice = sc->device->hostdata;
2417
2418	if (sense_count) {
2419		u8 *sense_data;
2420		int req_index;
2421
2422		/* Copy the sense received into the scsi command block. */
2423		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2424		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2425		memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
2426
2427		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2428		 */
2429		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2430			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2431				int idx;
2432
2433				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2434				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2435				ioc->events[idx].eventContext = ioc->eventContext;
2436
2437				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2438					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2439					(sc->device->channel << 8) | sc->device->id;
2440
2441				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2442
2443				ioc->eventContext++;
2444				if (ioc->pcidev->vendor ==
2445				    PCI_VENDOR_ID_IBM) {
2446					mptscsih_issue_sep_command(ioc,
2447					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2448					vdevice->vtarget->tflags |=
2449					    MPT_TARGET_FLAGS_LED_ON;
2450				}
2451			}
2452		}
2453	} else {
2454		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2455				ioc->name));
2456	}
2457}
2458
2459/**
2460 * mptscsih_get_scsi_lookup - retrieves scmd entry
2461 * @ioc: Pointer to MPT_ADAPTER structure
2462 * @i: index into the array
2463 *
2464 * Returns the scsi_cmd pointer
2465 */
2466struct scsi_cmnd *
2467mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2468{
2469	unsigned long	flags;
2470	struct scsi_cmnd *scmd;
2471
2472	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2473	scmd = ioc->ScsiLookup[i];
2474	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2475
2476	return scmd;
2477}
2478EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2479
2480/**
2481 * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2482 * @ioc: Pointer to MPT_ADAPTER structure
2483 * @i: index into the array
2484 *
2485 * Returns the scsi_cmd pointer
2486 *
2487 **/
2488static struct scsi_cmnd *
2489mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2490{
2491	unsigned long	flags;
2492	struct scsi_cmnd *scmd;
2493
2494	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2495	scmd = ioc->ScsiLookup[i];
2496	ioc->ScsiLookup[i] = NULL;
2497	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2498
2499	return scmd;
2500}
2501
2502/**
2503 * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2504 *
2505 * @ioc: Pointer to MPT_ADAPTER structure
2506 * @i: index into the array
2507 * @scmd: scsi_cmnd pointer
2508 *
2509 **/
2510static void
2511mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2512{
2513	unsigned long	flags;
2514
2515	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2516	ioc->ScsiLookup[i] = scmd;
2517	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2518}
2519
2520/**
2521 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2522 * @ioc: Pointer to MPT_ADAPTER structure
2523 * @sc: scsi_cmnd pointer
2524 */
2525static int
2526SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2527{
2528	unsigned long	flags;
2529	int i, index=-1;
2530
2531	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2532	for (i = 0; i < ioc->req_depth; i++) {
2533		if (ioc->ScsiLookup[i] == sc) {
2534			index = i;
2535			goto out;
2536		}
2537	}
2538
2539 out:
2540	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2541	return index;
2542}
2543
2544/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2545int
2546mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2547{
2548	MPT_SCSI_HOST	*hd;
2549
2550	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2551		return 0;
2552
2553	hd = shost_priv(ioc->sh);
2554	switch (reset_phase) {
2555	case MPT_IOC_SETUP_RESET:
2556		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2557		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2558		break;
2559	case MPT_IOC_PRE_RESET:
2560		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2561		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2562		mptscsih_flush_running_cmds(hd);
2563		break;
2564	case MPT_IOC_POST_RESET:
2565		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2566		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2567		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2568			ioc->internal_cmds.status |=
2569				MPT_MGMT_STATUS_DID_IOCRESET;
2570			complete(&ioc->internal_cmds.done);
2571		}
2572		break;
2573	default:
2574		break;
2575	}
2576	return 1;		/* currently means nothing really */
2577}
2578
2579/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2580int
2581mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2582{
2583	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2584
2585	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2586		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2587		ioc->name, event));
2588
2589	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2590	    event == MPI_EVENT_EXT_BUS_RESET) &&
2591	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2592			ioc->soft_resets++;
2593
2594	return 1;		/* currently means nothing really */
2595}
2596
2597/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2598/*
2599 *  Bus Scan and Domain Validation functionality ...
2600 */
2601
2602/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603/*
2604 *	mptscsih_scandv_complete - Scan and DV callback routine registered
2605 *	to Fustion MPT (base) driver.
2606 *
2607 *	@ioc: Pointer to MPT_ADAPTER structure
2608 *	@mf: Pointer to original MPT request frame
2609 *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2610 *
2611 *	This routine is called from mpt.c::mpt_interrupt() at the completion
2612 *	of any SCSI IO request.
2613 *	This routine is registered with the Fusion MPT (base) driver at driver
2614 *	load/init time via the mpt_register() API call.
2615 *
2616 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2617 *
2618 *	Remark: Sets a completion code and (possibly) saves sense data
2619 *	in the IOC member localReply structure.
2620 *	Used ONLY for DV and other internal commands.
2621 */
2622int
2623mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2624				MPT_FRAME_HDR *reply)
2625{
2626	SCSIIORequest_t *pReq;
2627	SCSIIOReply_t	*pReply;
2628	u8		 cmd;
2629	u16		 req_idx;
2630	u8	*sense_data;
2631	int		 sz;
2632
2633	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2634	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2635	if (!reply)
2636		goto out;
2637
2638	pReply = (SCSIIOReply_t *) reply;
2639	pReq = (SCSIIORequest_t *) req;
2640	ioc->internal_cmds.completion_code =
2641	    mptscsih_get_completion_code(ioc, req, reply);
2642	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2643	memcpy(ioc->internal_cmds.reply, reply,
2644	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2645	cmd = reply->u.hdr.Function;
2646	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2647	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2648	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2649		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2650		sense_data = ((u8 *)ioc->sense_buf_pool +
2651		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2652		sz = min_t(int, pReq->SenseBufferLength,
2653		    MPT_SENSE_BUFFER_ALLOC);
2654		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2655	}
2656 out:
2657	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2658		return 0;
2659	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2660	complete(&ioc->internal_cmds.done);
2661	return 1;
2662}
2663
2664
2665/**
2666 *	mptscsih_get_completion_code - get completion code from MPT request
2667 *	@ioc: Pointer to MPT_ADAPTER structure
2668 *	@req: Pointer to original MPT request frame
2669 *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2670 *
2671 **/
2672static int
2673mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2674				MPT_FRAME_HDR *reply)
2675{
2676	SCSIIOReply_t	*pReply;
2677	MpiRaidActionReply_t *pr;
2678	u8		 scsi_status;
2679	u16		 status;
2680	int		 completion_code;
2681
2682	pReply = (SCSIIOReply_t *)reply;
2683	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2684	scsi_status = pReply->SCSIStatus;
2685
2686	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2687	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2688	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2689	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2690
2691	switch (status) {
2692
2693	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2694		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2695		break;
2696
2697	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2698	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2699	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2700	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2701		completion_code = MPT_SCANDV_DID_RESET;
2702		break;
2703
2704	case MPI_IOCSTATUS_BUSY:
2705	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2706		completion_code = MPT_SCANDV_BUSY;
2707		break;
2708
2709	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2710	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2711	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2712		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2713			completion_code = MPT_SCANDV_GOOD;
2714		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2715			pr = (MpiRaidActionReply_t *)reply;
2716			if (le16_to_cpu(pr->ActionStatus) ==
2717				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2718				completion_code = MPT_SCANDV_GOOD;
2719			else
2720				completion_code = MPT_SCANDV_SOME_ERROR;
2721		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2722			completion_code = MPT_SCANDV_SENSE;
2723		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2724			if (req->u.scsireq.CDB[0] == INQUIRY)
2725				completion_code = MPT_SCANDV_ISSUE_SENSE;
2726			else
2727				completion_code = MPT_SCANDV_DID_RESET;
2728		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2729			completion_code = MPT_SCANDV_DID_RESET;
2730		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2731			completion_code = MPT_SCANDV_DID_RESET;
2732		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2733			completion_code = MPT_SCANDV_BUSY;
2734		else
2735			completion_code = MPT_SCANDV_GOOD;
2736		break;
2737
2738	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2739		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2740			completion_code = MPT_SCANDV_DID_RESET;
2741		else
2742			completion_code = MPT_SCANDV_SOME_ERROR;
2743		break;
2744	default:
2745		completion_code = MPT_SCANDV_SOME_ERROR;
2746		break;
2747
2748	}	/* switch(status) */
2749
2750	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2751	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2752	return completion_code;
2753}
2754
2755/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2756/**
2757 *	mptscsih_do_cmd - Do internal command.
2758 *	@hd: MPT_SCSI_HOST pointer
2759 *	@io: INTERNAL_CMD pointer.
2760 *
2761 *	Issue the specified internally generated command and do command
2762 *	specific cleanup. For bus scan / DV only.
2763 *	NOTES: If command is Inquiry and status is good,
2764 *	initialize a target structure, save the data
2765 *
2766 *	Remark: Single threaded access only.
2767 *
2768 *	Return:
2769 *		< 0 if an illegal command or no resources
2770 *
2771 *		   0 if good
2772 *
2773 *		 > 0 if command complete but some type of completion error.
2774 */
2775static int
2776mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2777{
2778	MPT_FRAME_HDR	*mf;
2779	SCSIIORequest_t	*pScsiReq;
2780	int		 my_idx, ii, dir;
2781	int		 timeout;
2782	char		 cmdLen;
2783	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2784	u8		 cmd = io->cmd;
2785	MPT_ADAPTER *ioc = hd->ioc;
2786	int		 ret = 0;
2787	unsigned long	 timeleft;
2788	unsigned long	 flags;
2789
2790	/* don't send internal command during diag reset */
2791	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2792	if (ioc->ioc_reset_in_progress) {
2793		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2794		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2795			"%s: busy with host reset\n", ioc->name, __func__));
2796		return MPT_SCANDV_BUSY;
2797	}
2798	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2799
2800	mutex_lock(&ioc->internal_cmds.mutex);
2801
2802	/* Set command specific information
2803	 */
2804	switch (cmd) {
2805	case INQUIRY:
2806		cmdLen = 6;
2807		dir = MPI_SCSIIO_CONTROL_READ;
2808		CDB[0] = cmd;
2809		CDB[4] = io->size;
2810		timeout = 10;
2811		break;
2812
2813	case TEST_UNIT_READY:
2814		cmdLen = 6;
2815		dir = MPI_SCSIIO_CONTROL_READ;
2816		timeout = 10;
2817		break;
2818
2819	case START_STOP:
2820		cmdLen = 6;
2821		dir = MPI_SCSIIO_CONTROL_READ;
2822		CDB[0] = cmd;
2823		CDB[4] = 1;	/*Spin up the disk */
2824		timeout = 15;
2825		break;
2826
2827	case REQUEST_SENSE:
2828		cmdLen = 6;
2829		CDB[0] = cmd;
2830		CDB[4] = io->size;
2831		dir = MPI_SCSIIO_CONTROL_READ;
2832		timeout = 10;
2833		break;
2834
2835	case READ_BUFFER:
2836		cmdLen = 10;
2837		dir = MPI_SCSIIO_CONTROL_READ;
2838		CDB[0] = cmd;
2839		if (io->flags & MPT_ICFLAG_ECHO) {
2840			CDB[1] = 0x0A;
2841		} else {
2842			CDB[1] = 0x02;
2843		}
2844
2845		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2846			CDB[1] |= 0x01;
2847		}
2848		CDB[6] = (io->size >> 16) & 0xFF;
2849		CDB[7] = (io->size >>  8) & 0xFF;
2850		CDB[8] = io->size & 0xFF;
2851		timeout = 10;
2852		break;
2853
2854	case WRITE_BUFFER:
2855		cmdLen = 10;
2856		dir = MPI_SCSIIO_CONTROL_WRITE;
2857		CDB[0] = cmd;
2858		if (io->flags & MPT_ICFLAG_ECHO) {
2859			CDB[1] = 0x0A;
2860		} else {
2861			CDB[1] = 0x02;
2862		}
2863		CDB[6] = (io->size >> 16) & 0xFF;
2864		CDB[7] = (io->size >>  8) & 0xFF;
2865		CDB[8] = io->size & 0xFF;
2866		timeout = 10;
2867		break;
2868
2869	case RESERVE:
2870		cmdLen = 6;
2871		dir = MPI_SCSIIO_CONTROL_READ;
2872		CDB[0] = cmd;
2873		timeout = 10;
2874		break;
2875
2876	case RELEASE:
2877		cmdLen = 6;
2878		dir = MPI_SCSIIO_CONTROL_READ;
2879		CDB[0] = cmd;
2880		timeout = 10;
2881		break;
2882
2883	case SYNCHRONIZE_CACHE:
2884		cmdLen = 10;
2885		dir = MPI_SCSIIO_CONTROL_READ;
2886		CDB[0] = cmd;
2887//		CDB[1] = 0x02;	/* set immediate bit */
2888		timeout = 10;
2889		break;
2890
2891	default:
2892		/* Error Case */
2893		ret = -EFAULT;
2894		goto out;
2895	}
2896
2897	/* Get and Populate a free Frame
2898	 * MsgContext set in mpt_get_msg_frame call
2899	 */
2900	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2901		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2902		    ioc->name, __func__));
2903		ret = MPT_SCANDV_BUSY;
2904		goto out;
2905	}
2906
2907	pScsiReq = (SCSIIORequest_t *) mf;
2908
2909	/* Get the request index */
2910	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911	ADD_INDEX_LOG(my_idx); /* for debug */
2912
2913	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2914		pScsiReq->TargetID = io->physDiskNum;
2915		pScsiReq->Bus = 0;
2916		pScsiReq->ChainOffset = 0;
2917		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2918	} else {
2919		pScsiReq->TargetID = io->id;
2920		pScsiReq->Bus = io->channel;
2921		pScsiReq->ChainOffset = 0;
2922		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2923	}
2924
2925	pScsiReq->CDBLength = cmdLen;
2926	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2927
2928	pScsiReq->Reserved = 0;
2929
2930	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2931	/* MsgContext set in mpt_get_msg_fram call  */
2932
2933	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2934
2935	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2936		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2937	else
2938		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2939
2940	if (cmd == REQUEST_SENSE) {
2941		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2942		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2943		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2944	}
2945
2946	for (ii = 0; ii < 16; ii++)
2947		pScsiReq->CDB[ii] = CDB[ii];
2948
2949	pScsiReq->DataLength = cpu_to_le32(io->size);
2950	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2951					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2952
2953	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2954	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2955	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2956
2957	if (dir == MPI_SCSIIO_CONTROL_READ)
2958		ioc->add_sge((char *) &pScsiReq->SGL,
2959		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2960	else
2961		ioc->add_sge((char *) &pScsiReq->SGL,
2962		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2963
2964	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2965	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2966	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2967	    timeout*HZ);
2968	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2969		ret = MPT_SCANDV_DID_RESET;
2970		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2971		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2972		    cmd));
2973		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2974			mpt_free_msg_frame(ioc, mf);
2975			goto out;
2976		}
2977		if (!timeleft) {
2978			printk(MYIOC_s_WARN_FMT
2979			       "Issuing Reset from %s!! doorbell=0x%08xh"
2980			       " cmd=0x%02x\n",
2981			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
2982			       cmd);
2983			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2984			mpt_free_msg_frame(ioc, mf);
2985		}
2986		goto out;
2987	}
2988
2989	ret = ioc->internal_cmds.completion_code;
2990	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2991			ioc->name, __func__, ret));
2992
2993 out:
2994	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2995	mutex_unlock(&ioc->internal_cmds.mutex);
2996	return ret;
2997}
2998
2999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3000/**
3001 *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3002 *	@hd: Pointer to a SCSI HOST structure
3003 *	@vdevice: virtual target device
3004 *
3005 *	Uses the ISR, but with special processing.
3006 *	MUST be single-threaded.
3007 *
3008 */
3009static void
3010mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3011{
3012	INTERNAL_CMD		 iocmd;
3013
3014	/* Ignore hidden raid components, this is handled when the command
3015	 * is sent to the volume
3016	 */
3017	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3018		return;
3019
3020	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3021	    !vdevice->configured_lun)
3022		return;
3023
3024	/* Following parameters will not change
3025	 * in this routine.
3026	 */
3027	iocmd.cmd = SYNCHRONIZE_CACHE;
3028	iocmd.flags = 0;
3029	iocmd.physDiskNum = -1;
3030	iocmd.data = NULL;
3031	iocmd.data_dma = -1;
3032	iocmd.size = 0;
3033	iocmd.rsvd = iocmd.rsvd2 = 0;
3034	iocmd.channel = vdevice->vtarget->channel;
3035	iocmd.id = vdevice->vtarget->id;
3036	iocmd.lun = vdevice->lun;
3037
3038	mptscsih_do_cmd(hd, &iocmd);
3039}
3040
3041static ssize_t
3042mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3043			 char *buf)
3044{
3045	struct Scsi_Host *host = class_to_shost(dev);
3046	MPT_SCSI_HOST	*hd = shost_priv(host);
3047	MPT_ADAPTER *ioc = hd->ioc;
3048
3049	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3050	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3051	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3052	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3053	    ioc->facts.FWVersion.Word & 0x000000FF);
3054}
3055static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3056
3057static ssize_t
3058mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3059			   char *buf)
3060{
3061	struct Scsi_Host *host = class_to_shost(dev);
3062	MPT_SCSI_HOST	*hd = shost_priv(host);
3063	MPT_ADAPTER *ioc = hd->ioc;
3064
3065	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3066	    (ioc->biosVersion & 0xFF000000) >> 24,
3067	    (ioc->biosVersion & 0x00FF0000) >> 16,
3068	    (ioc->biosVersion & 0x0000FF00) >> 8,
3069	    ioc->biosVersion & 0x000000FF);
3070}
3071static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3072
3073static ssize_t
3074mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3075			  char *buf)
3076{
3077	struct Scsi_Host *host = class_to_shost(dev);
3078	MPT_SCSI_HOST	*hd = shost_priv(host);
3079	MPT_ADAPTER *ioc = hd->ioc;
3080
3081	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3082}
3083static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3084
3085static ssize_t
3086mptscsih_version_product_show(struct device *dev,
3087			      struct device_attribute *attr,
3088char *buf)
3089{
3090	struct Scsi_Host *host = class_to_shost(dev);
3091	MPT_SCSI_HOST	*hd = shost_priv(host);
3092	MPT_ADAPTER *ioc = hd->ioc;
3093
3094	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3095}
3096static DEVICE_ATTR(version_product, S_IRUGO,
3097    mptscsih_version_product_show, NULL);
3098
3099static ssize_t
3100mptscsih_version_nvdata_persistent_show(struct device *dev,
3101					struct device_attribute *attr,
3102					char *buf)
3103{
3104	struct Scsi_Host *host = class_to_shost(dev);
3105	MPT_SCSI_HOST	*hd = shost_priv(host);
3106	MPT_ADAPTER *ioc = hd->ioc;
3107
3108	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3109	    ioc->nvdata_version_persistent);
3110}
3111static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3112    mptscsih_version_nvdata_persistent_show, NULL);
3113
3114static ssize_t
3115mptscsih_version_nvdata_default_show(struct device *dev,
3116				     struct device_attribute *attr, char *buf)
3117{
3118	struct Scsi_Host *host = class_to_shost(dev);
3119	MPT_SCSI_HOST	*hd = shost_priv(host);
3120	MPT_ADAPTER *ioc = hd->ioc;
3121
3122	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3123}
3124static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3125    mptscsih_version_nvdata_default_show, NULL);
3126
3127static ssize_t
3128mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3129			 char *buf)
3130{
3131	struct Scsi_Host *host = class_to_shost(dev);
3132	MPT_SCSI_HOST	*hd = shost_priv(host);
3133	MPT_ADAPTER *ioc = hd->ioc;
3134
3135	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3136}
3137static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3138
3139static ssize_t
3140mptscsih_board_assembly_show(struct device *dev,
3141			     struct device_attribute *attr, char *buf)
3142{
3143	struct Scsi_Host *host = class_to_shost(dev);
3144	MPT_SCSI_HOST	*hd = shost_priv(host);
3145	MPT_ADAPTER *ioc = hd->ioc;
3146
3147	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3148}
3149static DEVICE_ATTR(board_assembly, S_IRUGO,
3150    mptscsih_board_assembly_show, NULL);
3151
3152static ssize_t
3153mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3154			   char *buf)
3155{
3156	struct Scsi_Host *host = class_to_shost(dev);
3157	MPT_SCSI_HOST	*hd = shost_priv(host);
3158	MPT_ADAPTER *ioc = hd->ioc;
3159
3160	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3161}
3162static DEVICE_ATTR(board_tracer, S_IRUGO,
3163    mptscsih_board_tracer_show, NULL);
3164
3165static ssize_t
3166mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3167		       char *buf)
3168{
3169	struct Scsi_Host *host = class_to_shost(dev);
3170	MPT_SCSI_HOST	*hd = shost_priv(host);
3171	MPT_ADAPTER *ioc = hd->ioc;
3172
3173	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3174}
3175static DEVICE_ATTR(io_delay, S_IRUGO,
3176    mptscsih_io_delay_show, NULL);
3177
3178static ssize_t
3179mptscsih_device_delay_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, "%02d\n", ioc->device_missing_delay);
3187}
3188static DEVICE_ATTR(device_delay, S_IRUGO,
3189    mptscsih_device_delay_show, NULL);
3190
3191static ssize_t
3192mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3193			  char *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, "%08xh\n", ioc->debug_level);
3200}
3201static ssize_t
3202mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3203			   const char *buf, size_t count)
3204{
3205	struct Scsi_Host *host = class_to_shost(dev);
3206	MPT_SCSI_HOST	*hd = shost_priv(host);
3207	MPT_ADAPTER *ioc = hd->ioc;
3208	int val = 0;
3209
3210	if (sscanf(buf, "%x", &val) != 1)
3211		return -EINVAL;
3212
3213	ioc->debug_level = val;
3214	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3215				ioc->name, ioc->debug_level);
3216	return strlen(buf);
3217}
3218static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3219	mptscsih_debug_level_show, mptscsih_debug_level_store);
3220
3221static struct attribute *mptscsih_host_attrs[] = {
3222	&dev_attr_version_fw.attr,
3223	&dev_attr_version_bios.attr,
3224	&dev_attr_version_mpi.attr,
3225	&dev_attr_version_product.attr,
3226	&dev_attr_version_nvdata_persistent.attr,
3227	&dev_attr_version_nvdata_default.attr,
3228	&dev_attr_board_name.attr,
3229	&dev_attr_board_assembly.attr,
3230	&dev_attr_board_tracer.attr,
3231	&dev_attr_io_delay.attr,
3232	&dev_attr_device_delay.attr,
3233	&dev_attr_debug_level.attr,
3234	NULL,
3235};
3236
3237static const struct attribute_group mptscsih_host_attr_group = {
3238	.attrs = mptscsih_host_attrs
3239};
3240
3241const struct attribute_group *mptscsih_host_attr_groups[] = {
3242	&mptscsih_host_attr_group,
3243	NULL
3244};
3245EXPORT_SYMBOL(mptscsih_host_attr_groups);
3246
3247EXPORT_SYMBOL(mptscsih_remove);
3248EXPORT_SYMBOL(mptscsih_shutdown);
3249#ifdef CONFIG_PM
3250EXPORT_SYMBOL(mptscsih_suspend);
3251EXPORT_SYMBOL(mptscsih_resume);
3252#endif
3253EXPORT_SYMBOL(mptscsih_show_info);
3254EXPORT_SYMBOL(mptscsih_info);
3255EXPORT_SYMBOL(mptscsih_qcmd);
3256EXPORT_SYMBOL(mptscsih_slave_destroy);
3257EXPORT_SYMBOL(mptscsih_slave_configure);
3258EXPORT_SYMBOL(mptscsih_abort);
3259EXPORT_SYMBOL(mptscsih_dev_reset);
3260EXPORT_SYMBOL(mptscsih_bus_reset);
3261EXPORT_SYMBOL(mptscsih_host_reset);
3262EXPORT_SYMBOL(mptscsih_bios_param);
3263EXPORT_SYMBOL(mptscsih_io_done);
3264EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3265EXPORT_SYMBOL(mptscsih_scandv_complete);
3266EXPORT_SYMBOL(mptscsih_event_process);
3267EXPORT_SYMBOL(mptscsih_ioc_reset);
3268EXPORT_SYMBOL(mptscsih_change_queue_depth);
3269
3270/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
v4.10.11
   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#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 = %llu\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:%llu] "
 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			break;
 796
 797		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
 798			if (ioc->bus_type == FC)
 799				sc->result = DID_ERROR << 16;
 800			else
 801				sc->result = DID_RESET << 16;
 802			break;
 803
 804		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
 805			scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 806			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
 807				sc->result=DID_SOFT_ERROR << 16;
 808			else /* Sufficient data transfer occurred */
 809				sc->result = (DID_OK << 16) | scsi_status;
 810			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 811			    "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
 812			    ioc->name, sc->result, sc->device->channel, sc->device->id));
 813			break;
 814
 815		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 816			/*
 817			 *  Do upfront check for valid SenseData and give it
 818			 *  precedence!
 819			 */
 820			sc->result = (DID_OK << 16) | scsi_status;
 821			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
 822
 823				/*
 824				 * For an Errata on LSI53C1030
 825				 * When the length of request data
 826				 * and transfer data are different
 827				 * with result of command (READ or VERIFY),
 828				 * DID_SOFT_ERROR is set.
 829				 */
 830				if (ioc->bus_type == SPI) {
 831					if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
 832					    pScsiReq->CDB[0] == READ_10 ||
 833					    pScsiReq->CDB[0] == READ_12 ||
 834						(pScsiReq->CDB[0] == READ_16 &&
 835						((pScsiReq->CDB[1] & 0x02) == 0)) ||
 836					    pScsiReq->CDB[0] == VERIFY  ||
 837					    pScsiReq->CDB[0] == VERIFY_16) {
 838						if (scsi_bufflen(sc) !=
 839							xfer_cnt) {
 840							sc->result =
 841							DID_SOFT_ERROR << 16;
 842						    printk(KERN_WARNING "Errata"
 843						    "on LSI53C1030 occurred."
 844						    "sc->req_bufflen=0x%02x,"
 845						    "xfer_cnt=0x%02x\n",
 846						    scsi_bufflen(sc),
 847						    xfer_cnt);
 848						}
 849					}
 850				}
 851
 852				if (xfer_cnt < sc->underflow) {
 853					if (scsi_status == SAM_STAT_BUSY)
 854						sc->result = SAM_STAT_BUSY;
 855					else
 856						sc->result = DID_SOFT_ERROR << 16;
 857				}
 858				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
 859					/* What to do?
 860				 	*/
 861					sc->result = DID_SOFT_ERROR << 16;
 862				}
 863				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 864					/*  Not real sure here either...  */
 865					sc->result = DID_RESET << 16;
 866				}
 867			}
 868
 869
 870			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 871			    "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
 872			    ioc->name, sc->underflow));
 873			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 874			    "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
 875
 876			/* Report Queue Full
 877			 */
 878			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 879				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 880
 881			break;
 882
 883		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 884			scsi_set_resid(sc, 0);
 
 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	scsi_remove_host(host);
1180
1181	if((hd = shost_priv(host)) == NULL)
1182		return;
1183
1184	mptscsih_shutdown(pdev);
1185
1186	sz1=0;
1187
1188	if (ioc->ScsiLookup != NULL) {
1189		sz1 = ioc->req_depth * sizeof(void *);
1190		kfree(ioc->ScsiLookup);
1191		ioc->ScsiLookup = NULL;
1192	}
1193
1194	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1195	    "Free'd ScsiLookup (%d) memory\n",
1196	    ioc->name, sz1));
1197
1198	kfree(hd->info_kbuf);
 
1199
1200	/* NULL the Scsi_Host pointer
1201	 */
1202	ioc->sh = NULL;
1203
1204	scsi_host_put(host);
1205
1206	mpt_detach(pdev);
1207
1208}
1209
1210/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1211/*
1212 *	mptscsih_shutdown - reboot notifier
1213 *
1214 */
1215void
1216mptscsih_shutdown(struct pci_dev *pdev)
1217{
1218}
1219
1220#ifdef CONFIG_PM
1221/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1222/*
1223 *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1224 *
1225 *
1226 */
1227int
1228mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1229{
1230	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1231
1232	scsi_block_requests(ioc->sh);
1233	flush_scheduled_work();
1234	mptscsih_shutdown(pdev);
1235	return mpt_suspend(pdev,state);
1236}
1237
1238/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1239/*
1240 *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1241 *
1242 *
1243 */
1244int
1245mptscsih_resume(struct pci_dev *pdev)
1246{
1247	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1248	int rc;
1249
1250	rc = mpt_resume(pdev);
1251	scsi_unblock_requests(ioc->sh);
1252	return rc;
1253}
1254
1255#endif
1256
1257/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1258/**
1259 *	mptscsih_info - Return information about MPT adapter
1260 *	@SChost: Pointer to Scsi_Host structure
1261 *
1262 *	(linux scsi_host_template.info routine)
1263 *
1264 *	Returns pointer to buffer where information was written.
1265 */
1266const char *
1267mptscsih_info(struct Scsi_Host *SChost)
1268{
1269	MPT_SCSI_HOST *h;
1270	int size = 0;
1271
1272	h = shost_priv(SChost);
1273
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	return h->info_kbuf;
1283}
1284
1285int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1286{
1287	MPT_SCSI_HOST	*hd = shost_priv(host);
1288	MPT_ADAPTER	*ioc = hd->ioc;
1289
1290	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1291	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1292	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1293	seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1294
1295	return 0;
1296}
1297
1298/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1299#define ADD_INDEX_LOG(req_ent)	do { } while(0)
1300
1301/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1302/**
1303 *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1304 *	@SCpnt: Pointer to scsi_cmnd structure
1305 *
1306 *	(linux scsi_host_template.queuecommand routine)
1307 *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1308 *	from a linux scsi_cmnd request and send it to the IOC.
1309 *
1310 *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1311 */
1312int
1313mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1314{
1315	MPT_SCSI_HOST		*hd;
1316	MPT_FRAME_HDR		*mf;
1317	SCSIIORequest_t		*pScsiReq;
1318	VirtDevice		*vdevice = SCpnt->device->hostdata;
1319	u32	 datalen;
1320	u32	 scsictl;
1321	u32	 scsidir;
1322	u32	 cmd_len;
1323	int	 my_idx;
1324	int	 ii;
1325	MPT_ADAPTER *ioc;
1326
1327	hd = shost_priv(SCpnt->device->host);
1328	ioc = hd->ioc;
1329
1330	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1331		ioc->name, SCpnt));
1332
1333	if (ioc->taskmgmt_quiesce_io)
1334		return SCSI_MLQUEUE_HOST_BUSY;
1335
1336	/*
1337	 *  Put together a MPT SCSI request...
1338	 */
1339	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1340		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1341				ioc->name));
1342		return SCSI_MLQUEUE_HOST_BUSY;
1343	}
1344
1345	pScsiReq = (SCSIIORequest_t *) mf;
1346
1347	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1348
1349	ADD_INDEX_LOG(my_idx);
1350
1351	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1352	 *    Seems we may receive a buffer (datalen>0) even when there
1353	 *    will be no data transfer!  GRRRRR...
1354	 */
1355	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1356		datalen = scsi_bufflen(SCpnt);
1357		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1358	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1359		datalen = scsi_bufflen(SCpnt);
1360		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1361	} else {
1362		datalen = 0;
1363		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1364	}
1365
1366	/* Default to untagged. Once a target structure has been allocated,
1367	 * use the Inquiry data to determine if device supports tagged.
1368	 */
1369	if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1370	    SCpnt->device->tagged_supported)
1371		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1372	else
1373		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1374
1375
1376	/* Use the above information to set up the message frame
1377	 */
1378	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1379	pScsiReq->Bus = vdevice->vtarget->channel;
1380	pScsiReq->ChainOffset = 0;
1381	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1382		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1383	else
1384		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1385	pScsiReq->CDBLength = SCpnt->cmd_len;
1386	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1387	pScsiReq->Reserved = 0;
1388	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1389	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1390	pScsiReq->Control = cpu_to_le32(scsictl);
1391
1392	/*
1393	 *  Write SCSI CDB into the message
1394	 */
1395	cmd_len = SCpnt->cmd_len;
1396	for (ii=0; ii < cmd_len; ii++)
1397		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1398
1399	for (ii=cmd_len; ii < 16; ii++)
1400		pScsiReq->CDB[ii] = 0;
1401
1402	/* DataLength */
1403	pScsiReq->DataLength = cpu_to_le32(datalen);
1404
1405	/* SenseBuffer low address */
1406	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1407					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1408
1409	/* Now add the SG list
1410	 * Always have a SGE even if null length.
1411	 */
1412	if (datalen == 0) {
1413		/* Add a NULL SGE */
1414		ioc->add_sge((char *)&pScsiReq->SGL,
1415			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1416			(dma_addr_t) -1);
1417	} else {
1418		/* Add a 32 or 64 bit SGE */
1419		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1420			goto fail;
1421	}
1422
1423	SCpnt->host_scribble = (unsigned char *)mf;
1424	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1425
1426	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1427	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1428			ioc->name, SCpnt, mf, my_idx));
1429	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1430	return 0;
1431
1432 fail:
1433	mptscsih_freeChainBuffers(ioc, my_idx);
1434	mpt_free_msg_frame(ioc, mf);
1435	return SCSI_MLQUEUE_HOST_BUSY;
1436}
1437
1438/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439/*
1440 *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1441 *	with a SCSI IO request
1442 *	@hd: Pointer to the MPT_SCSI_HOST instance
1443 *	@req_idx: Index of the SCSI IO request frame.
1444 *
1445 *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1446 *	No return.
1447 */
1448static void
1449mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1450{
1451	MPT_FRAME_HDR *chain;
1452	unsigned long flags;
1453	int chain_idx;
1454	int next;
1455
1456	/* Get the first chain index and reset
1457	 * tracker state.
1458	 */
1459	chain_idx = ioc->ReqToChain[req_idx];
1460	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1461
1462	while (chain_idx != MPT_HOST_NO_CHAIN) {
1463
1464		/* Save the next chain buffer index */
1465		next = ioc->ChainToChain[chain_idx];
1466
1467		/* Free this chain buffer and reset
1468		 * tracker
1469		 */
1470		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1471
1472		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1473					+ (chain_idx * ioc->req_sz));
1474
1475		spin_lock_irqsave(&ioc->FreeQlock, flags);
1476		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1477		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1478
1479		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1480				ioc->name, chain_idx));
1481
1482		/* handle next */
1483		chain_idx = next;
1484	}
1485	return;
1486}
1487
1488/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489/*
1490 *	Reset Handling
1491 */
1492
1493/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494/**
1495 *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1496 *	@hd: Pointer to MPT_SCSI_HOST structure
1497 *	@type: Task Management type
1498 *	@channel: channel number for task management
1499 *	@id: Logical Target ID for reset (if appropriate)
1500 *	@lun: Logical Unit for reset (if appropriate)
1501 *	@ctx2abort: Context for the task to be aborted (if appropriate)
1502 *	@timeout: timeout for task management control
1503 *
1504 *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1505 *	or a non-interrupt thread.  In the former, must not call schedule().
1506 *
1507 *	Not all fields are meaningfull for all task types.
1508 *
1509 *	Returns 0 for SUCCESS, or FAILED.
1510 *
1511 **/
1512int
1513mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1514	int ctx2abort, ulong timeout)
1515{
1516	MPT_FRAME_HDR	*mf;
1517	SCSITaskMgmt_t	*pScsiTm;
1518	int		 ii;
1519	int		 retval;
1520	MPT_ADAPTER 	*ioc = hd->ioc;
1521	unsigned long	 timeleft;
1522	u8		 issue_hard_reset;
1523	u32		 ioc_raw_state;
1524	unsigned long	 time_count;
1525
1526	issue_hard_reset = 0;
1527	ioc_raw_state = mpt_GetIocState(ioc, 0);
1528
1529	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1530		printk(MYIOC_s_WARN_FMT
1531			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1532			ioc->name, type, ioc_raw_state);
1533		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1534		    ioc->name, __func__);
1535		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1536			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1537			    "FAILED!!\n", ioc->name);
1538		return 0;
1539	}
1540
1541	/* DOORBELL ACTIVE check is not required if
1542	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1543	*/
1544
1545	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1546		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1547		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1548		printk(MYIOC_s_WARN_FMT
1549			"TaskMgmt type=%x: ioc_state: "
1550			"DOORBELL_ACTIVE (0x%x)!\n",
1551			ioc->name, type, ioc_raw_state);
1552		return FAILED;
1553	}
1554
1555	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1556	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1557		mf = NULL;
1558		retval = FAILED;
1559		goto out;
1560	}
1561
1562	/* Return Fail to calling function if no message frames available.
1563	 */
1564	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1565		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1566			"TaskMgmt no msg frames!!\n", ioc->name));
1567		retval = FAILED;
1568		mpt_clear_taskmgmt_in_progress_flag(ioc);
1569		goto out;
1570	}
1571	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1572			ioc->name, mf));
1573
1574	/* Format the Request
1575	 */
1576	pScsiTm = (SCSITaskMgmt_t *) mf;
1577	pScsiTm->TargetID = id;
1578	pScsiTm->Bus = channel;
1579	pScsiTm->ChainOffset = 0;
1580	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1581
1582	pScsiTm->Reserved = 0;
1583	pScsiTm->TaskType = type;
1584	pScsiTm->Reserved1 = 0;
1585	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1586                    ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1587
1588	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1589
1590	for (ii=0; ii < 7; ii++)
1591		pScsiTm->Reserved2[ii] = 0;
1592
1593	pScsiTm->TaskMsgContext = ctx2abort;
1594
1595	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1596		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1597		type, timeout));
1598
1599	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1600
1601	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1602	time_count = jiffies;
1603	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1604	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1605		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1606	else {
1607		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1608			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1609		if (retval) {
1610			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1611				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1612				ioc->name, mf, retval));
1613			mpt_free_msg_frame(ioc, mf);
1614			mpt_clear_taskmgmt_in_progress_flag(ioc);
1615			goto out;
1616		}
1617	}
1618
1619	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1620		timeout*HZ);
1621	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1622		retval = FAILED;
1623		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1624		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1625		mpt_clear_taskmgmt_in_progress_flag(ioc);
1626		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1627			goto out;
1628		issue_hard_reset = 1;
1629		goto out;
1630	}
1631
1632	retval = mptscsih_taskmgmt_reply(ioc, type,
1633	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1634
1635	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1636	    "TaskMgmt completed (%d seconds)\n",
1637	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1638
1639 out:
1640
1641	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1642	if (issue_hard_reset) {
1643		printk(MYIOC_s_WARN_FMT
1644		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1645		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1646		retval = (ioc->bus_type == SAS) ?
1647			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1648			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1649		mpt_free_msg_frame(ioc, mf);
1650	}
1651
1652	retval = (retval == 0) ? 0 : FAILED;
1653	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1654	return retval;
1655}
1656EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1657
1658static int
1659mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1660{
1661	switch (ioc->bus_type) {
1662	case FC:
1663		return 40;
1664	case SAS:
1665		return 30;
1666	case SPI:
1667	default:
1668		return 10;
1669	}
1670}
1671
1672/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1673/**
1674 *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1675 *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1676 *
1677 *	(linux scsi_host_template.eh_abort_handler routine)
1678 *
1679 *	Returns SUCCESS or FAILED.
1680 **/
1681int
1682mptscsih_abort(struct scsi_cmnd * SCpnt)
1683{
1684	MPT_SCSI_HOST	*hd;
1685	MPT_FRAME_HDR	*mf;
1686	u32		 ctx2abort;
1687	int		 scpnt_idx;
1688	int		 retval;
1689	VirtDevice	 *vdevice;
1690	MPT_ADAPTER	*ioc;
1691
1692	/* If we can't locate our host adapter structure, return FAILED status.
1693	 */
1694	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1695		SCpnt->result = DID_RESET << 16;
1696		SCpnt->scsi_done(SCpnt);
1697		printk(KERN_ERR MYNAM ": task abort: "
1698		    "can't locate host! (sc=%p)\n", SCpnt);
1699		return FAILED;
1700	}
1701
1702	ioc = hd->ioc;
1703	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1704	       ioc->name, SCpnt);
1705	scsi_print_command(SCpnt);
1706
1707	vdevice = SCpnt->device->hostdata;
1708	if (!vdevice || !vdevice->vtarget) {
1709		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1710		    "task abort: device has been deleted (sc=%p)\n",
1711		    ioc->name, SCpnt));
1712		SCpnt->result = DID_NO_CONNECT << 16;
1713		SCpnt->scsi_done(SCpnt);
1714		retval = SUCCESS;
1715		goto out;
1716	}
1717
1718	/* Task aborts are not supported for hidden raid components.
1719	 */
1720	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1721		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1722		    "task abort: hidden raid component (sc=%p)\n",
1723		    ioc->name, SCpnt));
1724		SCpnt->result = DID_RESET << 16;
1725		retval = FAILED;
1726		goto out;
1727	}
1728
1729	/* Task aborts are not supported for volumes.
1730	 */
1731	if (vdevice->vtarget->raidVolume) {
1732		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1733		    "task abort: raid volume (sc=%p)\n",
1734		    ioc->name, SCpnt));
1735		SCpnt->result = DID_RESET << 16;
1736		retval = FAILED;
1737		goto out;
1738	}
1739
1740	/* Find this command
1741	 */
1742	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1743		/* Cmd not found in ScsiLookup.
1744		 * Do OS callback.
1745		 */
1746		SCpnt->result = DID_RESET << 16;
1747		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1748		   "Command not in the active list! (sc=%p)\n", ioc->name,
1749		   SCpnt));
1750		retval = SUCCESS;
1751		goto out;
1752	}
1753
1754	if (ioc->timeouts < -1)
1755		ioc->timeouts++;
1756
1757	if (mpt_fwfault_debug)
1758		mpt_halt_firmware(ioc);
1759
1760	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1761	 * (the IO to be ABORT'd)
1762	 *
1763	 * NOTE: Since we do not byteswap MsgContext, we do not
1764	 *	 swap it here either.  It is an opaque cookie to
1765	 *	 the controller, so it does not matter. -DaveM
1766	 */
1767	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1768	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1769	retval = mptscsih_IssueTaskMgmt(hd,
1770			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1771			 vdevice->vtarget->channel,
1772			 vdevice->vtarget->id, vdevice->lun,
1773			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1774
1775	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1776		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1777		    "task abort: command still in active list! (sc=%p)\n",
1778		    ioc->name, SCpnt));
1779		retval = FAILED;
1780	} else {
1781		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1782		    "task abort: command cleared from active list! (sc=%p)\n",
1783		    ioc->name, SCpnt));
1784		retval = SUCCESS;
1785	}
1786
1787 out:
1788	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1789	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1790	    SCpnt);
1791
1792	return retval;
1793}
1794
1795/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1796/**
1797 *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1798 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1799 *
1800 *	(linux scsi_host_template.eh_dev_reset_handler routine)
1801 *
1802 *	Returns SUCCESS or FAILED.
1803 **/
1804int
1805mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1806{
1807	MPT_SCSI_HOST	*hd;
1808	int		 retval;
1809	VirtDevice	 *vdevice;
1810	MPT_ADAPTER	*ioc;
1811
1812	/* If we can't locate our host adapter structure, return FAILED status.
1813	 */
1814	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1815		printk(KERN_ERR MYNAM ": target reset: "
1816		   "Can't locate host! (sc=%p)\n", SCpnt);
1817		return FAILED;
1818	}
1819
1820	ioc = hd->ioc;
1821	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1822	       ioc->name, SCpnt);
1823	scsi_print_command(SCpnt);
1824
1825	vdevice = SCpnt->device->hostdata;
1826	if (!vdevice || !vdevice->vtarget) {
1827		retval = 0;
1828		goto out;
1829	}
1830
1831	/* Target reset to hidden raid component is not supported
1832	 */
1833	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1834		retval = FAILED;
1835		goto out;
1836	}
1837
1838	retval = mptscsih_IssueTaskMgmt(hd,
1839				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1840				vdevice->vtarget->channel,
1841				vdevice->vtarget->id, 0, 0,
1842				mptscsih_get_tm_timeout(ioc));
1843
1844 out:
1845	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1846	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1847
1848	if (retval == 0)
1849		return SUCCESS;
1850	else
1851		return FAILED;
1852}
1853
1854
1855/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1856/**
1857 *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1858 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1859 *
1860 *	(linux scsi_host_template.eh_bus_reset_handler routine)
1861 *
1862 *	Returns SUCCESS or FAILED.
1863 **/
1864int
1865mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1866{
1867	MPT_SCSI_HOST	*hd;
1868	int		 retval;
1869	VirtDevice	 *vdevice;
1870	MPT_ADAPTER	*ioc;
1871
1872	/* If we can't locate our host adapter structure, return FAILED status.
1873	 */
1874	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1875		printk(KERN_ERR MYNAM ": bus reset: "
1876		   "Can't locate host! (sc=%p)\n", SCpnt);
1877		return FAILED;
1878	}
1879
1880	ioc = hd->ioc;
1881	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1882	       ioc->name, SCpnt);
1883	scsi_print_command(SCpnt);
1884
1885	if (ioc->timeouts < -1)
1886		ioc->timeouts++;
1887
1888	vdevice = SCpnt->device->hostdata;
1889	if (!vdevice || !vdevice->vtarget)
1890		return SUCCESS;
1891	retval = mptscsih_IssueTaskMgmt(hd,
1892					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1893					vdevice->vtarget->channel, 0, 0, 0,
1894					mptscsih_get_tm_timeout(ioc));
1895
1896	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1897	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1898
1899	if (retval == 0)
1900		return SUCCESS;
1901	else
1902		return FAILED;
1903}
1904
1905/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1906/**
1907 *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1908 *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1909 *
1910 *	(linux scsi_host_template.eh_host_reset_handler routine)
1911 *
1912 *	Returns SUCCESS or FAILED.
1913 */
1914int
1915mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1916{
1917	MPT_SCSI_HOST *  hd;
1918	int              status = SUCCESS;
1919	MPT_ADAPTER	*ioc;
1920	int		retval;
1921
1922	/*  If we can't locate the host to reset, then we failed. */
1923	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1924		printk(KERN_ERR MYNAM ": host reset: "
1925		    "Can't locate host! (sc=%p)\n", SCpnt);
1926		return FAILED;
1927	}
1928
1929	/* make sure we have no outstanding commands at this stage */
1930	mptscsih_flush_running_cmds(hd);
1931
1932	ioc = hd->ioc;
1933	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1934	    ioc->name, SCpnt);
1935
1936	/*  If our attempts to reset the host failed, then return a failed
1937	 *  status.  The host will be taken off line by the SCSI mid-layer.
1938	 */
1939    retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1940	if (retval < 0)
1941		status = FAILED;
1942	else
1943		status = SUCCESS;
1944
1945	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1946	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1947
1948	return status;
1949}
1950
1951static int
1952mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1953	SCSITaskMgmtReply_t *pScsiTmReply)
1954{
1955	u16			 iocstatus;
1956	u32			 termination_count;
1957	int			 retval;
1958
1959	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1960		retval = FAILED;
1961		goto out;
1962	}
1963
1964	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1965
1966	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1967	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1968
1969	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1970	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1971	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1972	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1973	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1974	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1975	    termination_count));
1976
1977	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1978	    pScsiTmReply->ResponseCode)
1979		mptscsih_taskmgmt_response_code(ioc,
1980		    pScsiTmReply->ResponseCode);
1981
1982	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1983		retval = 0;
1984		goto out;
1985	}
1986
1987	retval = FAILED;
1988	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1989		if (termination_count == 1)
1990			retval = 0;
1991		goto out;
1992	}
1993
1994	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1995	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1996		retval = 0;
1997
1998 out:
1999	return retval;
2000}
2001
2002/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2003void
2004mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2005{
2006	char *desc;
2007
2008	switch (response_code) {
2009	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2010		desc = "The task completed.";
2011		break;
2012	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2013		desc = "The IOC received an invalid frame status.";
2014		break;
2015	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2016		desc = "The task type is not supported.";
2017		break;
2018	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2019		desc = "The requested task failed.";
2020		break;
2021	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2022		desc = "The task completed successfully.";
2023		break;
2024	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2025		desc = "The LUN request is invalid.";
2026		break;
2027	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2028		desc = "The task is in the IOC queue and has not been sent to target.";
2029		break;
2030	default:
2031		desc = "unknown";
2032		break;
2033	}
2034	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2035		ioc->name, response_code, desc);
2036}
2037EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2038
2039/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2040/**
2041 *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2042 *	@ioc: Pointer to MPT_ADAPTER structure
2043 *	@mf: Pointer to SCSI task mgmt request frame
2044 *	@mr: Pointer to SCSI task mgmt reply frame
2045 *
2046 *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2047 *	of any SCSI task management request.
2048 *	This routine is registered with the MPT (base) driver at driver
2049 *	load/init time via the mpt_register() API call.
2050 *
2051 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2052 **/
2053int
2054mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2055	MPT_FRAME_HDR *mr)
2056{
2057	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2058		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2059
2060	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2061
2062	if (!mr)
2063		goto out;
2064
2065	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2066	memcpy(ioc->taskmgmt_cmds.reply, mr,
2067	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2068 out:
2069	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2070		mpt_clear_taskmgmt_in_progress_flag(ioc);
2071		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2072		complete(&ioc->taskmgmt_cmds.done);
2073		if (ioc->bus_type == SAS)
2074			ioc->schedule_target_reset(ioc);
2075		return 1;
2076	}
2077	return 0;
2078}
2079
2080/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2081/*
2082 *	This is anyones guess quite frankly.
2083 */
2084int
2085mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2086		sector_t capacity, int geom[])
2087{
2088	int		heads;
2089	int		sectors;
2090	sector_t	cylinders;
2091	ulong 		dummy;
2092
2093	heads = 64;
2094	sectors = 32;
2095
2096	dummy = heads * sectors;
2097	cylinders = capacity;
2098	sector_div(cylinders,dummy);
2099
2100	/*
2101	 * Handle extended translation size for logical drives
2102	 * > 1Gb
2103	 */
2104	if ((ulong)capacity >= 0x200000) {
2105		heads = 255;
2106		sectors = 63;
2107		dummy = heads * sectors;
2108		cylinders = capacity;
2109		sector_div(cylinders,dummy);
2110	}
2111
2112	/* return result */
2113	geom[0] = heads;
2114	geom[1] = sectors;
2115	geom[2] = cylinders;
2116
2117	return 0;
2118}
2119
2120/* Search IOC page 3 to determine if this is hidden physical disk
2121 *
2122 */
2123int
2124mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2125{
2126	struct inactive_raid_component_info *component_info;
2127	int i, j;
2128	RaidPhysDiskPage1_t *phys_disk;
2129	int rc = 0;
2130	int num_paths;
2131
2132	if (!ioc->raid_data.pIocPg3)
2133		goto out;
2134	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2135		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2136		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2137			rc = 1;
2138			goto out;
2139		}
2140	}
2141
2142	if (ioc->bus_type != SAS)
2143		goto out;
2144
2145	/*
2146	 * Check if dual path
2147	 */
2148	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2149		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2150		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2151		if (num_paths < 2)
2152			continue;
2153		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2154		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2155		if (!phys_disk)
2156			continue;
2157		if ((mpt_raid_phys_disk_pg1(ioc,
2158		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2159		    phys_disk))) {
2160			kfree(phys_disk);
2161			continue;
2162		}
2163		for (j = 0; j < num_paths; j++) {
2164			if ((phys_disk->Path[j].Flags &
2165			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2166				continue;
2167			if ((phys_disk->Path[j].Flags &
2168			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2169				continue;
2170			if ((id == phys_disk->Path[j].PhysDiskID) &&
2171			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2172				rc = 1;
2173				kfree(phys_disk);
2174				goto out;
2175			}
2176		}
2177		kfree(phys_disk);
2178	}
2179
2180
2181	/*
2182	 * Check inactive list for matching phys disks
2183	 */
2184	if (list_empty(&ioc->raid_data.inactive_list))
2185		goto out;
2186
2187	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2188	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2189	    list) {
2190		if ((component_info->d.PhysDiskID == id) &&
2191		    (component_info->d.PhysDiskBus == channel))
2192			rc = 1;
2193	}
2194	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2195
2196 out:
2197	return rc;
2198}
2199EXPORT_SYMBOL(mptscsih_is_phys_disk);
2200
2201u8
2202mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2203{
2204	struct inactive_raid_component_info *component_info;
2205	int i, j;
2206	RaidPhysDiskPage1_t *phys_disk;
2207	int rc = -ENXIO;
2208	int num_paths;
2209
2210	if (!ioc->raid_data.pIocPg3)
2211		goto out;
2212	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2213		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2214		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2215			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2216			goto out;
2217		}
2218	}
2219
2220	if (ioc->bus_type != SAS)
2221		goto out;
2222
2223	/*
2224	 * Check if dual path
2225	 */
2226	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2227		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2228		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2229		if (num_paths < 2)
2230			continue;
2231		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2232		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2233		if (!phys_disk)
2234			continue;
2235		if ((mpt_raid_phys_disk_pg1(ioc,
2236		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2237		    phys_disk))) {
2238			kfree(phys_disk);
2239			continue;
2240		}
2241		for (j = 0; j < num_paths; j++) {
2242			if ((phys_disk->Path[j].Flags &
2243			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2244				continue;
2245			if ((phys_disk->Path[j].Flags &
2246			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2247				continue;
2248			if ((id == phys_disk->Path[j].PhysDiskID) &&
2249			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2250				rc = phys_disk->PhysDiskNum;
2251				kfree(phys_disk);
2252				goto out;
2253			}
2254		}
2255		kfree(phys_disk);
2256	}
2257
2258	/*
2259	 * Check inactive list for matching phys disks
2260	 */
2261	if (list_empty(&ioc->raid_data.inactive_list))
2262		goto out;
2263
2264	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2265	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2266	    list) {
2267		if ((component_info->d.PhysDiskID == id) &&
2268		    (component_info->d.PhysDiskBus == channel))
2269			rc = component_info->d.PhysDiskNum;
2270	}
2271	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2272
2273 out:
2274	return rc;
2275}
2276EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2277
2278/*
2279 *	OS entry point to allow for host driver to free allocated memory
2280 *	Called if no device present or device being unloaded
2281 */
2282void
2283mptscsih_slave_destroy(struct scsi_device *sdev)
2284{
2285	struct Scsi_Host	*host = sdev->host;
2286	MPT_SCSI_HOST		*hd = shost_priv(host);
2287	VirtTarget		*vtarget;
2288	VirtDevice		*vdevice;
2289	struct scsi_target 	*starget;
2290
2291	starget = scsi_target(sdev);
2292	vtarget = starget->hostdata;
2293	vdevice = sdev->hostdata;
2294	if (!vdevice)
2295		return;
2296
2297	mptscsih_search_running_cmds(hd, vdevice);
2298	vtarget->num_luns--;
2299	mptscsih_synchronize_cache(hd, vdevice);
2300	kfree(vdevice);
2301	sdev->hostdata = NULL;
2302}
2303
2304/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2305/*
2306 *	mptscsih_change_queue_depth - This function will set a devices queue depth
2307 *	@sdev: per scsi_device pointer
2308 *	@qdepth: requested queue depth
2309 *
2310 *	Adding support for new 'change_queue_depth' api.
2311*/
2312int
2313mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2314{
2315	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2316	VirtTarget 		*vtarget;
2317	struct scsi_target 	*starget;
2318	int			max_depth;
2319	MPT_ADAPTER		*ioc = hd->ioc;
2320
2321	starget = scsi_target(sdev);
2322	vtarget = starget->hostdata;
2323
2324	if (ioc->bus_type == SPI) {
2325		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2326			max_depth = 1;
2327		else if (sdev->type == TYPE_DISK &&
2328			 vtarget->minSyncFactor <= MPT_ULTRA160)
2329			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2330		else
2331			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2332	} else
2333		 max_depth = ioc->sh->can_queue;
2334
2335	if (!sdev->tagged_supported)
2336		max_depth = 1;
2337
2338	if (qdepth > max_depth)
2339		qdepth = max_depth;
2340
2341	return scsi_change_queue_depth(sdev, qdepth);
2342}
2343
2344/*
2345 *	OS entry point to adjust the queue_depths on a per-device basis.
2346 *	Called once per device the bus scan. Use it to force the queue_depth
2347 *	member to 1 if a device does not support Q tags.
2348 *	Return non-zero if fails.
2349 */
2350int
2351mptscsih_slave_configure(struct scsi_device *sdev)
2352{
2353	struct Scsi_Host	*sh = sdev->host;
2354	VirtTarget		*vtarget;
2355	VirtDevice		*vdevice;
2356	struct scsi_target 	*starget;
2357	MPT_SCSI_HOST		*hd = shost_priv(sh);
2358	MPT_ADAPTER		*ioc = hd->ioc;
2359
2360	starget = scsi_target(sdev);
2361	vtarget = starget->hostdata;
2362	vdevice = sdev->hostdata;
2363
2364	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2365		"device @ %p, channel=%d, id=%d, lun=%llu\n",
2366		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2367	if (ioc->bus_type == SPI)
2368		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2369		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2370		    ioc->name, sdev->sdtr, sdev->wdtr,
2371		    sdev->ppr, sdev->inquiry_len));
2372
2373	vdevice->configured_lun = 1;
2374
2375	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2376		"Queue depth=%d, tflags=%x\n",
2377		ioc->name, sdev->queue_depth, vtarget->tflags));
2378
2379	if (ioc->bus_type == SPI)
2380		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2381		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2382		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2383		    vtarget->minSyncFactor));
2384
2385	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2386	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2387		"tagged %d, simple %d\n",
2388		ioc->name,sdev->tagged_supported, sdev->simple_tags));
2389
2390	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2391
2392	return 0;
2393}
2394
2395/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2396/*
2397 *  Private routines...
2398 */
2399
2400/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2401/* Utility function to copy sense data from the scsi_cmnd buffer
2402 * to the FC and SCSI target structures.
2403 *
2404 */
2405static void
2406mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2407{
2408	VirtDevice	*vdevice;
2409	SCSIIORequest_t	*pReq;
2410	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2411	MPT_ADAPTER 	*ioc = hd->ioc;
2412
2413	/* Get target structure
2414	 */
2415	pReq = (SCSIIORequest_t *) mf;
2416	vdevice = sc->device->hostdata;
2417
2418	if (sense_count) {
2419		u8 *sense_data;
2420		int req_index;
2421
2422		/* Copy the sense received into the scsi command block. */
2423		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2424		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2425		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2426
2427		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2428		 */
2429		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2430			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2431				int idx;
2432
2433				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2434				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2435				ioc->events[idx].eventContext = ioc->eventContext;
2436
2437				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2438					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2439					(sc->device->channel << 8) | sc->device->id;
2440
2441				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2442
2443				ioc->eventContext++;
2444				if (ioc->pcidev->vendor ==
2445				    PCI_VENDOR_ID_IBM) {
2446					mptscsih_issue_sep_command(ioc,
2447					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2448					vdevice->vtarget->tflags |=
2449					    MPT_TARGET_FLAGS_LED_ON;
2450				}
2451			}
2452		}
2453	} else {
2454		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2455				ioc->name));
2456	}
2457}
2458
2459/**
2460 * mptscsih_get_scsi_lookup - retrieves scmd entry
2461 * @ioc: Pointer to MPT_ADAPTER structure
2462 * @i: index into the array
2463 *
2464 * Returns the scsi_cmd pointer
2465 */
2466struct scsi_cmnd *
2467mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2468{
2469	unsigned long	flags;
2470	struct scsi_cmnd *scmd;
2471
2472	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2473	scmd = ioc->ScsiLookup[i];
2474	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2475
2476	return scmd;
2477}
2478EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2479
2480/**
2481 * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2482 * @ioc: Pointer to MPT_ADAPTER structure
2483 * @i: index into the array
2484 *
2485 * Returns the scsi_cmd pointer
2486 *
2487 **/
2488static struct scsi_cmnd *
2489mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2490{
2491	unsigned long	flags;
2492	struct scsi_cmnd *scmd;
2493
2494	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2495	scmd = ioc->ScsiLookup[i];
2496	ioc->ScsiLookup[i] = NULL;
2497	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2498
2499	return scmd;
2500}
2501
2502/**
2503 * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2504 *
2505 * @ioc: Pointer to MPT_ADAPTER structure
2506 * @i: index into the array
2507 * @scmd: scsi_cmnd pointer
2508 *
2509 **/
2510static void
2511mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2512{
2513	unsigned long	flags;
2514
2515	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2516	ioc->ScsiLookup[i] = scmd;
2517	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2518}
2519
2520/**
2521 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2522 * @ioc: Pointer to MPT_ADAPTER structure
2523 * @sc: scsi_cmnd pointer
2524 */
2525static int
2526SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2527{
2528	unsigned long	flags;
2529	int i, index=-1;
2530
2531	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2532	for (i = 0; i < ioc->req_depth; i++) {
2533		if (ioc->ScsiLookup[i] == sc) {
2534			index = i;
2535			goto out;
2536		}
2537	}
2538
2539 out:
2540	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2541	return index;
2542}
2543
2544/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2545int
2546mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2547{
2548	MPT_SCSI_HOST	*hd;
2549
2550	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2551		return 0;
2552
2553	hd = shost_priv(ioc->sh);
2554	switch (reset_phase) {
2555	case MPT_IOC_SETUP_RESET:
2556		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2557		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2558		break;
2559	case MPT_IOC_PRE_RESET:
2560		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2561		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2562		mptscsih_flush_running_cmds(hd);
2563		break;
2564	case MPT_IOC_POST_RESET:
2565		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2566		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2567		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2568			ioc->internal_cmds.status |=
2569				MPT_MGMT_STATUS_DID_IOCRESET;
2570			complete(&ioc->internal_cmds.done);
2571		}
2572		break;
2573	default:
2574		break;
2575	}
2576	return 1;		/* currently means nothing really */
2577}
2578
2579/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2580int
2581mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2582{
2583	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2584
2585	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2586		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2587		ioc->name, event));
2588
2589	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2590	    event == MPI_EVENT_EXT_BUS_RESET) &&
2591	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2592			ioc->soft_resets++;
2593
2594	return 1;		/* currently means nothing really */
2595}
2596
2597/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2598/*
2599 *  Bus Scan and Domain Validation functionality ...
2600 */
2601
2602/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603/*
2604 *	mptscsih_scandv_complete - Scan and DV callback routine registered
2605 *	to Fustion MPT (base) driver.
2606 *
2607 *	@ioc: Pointer to MPT_ADAPTER structure
2608 *	@mf: Pointer to original MPT request frame
2609 *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2610 *
2611 *	This routine is called from mpt.c::mpt_interrupt() at the completion
2612 *	of any SCSI IO request.
2613 *	This routine is registered with the Fusion MPT (base) driver at driver
2614 *	load/init time via the mpt_register() API call.
2615 *
2616 *	Returns 1 indicating alloc'd request frame ptr should be freed.
2617 *
2618 *	Remark: Sets a completion code and (possibly) saves sense data
2619 *	in the IOC member localReply structure.
2620 *	Used ONLY for DV and other internal commands.
2621 */
2622int
2623mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2624				MPT_FRAME_HDR *reply)
2625{
2626	SCSIIORequest_t *pReq;
2627	SCSIIOReply_t	*pReply;
2628	u8		 cmd;
2629	u16		 req_idx;
2630	u8	*sense_data;
2631	int		 sz;
2632
2633	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2634	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2635	if (!reply)
2636		goto out;
2637
2638	pReply = (SCSIIOReply_t *) reply;
2639	pReq = (SCSIIORequest_t *) req;
2640	ioc->internal_cmds.completion_code =
2641	    mptscsih_get_completion_code(ioc, req, reply);
2642	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2643	memcpy(ioc->internal_cmds.reply, reply,
2644	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2645	cmd = reply->u.hdr.Function;
2646	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2647	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2648	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2649		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2650		sense_data = ((u8 *)ioc->sense_buf_pool +
2651		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2652		sz = min_t(int, pReq->SenseBufferLength,
2653		    MPT_SENSE_BUFFER_ALLOC);
2654		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2655	}
2656 out:
2657	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2658		return 0;
2659	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2660	complete(&ioc->internal_cmds.done);
2661	return 1;
2662}
2663
2664
2665/**
2666 *	mptscsih_get_completion_code - get completion code from MPT request
2667 *	@ioc: Pointer to MPT_ADAPTER structure
2668 *	@req: Pointer to original MPT request frame
2669 *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2670 *
2671 **/
2672static int
2673mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2674				MPT_FRAME_HDR *reply)
2675{
2676	SCSIIOReply_t	*pReply;
2677	MpiRaidActionReply_t *pr;
2678	u8		 scsi_status;
2679	u16		 status;
2680	int		 completion_code;
2681
2682	pReply = (SCSIIOReply_t *)reply;
2683	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2684	scsi_status = pReply->SCSIStatus;
2685
2686	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2687	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2688	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2689	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2690
2691	switch (status) {
2692
2693	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2694		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2695		break;
2696
2697	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2698	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2699	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2700	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2701		completion_code = MPT_SCANDV_DID_RESET;
2702		break;
2703
2704	case MPI_IOCSTATUS_BUSY:
2705	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2706		completion_code = MPT_SCANDV_BUSY;
2707		break;
2708
2709	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2710	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2711	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2712		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2713			completion_code = MPT_SCANDV_GOOD;
2714		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2715			pr = (MpiRaidActionReply_t *)reply;
2716			if (le16_to_cpu(pr->ActionStatus) ==
2717				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2718				completion_code = MPT_SCANDV_GOOD;
2719			else
2720				completion_code = MPT_SCANDV_SOME_ERROR;
2721		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2722			completion_code = MPT_SCANDV_SENSE;
2723		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2724			if (req->u.scsireq.CDB[0] == INQUIRY)
2725				completion_code = MPT_SCANDV_ISSUE_SENSE;
2726			else
2727				completion_code = MPT_SCANDV_DID_RESET;
2728		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2729			completion_code = MPT_SCANDV_DID_RESET;
2730		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2731			completion_code = MPT_SCANDV_DID_RESET;
2732		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2733			completion_code = MPT_SCANDV_BUSY;
2734		else
2735			completion_code = MPT_SCANDV_GOOD;
2736		break;
2737
2738	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2739		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2740			completion_code = MPT_SCANDV_DID_RESET;
2741		else
2742			completion_code = MPT_SCANDV_SOME_ERROR;
2743		break;
2744	default:
2745		completion_code = MPT_SCANDV_SOME_ERROR;
2746		break;
2747
2748	}	/* switch(status) */
2749
2750	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2751	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2752	return completion_code;
2753}
2754
2755/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2756/**
2757 *	mptscsih_do_cmd - Do internal command.
2758 *	@hd: MPT_SCSI_HOST pointer
2759 *	@io: INTERNAL_CMD pointer.
2760 *
2761 *	Issue the specified internally generated command and do command
2762 *	specific cleanup. For bus scan / DV only.
2763 *	NOTES: If command is Inquiry and status is good,
2764 *	initialize a target structure, save the data
2765 *
2766 *	Remark: Single threaded access only.
2767 *
2768 *	Return:
2769 *		< 0 if an illegal command or no resources
2770 *
2771 *		   0 if good
2772 *
2773 *		 > 0 if command complete but some type of completion error.
2774 */
2775static int
2776mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2777{
2778	MPT_FRAME_HDR	*mf;
2779	SCSIIORequest_t	*pScsiReq;
2780	int		 my_idx, ii, dir;
2781	int		 timeout;
2782	char		 cmdLen;
2783	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2784	u8		 cmd = io->cmd;
2785	MPT_ADAPTER *ioc = hd->ioc;
2786	int		 ret = 0;
2787	unsigned long	 timeleft;
2788	unsigned long	 flags;
2789
2790	/* don't send internal command during diag reset */
2791	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2792	if (ioc->ioc_reset_in_progress) {
2793		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2794		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2795			"%s: busy with host reset\n", ioc->name, __func__));
2796		return MPT_SCANDV_BUSY;
2797	}
2798	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2799
2800	mutex_lock(&ioc->internal_cmds.mutex);
2801
2802	/* Set command specific information
2803	 */
2804	switch (cmd) {
2805	case INQUIRY:
2806		cmdLen = 6;
2807		dir = MPI_SCSIIO_CONTROL_READ;
2808		CDB[0] = cmd;
2809		CDB[4] = io->size;
2810		timeout = 10;
2811		break;
2812
2813	case TEST_UNIT_READY:
2814		cmdLen = 6;
2815		dir = MPI_SCSIIO_CONTROL_READ;
2816		timeout = 10;
2817		break;
2818
2819	case START_STOP:
2820		cmdLen = 6;
2821		dir = MPI_SCSIIO_CONTROL_READ;
2822		CDB[0] = cmd;
2823		CDB[4] = 1;	/*Spin up the disk */
2824		timeout = 15;
2825		break;
2826
2827	case REQUEST_SENSE:
2828		cmdLen = 6;
2829		CDB[0] = cmd;
2830		CDB[4] = io->size;
2831		dir = MPI_SCSIIO_CONTROL_READ;
2832		timeout = 10;
2833		break;
2834
2835	case READ_BUFFER:
2836		cmdLen = 10;
2837		dir = MPI_SCSIIO_CONTROL_READ;
2838		CDB[0] = cmd;
2839		if (io->flags & MPT_ICFLAG_ECHO) {
2840			CDB[1] = 0x0A;
2841		} else {
2842			CDB[1] = 0x02;
2843		}
2844
2845		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2846			CDB[1] |= 0x01;
2847		}
2848		CDB[6] = (io->size >> 16) & 0xFF;
2849		CDB[7] = (io->size >>  8) & 0xFF;
2850		CDB[8] = io->size & 0xFF;
2851		timeout = 10;
2852		break;
2853
2854	case WRITE_BUFFER:
2855		cmdLen = 10;
2856		dir = MPI_SCSIIO_CONTROL_WRITE;
2857		CDB[0] = cmd;
2858		if (io->flags & MPT_ICFLAG_ECHO) {
2859			CDB[1] = 0x0A;
2860		} else {
2861			CDB[1] = 0x02;
2862		}
2863		CDB[6] = (io->size >> 16) & 0xFF;
2864		CDB[7] = (io->size >>  8) & 0xFF;
2865		CDB[8] = io->size & 0xFF;
2866		timeout = 10;
2867		break;
2868
2869	case RESERVE:
2870		cmdLen = 6;
2871		dir = MPI_SCSIIO_CONTROL_READ;
2872		CDB[0] = cmd;
2873		timeout = 10;
2874		break;
2875
2876	case RELEASE:
2877		cmdLen = 6;
2878		dir = MPI_SCSIIO_CONTROL_READ;
2879		CDB[0] = cmd;
2880		timeout = 10;
2881		break;
2882
2883	case SYNCHRONIZE_CACHE:
2884		cmdLen = 10;
2885		dir = MPI_SCSIIO_CONTROL_READ;
2886		CDB[0] = cmd;
2887//		CDB[1] = 0x02;	/* set immediate bit */
2888		timeout = 10;
2889		break;
2890
2891	default:
2892		/* Error Case */
2893		ret = -EFAULT;
2894		goto out;
2895	}
2896
2897	/* Get and Populate a free Frame
2898	 * MsgContext set in mpt_get_msg_frame call
2899	 */
2900	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2901		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2902		    ioc->name, __func__));
2903		ret = MPT_SCANDV_BUSY;
2904		goto out;
2905	}
2906
2907	pScsiReq = (SCSIIORequest_t *) mf;
2908
2909	/* Get the request index */
2910	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2911	ADD_INDEX_LOG(my_idx); /* for debug */
2912
2913	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2914		pScsiReq->TargetID = io->physDiskNum;
2915		pScsiReq->Bus = 0;
2916		pScsiReq->ChainOffset = 0;
2917		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2918	} else {
2919		pScsiReq->TargetID = io->id;
2920		pScsiReq->Bus = io->channel;
2921		pScsiReq->ChainOffset = 0;
2922		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2923	}
2924
2925	pScsiReq->CDBLength = cmdLen;
2926	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2927
2928	pScsiReq->Reserved = 0;
2929
2930	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2931	/* MsgContext set in mpt_get_msg_fram call  */
2932
2933	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2934
2935	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2936		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2937	else
2938		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2939
2940	if (cmd == REQUEST_SENSE) {
2941		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2942		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2943		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2944	}
2945
2946	for (ii = 0; ii < 16; ii++)
2947		pScsiReq->CDB[ii] = CDB[ii];
2948
2949	pScsiReq->DataLength = cpu_to_le32(io->size);
2950	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2951					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2952
2953	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2954	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2955	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2956
2957	if (dir == MPI_SCSIIO_CONTROL_READ)
2958		ioc->add_sge((char *) &pScsiReq->SGL,
2959		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2960	else
2961		ioc->add_sge((char *) &pScsiReq->SGL,
2962		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2963
2964	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2965	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2966	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2967	    timeout*HZ);
2968	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2969		ret = MPT_SCANDV_DID_RESET;
2970		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2971		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2972		    cmd));
2973		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2974			mpt_free_msg_frame(ioc, mf);
2975			goto out;
2976		}
2977		if (!timeleft) {
2978			printk(MYIOC_s_WARN_FMT
2979			       "Issuing Reset from %s!! doorbell=0x%08xh"
2980			       " cmd=0x%02x\n",
2981			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
2982			       cmd);
2983			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2984			mpt_free_msg_frame(ioc, mf);
2985		}
2986		goto out;
2987	}
2988
2989	ret = ioc->internal_cmds.completion_code;
2990	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2991			ioc->name, __func__, ret));
2992
2993 out:
2994	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2995	mutex_unlock(&ioc->internal_cmds.mutex);
2996	return ret;
2997}
2998
2999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3000/**
3001 *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3002 *	@hd: Pointer to a SCSI HOST structure
3003 *	@vdevice: virtual target device
3004 *
3005 *	Uses the ISR, but with special processing.
3006 *	MUST be single-threaded.
3007 *
3008 */
3009static void
3010mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3011{
3012	INTERNAL_CMD		 iocmd;
3013
3014	/* Ignore hidden raid components, this is handled when the command
3015	 * is sent to the volume
3016	 */
3017	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3018		return;
3019
3020	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3021	    !vdevice->configured_lun)
3022		return;
3023
3024	/* Following parameters will not change
3025	 * in this routine.
3026	 */
3027	iocmd.cmd = SYNCHRONIZE_CACHE;
3028	iocmd.flags = 0;
3029	iocmd.physDiskNum = -1;
3030	iocmd.data = NULL;
3031	iocmd.data_dma = -1;
3032	iocmd.size = 0;
3033	iocmd.rsvd = iocmd.rsvd2 = 0;
3034	iocmd.channel = vdevice->vtarget->channel;
3035	iocmd.id = vdevice->vtarget->id;
3036	iocmd.lun = vdevice->lun;
3037
3038	mptscsih_do_cmd(hd, &iocmd);
3039}
3040
3041static ssize_t
3042mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3043			 char *buf)
3044{
3045	struct Scsi_Host *host = class_to_shost(dev);
3046	MPT_SCSI_HOST	*hd = shost_priv(host);
3047	MPT_ADAPTER *ioc = hd->ioc;
3048
3049	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3050	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3051	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3052	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3053	    ioc->facts.FWVersion.Word & 0x000000FF);
3054}
3055static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3056
3057static ssize_t
3058mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3059			   char *buf)
3060{
3061	struct Scsi_Host *host = class_to_shost(dev);
3062	MPT_SCSI_HOST	*hd = shost_priv(host);
3063	MPT_ADAPTER *ioc = hd->ioc;
3064
3065	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3066	    (ioc->biosVersion & 0xFF000000) >> 24,
3067	    (ioc->biosVersion & 0x00FF0000) >> 16,
3068	    (ioc->biosVersion & 0x0000FF00) >> 8,
3069	    ioc->biosVersion & 0x000000FF);
3070}
3071static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3072
3073static ssize_t
3074mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3075			  char *buf)
3076{
3077	struct Scsi_Host *host = class_to_shost(dev);
3078	MPT_SCSI_HOST	*hd = shost_priv(host);
3079	MPT_ADAPTER *ioc = hd->ioc;
3080
3081	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3082}
3083static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3084
3085static ssize_t
3086mptscsih_version_product_show(struct device *dev,
3087			      struct device_attribute *attr,
3088char *buf)
3089{
3090	struct Scsi_Host *host = class_to_shost(dev);
3091	MPT_SCSI_HOST	*hd = shost_priv(host);
3092	MPT_ADAPTER *ioc = hd->ioc;
3093
3094	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3095}
3096static DEVICE_ATTR(version_product, S_IRUGO,
3097    mptscsih_version_product_show, NULL);
3098
3099static ssize_t
3100mptscsih_version_nvdata_persistent_show(struct device *dev,
3101					struct device_attribute *attr,
3102					char *buf)
3103{
3104	struct Scsi_Host *host = class_to_shost(dev);
3105	MPT_SCSI_HOST	*hd = shost_priv(host);
3106	MPT_ADAPTER *ioc = hd->ioc;
3107
3108	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3109	    ioc->nvdata_version_persistent);
3110}
3111static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3112    mptscsih_version_nvdata_persistent_show, NULL);
3113
3114static ssize_t
3115mptscsih_version_nvdata_default_show(struct device *dev,
3116				     struct device_attribute *attr, char *buf)
3117{
3118	struct Scsi_Host *host = class_to_shost(dev);
3119	MPT_SCSI_HOST	*hd = shost_priv(host);
3120	MPT_ADAPTER *ioc = hd->ioc;
3121
3122	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3123}
3124static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3125    mptscsih_version_nvdata_default_show, NULL);
3126
3127static ssize_t
3128mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3129			 char *buf)
3130{
3131	struct Scsi_Host *host = class_to_shost(dev);
3132	MPT_SCSI_HOST	*hd = shost_priv(host);
3133	MPT_ADAPTER *ioc = hd->ioc;
3134
3135	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3136}
3137static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3138
3139static ssize_t
3140mptscsih_board_assembly_show(struct device *dev,
3141			     struct device_attribute *attr, char *buf)
3142{
3143	struct Scsi_Host *host = class_to_shost(dev);
3144	MPT_SCSI_HOST	*hd = shost_priv(host);
3145	MPT_ADAPTER *ioc = hd->ioc;
3146
3147	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3148}
3149static DEVICE_ATTR(board_assembly, S_IRUGO,
3150    mptscsih_board_assembly_show, NULL);
3151
3152static ssize_t
3153mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3154			   char *buf)
3155{
3156	struct Scsi_Host *host = class_to_shost(dev);
3157	MPT_SCSI_HOST	*hd = shost_priv(host);
3158	MPT_ADAPTER *ioc = hd->ioc;
3159
3160	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3161}
3162static DEVICE_ATTR(board_tracer, S_IRUGO,
3163    mptscsih_board_tracer_show, NULL);
3164
3165static ssize_t
3166mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3167		       char *buf)
3168{
3169	struct Scsi_Host *host = class_to_shost(dev);
3170	MPT_SCSI_HOST	*hd = shost_priv(host);
3171	MPT_ADAPTER *ioc = hd->ioc;
3172
3173	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3174}
3175static DEVICE_ATTR(io_delay, S_IRUGO,
3176    mptscsih_io_delay_show, NULL);
3177
3178static ssize_t
3179mptscsih_device_delay_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, "%02d\n", ioc->device_missing_delay);
3187}
3188static DEVICE_ATTR(device_delay, S_IRUGO,
3189    mptscsih_device_delay_show, NULL);
3190
3191static ssize_t
3192mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3193			  char *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, "%08xh\n", ioc->debug_level);
3200}
3201static ssize_t
3202mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3203			   const char *buf, size_t count)
3204{
3205	struct Scsi_Host *host = class_to_shost(dev);
3206	MPT_SCSI_HOST	*hd = shost_priv(host);
3207	MPT_ADAPTER *ioc = hd->ioc;
3208	int val = 0;
3209
3210	if (sscanf(buf, "%x", &val) != 1)
3211		return -EINVAL;
3212
3213	ioc->debug_level = val;
3214	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3215				ioc->name, ioc->debug_level);
3216	return strlen(buf);
3217}
3218static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3219	mptscsih_debug_level_show, mptscsih_debug_level_store);
3220
3221struct device_attribute *mptscsih_host_attrs[] = {
3222	&dev_attr_version_fw,
3223	&dev_attr_version_bios,
3224	&dev_attr_version_mpi,
3225	&dev_attr_version_product,
3226	&dev_attr_version_nvdata_persistent,
3227	&dev_attr_version_nvdata_default,
3228	&dev_attr_board_name,
3229	&dev_attr_board_assembly,
3230	&dev_attr_board_tracer,
3231	&dev_attr_io_delay,
3232	&dev_attr_device_delay,
3233	&dev_attr_debug_level,
3234	NULL,
3235};
3236
3237EXPORT_SYMBOL(mptscsih_host_attrs);
 
 
 
 
 
 
 
 
3238
3239EXPORT_SYMBOL(mptscsih_remove);
3240EXPORT_SYMBOL(mptscsih_shutdown);
3241#ifdef CONFIG_PM
3242EXPORT_SYMBOL(mptscsih_suspend);
3243EXPORT_SYMBOL(mptscsih_resume);
3244#endif
3245EXPORT_SYMBOL(mptscsih_show_info);
3246EXPORT_SYMBOL(mptscsih_info);
3247EXPORT_SYMBOL(mptscsih_qcmd);
3248EXPORT_SYMBOL(mptscsih_slave_destroy);
3249EXPORT_SYMBOL(mptscsih_slave_configure);
3250EXPORT_SYMBOL(mptscsih_abort);
3251EXPORT_SYMBOL(mptscsih_dev_reset);
3252EXPORT_SYMBOL(mptscsih_bus_reset);
3253EXPORT_SYMBOL(mptscsih_host_reset);
3254EXPORT_SYMBOL(mptscsih_bios_param);
3255EXPORT_SYMBOL(mptscsih_io_done);
3256EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3257EXPORT_SYMBOL(mptscsih_scandv_complete);
3258EXPORT_SYMBOL(mptscsih_event_process);
3259EXPORT_SYMBOL(mptscsih_ioc_reset);
3260EXPORT_SYMBOL(mptscsih_change_queue_depth);
3261
3262/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/