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