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