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