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