Linux Audio

Check our new training course

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