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