Linux Audio

Check our new training course

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