xref: /linux/drivers/message/fusion/mptscsih.c (revision 58f7553fa424fd0fd74e8b796d50c66014cebebe)
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      For use with LSI PCI chip/adapter(s)
4  *      running LSI Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2008 LSI Corporation
7  *  (mailto:DL-MPTFusionLinux@lsi.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15 
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20 
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31 
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40 
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46 
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/slab.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>	/* for mdelay */
55 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
56 #include <linux/reboot.h>	/* notifier code */
57 #include <linux/workqueue.h>
58 
59 #include <scsi/scsi.h>
60 #include <scsi/scsi_cmnd.h>
61 #include <scsi/scsi_device.h>
62 #include <scsi/scsi_host.h>
63 #include <scsi/scsi_tcq.h>
64 #include <scsi/scsi_dbg.h>
65 
66 #include "mptbase.h"
67 #include "mptscsih.h"
68 #include "lsi/mpi_log_sas.h"
69 
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME		"Fusion MPT SCSI Host driver"
72 #define my_VERSION	MPT_LINUX_VERSION_COMMON
73 #define MYNAM		"mptscsih"
74 
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 	sc->scsi_done(sc);		/* Issue the command callback */
1013 
1014 	/* Free Chain buffers */
1015 	mptscsih_freeChainBuffers(ioc, req_idx);
1016 	return 1;
1017 }
1018 
1019 /*
1020  *	mptscsih_flush_running_cmds - For each command found, search
1021  *		Scsi_Host instance taskQ and reply to OS.
1022  *		Called only if recovering from a FW reload.
1023  *	@hd: Pointer to a SCSI HOST structure
1024  *
1025  *	Returns: None.
1026  *
1027  *	Must be called while new I/Os are being queued.
1028  */
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 		sc->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 slave_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 			sc->scsi_done(sc);
1122 			spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1123 		}
1124 	}
1125 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1126 	return;
1127 }
1128 
1129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1130 
1131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1132 /*
1133  *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
1134  *	from a SCSI target device.
1135  *	@sc: Pointer to scsi_cmnd structure
1136  *	@pScsiReply: Pointer to SCSIIOReply_t
1137  *	@pScsiReq: Pointer to original SCSI request
1138  *
1139  *	This routine periodically reports QUEUE_FULL status returned from a
1140  *	SCSI target device.  It reports this to the console via kernel
1141  *	printk() API call, not more than once every 10 seconds.
1142  */
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((hd = shost_priv(host)) == NULL)
1180 		return;
1181 
1182 	mptscsih_shutdown(pdev);
1183 
1184 	sz1=0;
1185 
1186 	if (ioc->ScsiLookup != NULL) {
1187 		sz1 = ioc->req_depth * sizeof(void *);
1188 		kfree(ioc->ScsiLookup);
1189 		ioc->ScsiLookup = NULL;
1190 	}
1191 
1192 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1193 	    "Free'd ScsiLookup (%d) memory\n",
1194 	    ioc->name, sz1));
1195 
1196 	kfree(hd->info_kbuf);
1197 
1198 	/* NULL the Scsi_Host pointer
1199 	 */
1200 	ioc->sh = NULL;
1201 
1202 	scsi_host_put(host);
1203 
1204 	mpt_detach(pdev);
1205 
1206 }
1207 
1208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1209 /*
1210  *	mptscsih_shutdown - reboot notifier
1211  *
1212  */
1213 void
1214 mptscsih_shutdown(struct pci_dev *pdev)
1215 {
1216 }
1217 
1218 #ifdef CONFIG_PM
1219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1220 /*
1221  *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1222  *
1223  *
1224  */
1225 int
1226 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1227 {
1228 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1229 
1230 	scsi_block_requests(ioc->sh);
1231 	flush_scheduled_work();
1232 	mptscsih_shutdown(pdev);
1233 	return mpt_suspend(pdev,state);
1234 }
1235 
1236 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1237 /*
1238  *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1239  *
1240  *
1241  */
1242 int
1243 mptscsih_resume(struct pci_dev *pdev)
1244 {
1245 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1246 	int rc;
1247 
1248 	rc = mpt_resume(pdev);
1249 	scsi_unblock_requests(ioc->sh);
1250 	return rc;
1251 }
1252 
1253 #endif
1254 
1255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1256 /**
1257  *	mptscsih_info - Return information about MPT adapter
1258  *	@SChost: Pointer to Scsi_Host structure
1259  *
1260  *	(linux scsi_host_template.info routine)
1261  *
1262  *	Returns pointer to buffer where information was written.
1263  */
1264 const char *
1265 mptscsih_info(struct Scsi_Host *SChost)
1266 {
1267 	MPT_SCSI_HOST *h;
1268 	int size = 0;
1269 
1270 	h = shost_priv(SChost);
1271 
1272 	if (h->info_kbuf == NULL)
1273 		if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1274 			return h->info_kbuf;
1275 	h->info_kbuf[0] = '\0';
1276 
1277 	mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1278 	h->info_kbuf[size-1] = '\0';
1279 
1280 	return h->info_kbuf;
1281 }
1282 
1283 int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1284 {
1285 	MPT_SCSI_HOST	*hd = shost_priv(host);
1286 	MPT_ADAPTER	*ioc = hd->ioc;
1287 
1288 	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1289 	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1290 	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1291 	seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1292 
1293 	return 0;
1294 }
1295 
1296 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1297 #define ADD_INDEX_LOG(req_ent)	do { } while(0)
1298 
1299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1300 /**
1301  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1302  *	@SCpnt: Pointer to scsi_cmnd structure
1303  *
1304  *	(linux scsi_host_template.queuecommand routine)
1305  *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1306  *	from a linux scsi_cmnd request and send it to the IOC.
1307  *
1308  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1309  */
1310 int
1311 mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1312 {
1313 	MPT_SCSI_HOST		*hd;
1314 	MPT_FRAME_HDR		*mf;
1315 	SCSIIORequest_t		*pScsiReq;
1316 	VirtDevice		*vdevice = SCpnt->device->hostdata;
1317 	u32	 datalen;
1318 	u32	 scsictl;
1319 	u32	 scsidir;
1320 	u32	 cmd_len;
1321 	int	 my_idx;
1322 	int	 ii;
1323 	MPT_ADAPTER *ioc;
1324 
1325 	hd = shost_priv(SCpnt->device->host);
1326 	ioc = hd->ioc;
1327 
1328 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1329 		ioc->name, SCpnt));
1330 
1331 	if (ioc->taskmgmt_quiesce_io)
1332 		return SCSI_MLQUEUE_HOST_BUSY;
1333 
1334 	/*
1335 	 *  Put together a MPT SCSI request...
1336 	 */
1337 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1338 		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1339 				ioc->name));
1340 		return SCSI_MLQUEUE_HOST_BUSY;
1341 	}
1342 
1343 	pScsiReq = (SCSIIORequest_t *) mf;
1344 
1345 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1346 
1347 	ADD_INDEX_LOG(my_idx);
1348 
1349 	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1350 	 *    Seems we may receive a buffer (datalen>0) even when there
1351 	 *    will be no data transfer!  GRRRRR...
1352 	 */
1353 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1354 		datalen = scsi_bufflen(SCpnt);
1355 		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1356 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1357 		datalen = scsi_bufflen(SCpnt);
1358 		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1359 	} else {
1360 		datalen = 0;
1361 		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1362 	}
1363 
1364 	/* Default to untagged. Once a target structure has been allocated,
1365 	 * use the Inquiry data to determine if device supports tagged.
1366 	 */
1367 	if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1368 	    SCpnt->device->tagged_supported)
1369 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1370 	else
1371 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1372 
1373 
1374 	/* Use the above information to set up the message frame
1375 	 */
1376 	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1377 	pScsiReq->Bus = vdevice->vtarget->channel;
1378 	pScsiReq->ChainOffset = 0;
1379 	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1380 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1381 	else
1382 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1383 	pScsiReq->CDBLength = SCpnt->cmd_len;
1384 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1385 	pScsiReq->Reserved = 0;
1386 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1387 	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1388 	pScsiReq->Control = cpu_to_le32(scsictl);
1389 
1390 	/*
1391 	 *  Write SCSI CDB into the message
1392 	 */
1393 	cmd_len = SCpnt->cmd_len;
1394 	for (ii=0; ii < cmd_len; ii++)
1395 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1396 
1397 	for (ii=cmd_len; ii < 16; ii++)
1398 		pScsiReq->CDB[ii] = 0;
1399 
1400 	/* DataLength */
1401 	pScsiReq->DataLength = cpu_to_le32(datalen);
1402 
1403 	/* SenseBuffer low address */
1404 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1405 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1406 
1407 	/* Now add the SG list
1408 	 * Always have a SGE even if null length.
1409 	 */
1410 	if (datalen == 0) {
1411 		/* Add a NULL SGE */
1412 		ioc->add_sge((char *)&pScsiReq->SGL,
1413 			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1414 			(dma_addr_t) -1);
1415 	} else {
1416 		/* Add a 32 or 64 bit SGE */
1417 		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1418 			goto fail;
1419 	}
1420 
1421 	SCpnt->host_scribble = (unsigned char *)mf;
1422 	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1423 
1424 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1425 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1426 			ioc->name, SCpnt, mf, my_idx));
1427 	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1428 	return 0;
1429 
1430  fail:
1431 	mptscsih_freeChainBuffers(ioc, my_idx);
1432 	mpt_free_msg_frame(ioc, mf);
1433 	return SCSI_MLQUEUE_HOST_BUSY;
1434 }
1435 
1436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1437 /*
1438  *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1439  *	with a SCSI IO request
1440  *	@hd: Pointer to the MPT_SCSI_HOST instance
1441  *	@req_idx: Index of the SCSI IO request frame.
1442  *
1443  *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1444  *	No return.
1445  */
1446 static void
1447 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1448 {
1449 	MPT_FRAME_HDR *chain;
1450 	unsigned long flags;
1451 	int chain_idx;
1452 	int next;
1453 
1454 	/* Get the first chain index and reset
1455 	 * tracker state.
1456 	 */
1457 	chain_idx = ioc->ReqToChain[req_idx];
1458 	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1459 
1460 	while (chain_idx != MPT_HOST_NO_CHAIN) {
1461 
1462 		/* Save the next chain buffer index */
1463 		next = ioc->ChainToChain[chain_idx];
1464 
1465 		/* Free this chain buffer and reset
1466 		 * tracker
1467 		 */
1468 		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1469 
1470 		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1471 					+ (chain_idx * ioc->req_sz));
1472 
1473 		spin_lock_irqsave(&ioc->FreeQlock, flags);
1474 		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1475 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1476 
1477 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1478 				ioc->name, chain_idx));
1479 
1480 		/* handle next */
1481 		chain_idx = next;
1482 	}
1483 	return;
1484 }
1485 
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487 /*
1488  *	Reset Handling
1489  */
1490 
1491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1492 /**
1493  *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1494  *	@hd: Pointer to MPT_SCSI_HOST structure
1495  *	@type: Task Management type
1496  *	@channel: channel number for task management
1497  *	@id: Logical Target ID for reset (if appropriate)
1498  *	@lun: Logical Unit for reset (if appropriate)
1499  *	@ctx2abort: Context for the task to be aborted (if appropriate)
1500  *	@timeout: timeout for task management control
1501  *
1502  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1503  *	or a non-interrupt thread.  In the former, must not call schedule().
1504  *
1505  *	Not all fields are meaningfull for all task types.
1506  *
1507  *	Returns 0 for SUCCESS, or FAILED.
1508  *
1509  **/
1510 int
1511 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1512 	int ctx2abort, ulong timeout)
1513 {
1514 	MPT_FRAME_HDR	*mf;
1515 	SCSITaskMgmt_t	*pScsiTm;
1516 	int		 ii;
1517 	int		 retval;
1518 	MPT_ADAPTER 	*ioc = hd->ioc;
1519 	u8		 issue_hard_reset;
1520 	u32		 ioc_raw_state;
1521 	unsigned long	 time_count;
1522 
1523 	issue_hard_reset = 0;
1524 	ioc_raw_state = mpt_GetIocState(ioc, 0);
1525 
1526 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1527 		printk(MYIOC_s_WARN_FMT
1528 			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1529 			ioc->name, type, ioc_raw_state);
1530 		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1531 		    ioc->name, __func__);
1532 		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1533 			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1534 			    "FAILED!!\n", ioc->name);
1535 		return 0;
1536 	}
1537 
1538 	/* DOORBELL ACTIVE check is not required if
1539 	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1540 	*/
1541 
1542 	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1543 		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1544 		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1545 		printk(MYIOC_s_WARN_FMT
1546 			"TaskMgmt type=%x: ioc_state: "
1547 			"DOORBELL_ACTIVE (0x%x)!\n",
1548 			ioc->name, type, ioc_raw_state);
1549 		return FAILED;
1550 	}
1551 
1552 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1553 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1554 		mf = NULL;
1555 		retval = FAILED;
1556 		goto out;
1557 	}
1558 
1559 	/* Return Fail to calling function if no message frames available.
1560 	 */
1561 	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1562 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1563 			"TaskMgmt no msg frames!!\n", ioc->name));
1564 		retval = FAILED;
1565 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1566 		goto out;
1567 	}
1568 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1569 			ioc->name, mf));
1570 
1571 	/* Format the Request
1572 	 */
1573 	pScsiTm = (SCSITaskMgmt_t *) mf;
1574 	pScsiTm->TargetID = id;
1575 	pScsiTm->Bus = channel;
1576 	pScsiTm->ChainOffset = 0;
1577 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1578 
1579 	pScsiTm->Reserved = 0;
1580 	pScsiTm->TaskType = type;
1581 	pScsiTm->Reserved1 = 0;
1582 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1583                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1584 
1585 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1586 
1587 	for (ii=0; ii < 7; ii++)
1588 		pScsiTm->Reserved2[ii] = 0;
1589 
1590 	pScsiTm->TaskMsgContext = ctx2abort;
1591 
1592 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1593 		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1594 		type, timeout));
1595 
1596 	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1597 
1598 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1599 	time_count = jiffies;
1600 	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1601 	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1602 		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1603 	else {
1604 		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1605 			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1606 		if (retval) {
1607 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1608 				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1609 				ioc->name, mf, retval));
1610 			mpt_free_msg_frame(ioc, mf);
1611 			mpt_clear_taskmgmt_in_progress_flag(ioc);
1612 			goto out;
1613 		}
1614 	}
1615 
1616 	wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1617 		timeout*HZ);
1618 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1619 		retval = FAILED;
1620 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1621 		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1622 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1623 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1624 			goto out;
1625 		issue_hard_reset = 1;
1626 		goto out;
1627 	}
1628 
1629 	retval = mptscsih_taskmgmt_reply(ioc, type,
1630 	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1631 
1632 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1633 	    "TaskMgmt completed (%d seconds)\n",
1634 	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1635 
1636  out:
1637 
1638 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1639 	if (issue_hard_reset) {
1640 		printk(MYIOC_s_WARN_FMT
1641 		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1642 		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1643 		retval = (ioc->bus_type == SAS) ?
1644 			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1645 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1646 		mpt_free_msg_frame(ioc, mf);
1647 	}
1648 
1649 	retval = (retval == 0) ? 0 : FAILED;
1650 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1651 	return retval;
1652 }
1653 EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1654 
1655 static int
1656 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1657 {
1658 	switch (ioc->bus_type) {
1659 	case FC:
1660 		return 40;
1661 	case SAS:
1662 		return 30;
1663 	case SPI:
1664 	default:
1665 		return 10;
1666 	}
1667 }
1668 
1669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1670 /**
1671  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1672  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1673  *
1674  *	(linux scsi_host_template.eh_abort_handler routine)
1675  *
1676  *	Returns SUCCESS or FAILED.
1677  **/
1678 int
1679 mptscsih_abort(struct scsi_cmnd * SCpnt)
1680 {
1681 	MPT_SCSI_HOST	*hd;
1682 	MPT_FRAME_HDR	*mf;
1683 	u32		 ctx2abort;
1684 	int		 scpnt_idx;
1685 	int		 retval;
1686 	VirtDevice	 *vdevice;
1687 	MPT_ADAPTER	*ioc;
1688 
1689 	/* If we can't locate our host adapter structure, return FAILED status.
1690 	 */
1691 	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1692 		SCpnt->result = DID_RESET << 16;
1693 		SCpnt->scsi_done(SCpnt);
1694 		printk(KERN_ERR MYNAM ": task abort: "
1695 		    "can't locate host! (sc=%p)\n", SCpnt);
1696 		return FAILED;
1697 	}
1698 
1699 	ioc = hd->ioc;
1700 	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1701 	       ioc->name, SCpnt);
1702 	scsi_print_command(SCpnt);
1703 
1704 	vdevice = SCpnt->device->hostdata;
1705 	if (!vdevice || !vdevice->vtarget) {
1706 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1707 		    "task abort: device has been deleted (sc=%p)\n",
1708 		    ioc->name, SCpnt));
1709 		SCpnt->result = DID_NO_CONNECT << 16;
1710 		SCpnt->scsi_done(SCpnt);
1711 		retval = SUCCESS;
1712 		goto out;
1713 	}
1714 
1715 	/* Task aborts are not supported for hidden raid components.
1716 	 */
1717 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1718 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1719 		    "task abort: hidden raid component (sc=%p)\n",
1720 		    ioc->name, SCpnt));
1721 		SCpnt->result = DID_RESET << 16;
1722 		retval = FAILED;
1723 		goto out;
1724 	}
1725 
1726 	/* Task aborts are not supported for volumes.
1727 	 */
1728 	if (vdevice->vtarget->raidVolume) {
1729 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1730 		    "task abort: raid volume (sc=%p)\n",
1731 		    ioc->name, SCpnt));
1732 		SCpnt->result = DID_RESET << 16;
1733 		retval = FAILED;
1734 		goto out;
1735 	}
1736 
1737 	/* Find this command
1738 	 */
1739 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1740 		/* Cmd not found in ScsiLookup.
1741 		 * Do OS callback.
1742 		 */
1743 		SCpnt->result = DID_RESET << 16;
1744 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1745 		   "Command not in the active list! (sc=%p)\n", ioc->name,
1746 		   SCpnt));
1747 		retval = SUCCESS;
1748 		goto out;
1749 	}
1750 
1751 	if (ioc->timeouts < -1)
1752 		ioc->timeouts++;
1753 
1754 	if (mpt_fwfault_debug)
1755 		mpt_halt_firmware(ioc);
1756 
1757 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1758 	 * (the IO to be ABORT'd)
1759 	 *
1760 	 * NOTE: Since we do not byteswap MsgContext, we do not
1761 	 *	 swap it here either.  It is an opaque cookie to
1762 	 *	 the controller, so it does not matter. -DaveM
1763 	 */
1764 	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1765 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1766 	retval = mptscsih_IssueTaskMgmt(hd,
1767 			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1768 			 vdevice->vtarget->channel,
1769 			 vdevice->vtarget->id, vdevice->lun,
1770 			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1771 
1772 	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1773 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1774 		    "task abort: command still in active list! (sc=%p)\n",
1775 		    ioc->name, SCpnt));
1776 		retval = FAILED;
1777 	} else {
1778 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1779 		    "task abort: command cleared from active list! (sc=%p)\n",
1780 		    ioc->name, SCpnt));
1781 		retval = SUCCESS;
1782 	}
1783 
1784  out:
1785 	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1786 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1787 	    SCpnt);
1788 
1789 	return retval;
1790 }
1791 
1792 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1793 /**
1794  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1795  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1796  *
1797  *	(linux scsi_host_template.eh_dev_reset_handler routine)
1798  *
1799  *	Returns SUCCESS or FAILED.
1800  **/
1801 int
1802 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1803 {
1804 	MPT_SCSI_HOST	*hd;
1805 	int		 retval;
1806 	VirtDevice	 *vdevice;
1807 	MPT_ADAPTER	*ioc;
1808 
1809 	/* If we can't locate our host adapter structure, return FAILED status.
1810 	 */
1811 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1812 		printk(KERN_ERR MYNAM ": target reset: "
1813 		   "Can't locate host! (sc=%p)\n", SCpnt);
1814 		return FAILED;
1815 	}
1816 
1817 	ioc = hd->ioc;
1818 	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1819 	       ioc->name, SCpnt);
1820 	scsi_print_command(SCpnt);
1821 
1822 	vdevice = SCpnt->device->hostdata;
1823 	if (!vdevice || !vdevice->vtarget) {
1824 		retval = 0;
1825 		goto out;
1826 	}
1827 
1828 	/* Target reset to hidden raid component is not supported
1829 	 */
1830 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1831 		retval = FAILED;
1832 		goto out;
1833 	}
1834 
1835 	retval = mptscsih_IssueTaskMgmt(hd,
1836 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1837 				vdevice->vtarget->channel,
1838 				vdevice->vtarget->id, 0, 0,
1839 				mptscsih_get_tm_timeout(ioc));
1840 
1841  out:
1842 	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1843 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1844 
1845 	if (retval == 0)
1846 		return SUCCESS;
1847 	else
1848 		return FAILED;
1849 }
1850 
1851 
1852 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1853 /**
1854  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1855  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1856  *
1857  *	(linux scsi_host_template.eh_bus_reset_handler routine)
1858  *
1859  *	Returns SUCCESS or FAILED.
1860  **/
1861 int
1862 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1863 {
1864 	MPT_SCSI_HOST	*hd;
1865 	int		 retval;
1866 	VirtDevice	 *vdevice;
1867 	MPT_ADAPTER	*ioc;
1868 
1869 	/* If we can't locate our host adapter structure, return FAILED status.
1870 	 */
1871 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1872 		printk(KERN_ERR MYNAM ": bus reset: "
1873 		   "Can't locate host! (sc=%p)\n", SCpnt);
1874 		return FAILED;
1875 	}
1876 
1877 	ioc = hd->ioc;
1878 	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1879 	       ioc->name, SCpnt);
1880 	scsi_print_command(SCpnt);
1881 
1882 	if (ioc->timeouts < -1)
1883 		ioc->timeouts++;
1884 
1885 	vdevice = SCpnt->device->hostdata;
1886 	if (!vdevice || !vdevice->vtarget)
1887 		return SUCCESS;
1888 	retval = mptscsih_IssueTaskMgmt(hd,
1889 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1890 					vdevice->vtarget->channel, 0, 0, 0,
1891 					mptscsih_get_tm_timeout(ioc));
1892 
1893 	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1894 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1895 
1896 	if (retval == 0)
1897 		return SUCCESS;
1898 	else
1899 		return FAILED;
1900 }
1901 
1902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1903 /**
1904  *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1905  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1906  *
1907  *	(linux scsi_host_template.eh_host_reset_handler routine)
1908  *
1909  *	Returns SUCCESS or FAILED.
1910  */
1911 int
1912 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1913 {
1914 	MPT_SCSI_HOST *  hd;
1915 	int              status = SUCCESS;
1916 	MPT_ADAPTER	*ioc;
1917 	int		retval;
1918 
1919 	/*  If we can't locate the host to reset, then we failed. */
1920 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1921 		printk(KERN_ERR MYNAM ": host reset: "
1922 		    "Can't locate host! (sc=%p)\n", SCpnt);
1923 		return FAILED;
1924 	}
1925 
1926 	/* make sure we have no outstanding commands at this stage */
1927 	mptscsih_flush_running_cmds(hd);
1928 
1929 	ioc = hd->ioc;
1930 	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1931 	    ioc->name, SCpnt);
1932 
1933 	/*  If our attempts to reset the host failed, then return a failed
1934 	 *  status.  The host will be taken off line by the SCSI mid-layer.
1935 	 */
1936 	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1937 	if (retval < 0)
1938 		status = FAILED;
1939 	else
1940 		status = SUCCESS;
1941 
1942 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1943 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1944 
1945 	return status;
1946 }
1947 
1948 static int
1949 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1950 	SCSITaskMgmtReply_t *pScsiTmReply)
1951 {
1952 	u16			 iocstatus;
1953 	u32			 termination_count;
1954 	int			 retval;
1955 
1956 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1957 		retval = FAILED;
1958 		goto out;
1959 	}
1960 
1961 	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1962 
1963 	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1964 	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1965 
1966 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1967 	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1968 	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1969 	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1970 	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1971 	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1972 	    termination_count));
1973 
1974 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1975 	    pScsiTmReply->ResponseCode)
1976 		mptscsih_taskmgmt_response_code(ioc,
1977 		    pScsiTmReply->ResponseCode);
1978 
1979 	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1980 		retval = 0;
1981 		goto out;
1982 	}
1983 
1984 	retval = FAILED;
1985 	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1986 		if (termination_count == 1)
1987 			retval = 0;
1988 		goto out;
1989 	}
1990 
1991 	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1992 	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1993 		retval = 0;
1994 
1995  out:
1996 	return retval;
1997 }
1998 
1999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2000 void
2001 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2002 {
2003 	char *desc;
2004 
2005 	switch (response_code) {
2006 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2007 		desc = "The task completed.";
2008 		break;
2009 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2010 		desc = "The IOC received an invalid frame status.";
2011 		break;
2012 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2013 		desc = "The task type is not supported.";
2014 		break;
2015 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2016 		desc = "The requested task failed.";
2017 		break;
2018 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2019 		desc = "The task completed successfully.";
2020 		break;
2021 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2022 		desc = "The LUN request is invalid.";
2023 		break;
2024 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2025 		desc = "The task is in the IOC queue and has not been sent to target.";
2026 		break;
2027 	default:
2028 		desc = "unknown";
2029 		break;
2030 	}
2031 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2032 		ioc->name, response_code, desc);
2033 }
2034 EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2035 
2036 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2037 /**
2038  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2039  *	@ioc: Pointer to MPT_ADAPTER structure
2040  *	@mf: Pointer to SCSI task mgmt request frame
2041  *	@mr: Pointer to SCSI task mgmt reply frame
2042  *
2043  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2044  *	of any SCSI task management request.
2045  *	This routine is registered with the MPT (base) driver at driver
2046  *	load/init time via the mpt_register() API call.
2047  *
2048  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2049  **/
2050 int
2051 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2052 	MPT_FRAME_HDR *mr)
2053 {
2054 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2055 		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2056 
2057 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2058 
2059 	if (!mr)
2060 		goto out;
2061 
2062 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2063 	memcpy(ioc->taskmgmt_cmds.reply, mr,
2064 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2065  out:
2066 	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2067 		mpt_clear_taskmgmt_in_progress_flag(ioc);
2068 		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2069 		complete(&ioc->taskmgmt_cmds.done);
2070 		if (ioc->bus_type == SAS)
2071 			ioc->schedule_target_reset(ioc);
2072 		return 1;
2073 	}
2074 	return 0;
2075 }
2076 
2077 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2078 /*
2079  *	This is anyones guess quite frankly.
2080  */
2081 int
2082 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2083 		sector_t capacity, int geom[])
2084 {
2085 	int		heads;
2086 	int		sectors;
2087 	sector_t	cylinders;
2088 	ulong 		dummy;
2089 
2090 	heads = 64;
2091 	sectors = 32;
2092 
2093 	dummy = heads * sectors;
2094 	cylinders = capacity;
2095 	sector_div(cylinders,dummy);
2096 
2097 	/*
2098 	 * Handle extended translation size for logical drives
2099 	 * > 1Gb
2100 	 */
2101 	if ((ulong)capacity >= 0x200000) {
2102 		heads = 255;
2103 		sectors = 63;
2104 		dummy = heads * sectors;
2105 		cylinders = capacity;
2106 		sector_div(cylinders,dummy);
2107 	}
2108 
2109 	/* return result */
2110 	geom[0] = heads;
2111 	geom[1] = sectors;
2112 	geom[2] = cylinders;
2113 
2114 	return 0;
2115 }
2116 
2117 /* Search IOC page 3 to determine if this is hidden physical disk
2118  *
2119  */
2120 int
2121 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2122 {
2123 	struct inactive_raid_component_info *component_info;
2124 	int i, j;
2125 	RaidPhysDiskPage1_t *phys_disk;
2126 	int rc = 0;
2127 	int num_paths;
2128 
2129 	if (!ioc->raid_data.pIocPg3)
2130 		goto out;
2131 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2132 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2133 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2134 			rc = 1;
2135 			goto out;
2136 		}
2137 	}
2138 
2139 	if (ioc->bus_type != SAS)
2140 		goto out;
2141 
2142 	/*
2143 	 * Check if dual path
2144 	 */
2145 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2146 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2147 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2148 		if (num_paths < 2)
2149 			continue;
2150 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2151 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2152 		if (!phys_disk)
2153 			continue;
2154 		if ((mpt_raid_phys_disk_pg1(ioc,
2155 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2156 		    phys_disk))) {
2157 			kfree(phys_disk);
2158 			continue;
2159 		}
2160 		for (j = 0; j < num_paths; j++) {
2161 			if ((phys_disk->Path[j].Flags &
2162 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2163 				continue;
2164 			if ((phys_disk->Path[j].Flags &
2165 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2166 				continue;
2167 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2168 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2169 				rc = 1;
2170 				kfree(phys_disk);
2171 				goto out;
2172 			}
2173 		}
2174 		kfree(phys_disk);
2175 	}
2176 
2177 
2178 	/*
2179 	 * Check inactive list for matching phys disks
2180 	 */
2181 	if (list_empty(&ioc->raid_data.inactive_list))
2182 		goto out;
2183 
2184 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2185 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2186 	    list) {
2187 		if ((component_info->d.PhysDiskID == id) &&
2188 		    (component_info->d.PhysDiskBus == channel))
2189 			rc = 1;
2190 	}
2191 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2192 
2193  out:
2194 	return rc;
2195 }
2196 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2197 
2198 u8
2199 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2200 {
2201 	struct inactive_raid_component_info *component_info;
2202 	int i, j;
2203 	RaidPhysDiskPage1_t *phys_disk;
2204 	int rc = -ENXIO;
2205 	int num_paths;
2206 
2207 	if (!ioc->raid_data.pIocPg3)
2208 		goto out;
2209 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2210 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2211 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2212 			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2213 			goto out;
2214 		}
2215 	}
2216 
2217 	if (ioc->bus_type != SAS)
2218 		goto out;
2219 
2220 	/*
2221 	 * Check if dual path
2222 	 */
2223 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2224 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2225 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2226 		if (num_paths < 2)
2227 			continue;
2228 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2229 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2230 		if (!phys_disk)
2231 			continue;
2232 		if ((mpt_raid_phys_disk_pg1(ioc,
2233 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2234 		    phys_disk))) {
2235 			kfree(phys_disk);
2236 			continue;
2237 		}
2238 		for (j = 0; j < num_paths; j++) {
2239 			if ((phys_disk->Path[j].Flags &
2240 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2241 				continue;
2242 			if ((phys_disk->Path[j].Flags &
2243 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2244 				continue;
2245 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2246 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2247 				rc = phys_disk->PhysDiskNum;
2248 				kfree(phys_disk);
2249 				goto out;
2250 			}
2251 		}
2252 		kfree(phys_disk);
2253 	}
2254 
2255 	/*
2256 	 * Check inactive list for matching phys disks
2257 	 */
2258 	if (list_empty(&ioc->raid_data.inactive_list))
2259 		goto out;
2260 
2261 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2262 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2263 	    list) {
2264 		if ((component_info->d.PhysDiskID == id) &&
2265 		    (component_info->d.PhysDiskBus == channel))
2266 			rc = component_info->d.PhysDiskNum;
2267 	}
2268 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2269 
2270  out:
2271 	return rc;
2272 }
2273 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2274 
2275 /*
2276  *	OS entry point to allow for host driver to free allocated memory
2277  *	Called if no device present or device being unloaded
2278  */
2279 void
2280 mptscsih_slave_destroy(struct scsi_device *sdev)
2281 {
2282 	struct Scsi_Host	*host = sdev->host;
2283 	MPT_SCSI_HOST		*hd = shost_priv(host);
2284 	VirtTarget		*vtarget;
2285 	VirtDevice		*vdevice;
2286 	struct scsi_target 	*starget;
2287 
2288 	starget = scsi_target(sdev);
2289 	vtarget = starget->hostdata;
2290 	vdevice = sdev->hostdata;
2291 	if (!vdevice)
2292 		return;
2293 
2294 	mptscsih_search_running_cmds(hd, vdevice);
2295 	vtarget->num_luns--;
2296 	mptscsih_synchronize_cache(hd, vdevice);
2297 	kfree(vdevice);
2298 	sdev->hostdata = NULL;
2299 }
2300 
2301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2302 /*
2303  *	mptscsih_change_queue_depth - This function will set a devices queue depth
2304  *	@sdev: per scsi_device pointer
2305  *	@qdepth: requested queue depth
2306  *
2307  *	Adding support for new 'change_queue_depth' api.
2308 */
2309 int
2310 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2311 {
2312 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2313 	VirtTarget 		*vtarget;
2314 	struct scsi_target 	*starget;
2315 	int			max_depth;
2316 	MPT_ADAPTER		*ioc = hd->ioc;
2317 
2318 	starget = scsi_target(sdev);
2319 	vtarget = starget->hostdata;
2320 
2321 	if (ioc->bus_type == SPI) {
2322 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2323 			max_depth = 1;
2324 		else if (sdev->type == TYPE_DISK &&
2325 			 vtarget->minSyncFactor <= MPT_ULTRA160)
2326 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2327 		else
2328 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2329 	} else
2330 		 max_depth = ioc->sh->can_queue;
2331 
2332 	if (!sdev->tagged_supported)
2333 		max_depth = 1;
2334 
2335 	if (qdepth > max_depth)
2336 		qdepth = max_depth;
2337 
2338 	return scsi_change_queue_depth(sdev, qdepth);
2339 }
2340 
2341 /*
2342  *	OS entry point to adjust the queue_depths on a per-device basis.
2343  *	Called once per device the bus scan. Use it to force the queue_depth
2344  *	member to 1 if a device does not support Q tags.
2345  *	Return non-zero if fails.
2346  */
2347 int
2348 mptscsih_slave_configure(struct scsi_device *sdev)
2349 {
2350 	struct Scsi_Host	*sh = sdev->host;
2351 	VirtTarget		*vtarget;
2352 	VirtDevice		*vdevice;
2353 	struct scsi_target 	*starget;
2354 	MPT_SCSI_HOST		*hd = shost_priv(sh);
2355 	MPT_ADAPTER		*ioc = hd->ioc;
2356 
2357 	starget = scsi_target(sdev);
2358 	vtarget = starget->hostdata;
2359 	vdevice = sdev->hostdata;
2360 
2361 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2362 		"device @ %p, channel=%d, id=%d, lun=%llu\n",
2363 		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2364 	if (ioc->bus_type == SPI)
2365 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2366 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2367 		    ioc->name, sdev->sdtr, sdev->wdtr,
2368 		    sdev->ppr, sdev->inquiry_len));
2369 
2370 	vdevice->configured_lun = 1;
2371 
2372 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2373 		"Queue depth=%d, tflags=%x\n",
2374 		ioc->name, sdev->queue_depth, vtarget->tflags));
2375 
2376 	if (ioc->bus_type == SPI)
2377 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2378 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2379 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2380 		    vtarget->minSyncFactor));
2381 
2382 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2383 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2384 		"tagged %d, simple %d\n",
2385 		ioc->name,sdev->tagged_supported, sdev->simple_tags));
2386 
2387 	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2388 
2389 	return 0;
2390 }
2391 
2392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2393 /*
2394  *  Private routines...
2395  */
2396 
2397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2398 /* Utility function to copy sense data from the scsi_cmnd buffer
2399  * to the FC and SCSI target structures.
2400  *
2401  */
2402 static void
2403 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2404 {
2405 	VirtDevice	*vdevice;
2406 	SCSIIORequest_t	*pReq;
2407 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2408 	MPT_ADAPTER 	*ioc = hd->ioc;
2409 
2410 	/* Get target structure
2411 	 */
2412 	pReq = (SCSIIORequest_t *) mf;
2413 	vdevice = sc->device->hostdata;
2414 
2415 	if (sense_count) {
2416 		u8 *sense_data;
2417 		int req_index;
2418 
2419 		/* Copy the sense received into the scsi command block. */
2420 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2421 		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2422 		memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
2423 
2424 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2425 		 */
2426 		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2427 			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2428 				int idx;
2429 
2430 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2431 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2432 				ioc->events[idx].eventContext = ioc->eventContext;
2433 
2434 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2435 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2436 					(sc->device->channel << 8) | sc->device->id;
2437 
2438 				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2439 
2440 				ioc->eventContext++;
2441 				if (ioc->pcidev->vendor ==
2442 				    PCI_VENDOR_ID_IBM) {
2443 					mptscsih_issue_sep_command(ioc,
2444 					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2445 					vdevice->vtarget->tflags |=
2446 					    MPT_TARGET_FLAGS_LED_ON;
2447 				}
2448 			}
2449 		}
2450 	} else {
2451 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2452 				ioc->name));
2453 	}
2454 }
2455 
2456 /**
2457  * mptscsih_get_scsi_lookup - retrieves scmd entry
2458  * @ioc: Pointer to MPT_ADAPTER structure
2459  * @i: index into the array
2460  *
2461  * Returns the scsi_cmd pointer
2462  */
2463 struct scsi_cmnd *
2464 mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2465 {
2466 	unsigned long	flags;
2467 	struct scsi_cmnd *scmd;
2468 
2469 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2470 	scmd = ioc->ScsiLookup[i];
2471 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2472 
2473 	return scmd;
2474 }
2475 EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2476 
2477 /**
2478  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2479  * @ioc: Pointer to MPT_ADAPTER structure
2480  * @i: index into the array
2481  *
2482  * Returns the scsi_cmd pointer
2483  *
2484  **/
2485 static struct scsi_cmnd *
2486 mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2487 {
2488 	unsigned long	flags;
2489 	struct scsi_cmnd *scmd;
2490 
2491 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2492 	scmd = ioc->ScsiLookup[i];
2493 	ioc->ScsiLookup[i] = NULL;
2494 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2495 
2496 	return scmd;
2497 }
2498 
2499 /**
2500  * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2501  *
2502  * @ioc: Pointer to MPT_ADAPTER structure
2503  * @i: index into the array
2504  * @scmd: scsi_cmnd pointer
2505  *
2506  **/
2507 static void
2508 mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2509 {
2510 	unsigned long	flags;
2511 
2512 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2513 	ioc->ScsiLookup[i] = scmd;
2514 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2515 }
2516 
2517 /**
2518  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2519  * @ioc: Pointer to MPT_ADAPTER structure
2520  * @sc: scsi_cmnd pointer
2521  */
2522 static int
2523 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2524 {
2525 	unsigned long	flags;
2526 	int i, index=-1;
2527 
2528 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2529 	for (i = 0; i < ioc->req_depth; i++) {
2530 		if (ioc->ScsiLookup[i] == sc) {
2531 			index = i;
2532 			goto out;
2533 		}
2534 	}
2535 
2536  out:
2537 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2538 	return index;
2539 }
2540 
2541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2542 int
2543 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2544 {
2545 	MPT_SCSI_HOST	*hd;
2546 
2547 	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2548 		return 0;
2549 
2550 	hd = shost_priv(ioc->sh);
2551 	switch (reset_phase) {
2552 	case MPT_IOC_SETUP_RESET:
2553 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2554 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2555 		break;
2556 	case MPT_IOC_PRE_RESET:
2557 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2558 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2559 		mptscsih_flush_running_cmds(hd);
2560 		break;
2561 	case MPT_IOC_POST_RESET:
2562 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2563 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2564 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2565 			ioc->internal_cmds.status |=
2566 				MPT_MGMT_STATUS_DID_IOCRESET;
2567 			complete(&ioc->internal_cmds.done);
2568 		}
2569 		break;
2570 	default:
2571 		break;
2572 	}
2573 	return 1;		/* currently means nothing really */
2574 }
2575 
2576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2577 int
2578 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2579 {
2580 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2581 
2582 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2583 		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2584 		ioc->name, event));
2585 
2586 	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2587 	    event == MPI_EVENT_EXT_BUS_RESET) &&
2588 	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2589 			ioc->soft_resets++;
2590 
2591 	return 1;		/* currently means nothing really */
2592 }
2593 
2594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2595 /*
2596  *  Bus Scan and Domain Validation functionality ...
2597  */
2598 
2599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2600 /*
2601  *	mptscsih_scandv_complete - Scan and DV callback routine registered
2602  *	to Fustion MPT (base) driver.
2603  *
2604  *	@ioc: Pointer to MPT_ADAPTER structure
2605  *	@mf: Pointer to original MPT request frame
2606  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2607  *
2608  *	This routine is called from mpt.c::mpt_interrupt() at the completion
2609  *	of any SCSI IO request.
2610  *	This routine is registered with the Fusion MPT (base) driver at driver
2611  *	load/init time via the mpt_register() API call.
2612  *
2613  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2614  *
2615  *	Remark: Sets a completion code and (possibly) saves sense data
2616  *	in the IOC member localReply structure.
2617  *	Used ONLY for DV and other internal commands.
2618  */
2619 int
2620 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2621 				MPT_FRAME_HDR *reply)
2622 {
2623 	SCSIIORequest_t *pReq;
2624 	SCSIIOReply_t	*pReply;
2625 	u8		 cmd;
2626 	u16		 req_idx;
2627 	u8	*sense_data;
2628 	int		 sz;
2629 
2630 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2631 	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2632 	if (!reply)
2633 		goto out;
2634 
2635 	pReply = (SCSIIOReply_t *) reply;
2636 	pReq = (SCSIIORequest_t *) req;
2637 	ioc->internal_cmds.completion_code =
2638 	    mptscsih_get_completion_code(ioc, req, reply);
2639 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2640 	memcpy(ioc->internal_cmds.reply, reply,
2641 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2642 	cmd = reply->u.hdr.Function;
2643 	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2644 	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2645 	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2646 		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2647 		sense_data = ((u8 *)ioc->sense_buf_pool +
2648 		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2649 		sz = min_t(int, pReq->SenseBufferLength,
2650 		    MPT_SENSE_BUFFER_ALLOC);
2651 		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2652 	}
2653  out:
2654 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2655 		return 0;
2656 	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2657 	complete(&ioc->internal_cmds.done);
2658 	return 1;
2659 }
2660 
2661 
2662 /**
2663  *	mptscsih_get_completion_code - get completion code from MPT request
2664  *	@ioc: Pointer to MPT_ADAPTER structure
2665  *	@req: Pointer to original MPT request frame
2666  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2667  *
2668  **/
2669 static int
2670 mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2671 				MPT_FRAME_HDR *reply)
2672 {
2673 	SCSIIOReply_t	*pReply;
2674 	MpiRaidActionReply_t *pr;
2675 	u8		 scsi_status;
2676 	u16		 status;
2677 	int		 completion_code;
2678 
2679 	pReply = (SCSIIOReply_t *)reply;
2680 	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2681 	scsi_status = pReply->SCSIStatus;
2682 
2683 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2684 	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2685 	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2686 	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2687 
2688 	switch (status) {
2689 
2690 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2691 		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2692 		break;
2693 
2694 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2695 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2696 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2697 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2698 		completion_code = MPT_SCANDV_DID_RESET;
2699 		break;
2700 
2701 	case MPI_IOCSTATUS_BUSY:
2702 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2703 		completion_code = MPT_SCANDV_BUSY;
2704 		break;
2705 
2706 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2707 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2708 	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2709 		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2710 			completion_code = MPT_SCANDV_GOOD;
2711 		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2712 			pr = (MpiRaidActionReply_t *)reply;
2713 			if (le16_to_cpu(pr->ActionStatus) ==
2714 				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2715 				completion_code = MPT_SCANDV_GOOD;
2716 			else
2717 				completion_code = MPT_SCANDV_SOME_ERROR;
2718 		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2719 			completion_code = MPT_SCANDV_SENSE;
2720 		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2721 			if (req->u.scsireq.CDB[0] == INQUIRY)
2722 				completion_code = MPT_SCANDV_ISSUE_SENSE;
2723 			else
2724 				completion_code = MPT_SCANDV_DID_RESET;
2725 		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2726 			completion_code = MPT_SCANDV_DID_RESET;
2727 		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2728 			completion_code = MPT_SCANDV_DID_RESET;
2729 		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2730 			completion_code = MPT_SCANDV_BUSY;
2731 		else
2732 			completion_code = MPT_SCANDV_GOOD;
2733 		break;
2734 
2735 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2736 		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2737 			completion_code = MPT_SCANDV_DID_RESET;
2738 		else
2739 			completion_code = MPT_SCANDV_SOME_ERROR;
2740 		break;
2741 	default:
2742 		completion_code = MPT_SCANDV_SOME_ERROR;
2743 		break;
2744 
2745 	}	/* switch(status) */
2746 
2747 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2748 	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2749 	return completion_code;
2750 }
2751 
2752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2753 /**
2754  *	mptscsih_do_cmd - Do internal command.
2755  *	@hd: MPT_SCSI_HOST pointer
2756  *	@io: INTERNAL_CMD pointer.
2757  *
2758  *	Issue the specified internally generated command and do command
2759  *	specific cleanup. For bus scan / DV only.
2760  *	NOTES: If command is Inquiry and status is good,
2761  *	initialize a target structure, save the data
2762  *
2763  *	Remark: Single threaded access only.
2764  *
2765  *	Return:
2766  *		< 0 if an illegal command or no resources
2767  *
2768  *		   0 if good
2769  *
2770  *		 > 0 if command complete but some type of completion error.
2771  */
2772 static int
2773 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2774 {
2775 	MPT_FRAME_HDR	*mf;
2776 	SCSIIORequest_t	*pScsiReq;
2777 	int		 my_idx, ii, dir;
2778 	int		 timeout;
2779 	char		 cmdLen;
2780 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2781 	u8		 cmd = io->cmd;
2782 	MPT_ADAPTER *ioc = hd->ioc;
2783 	int		 ret = 0;
2784 	unsigned long	 timeleft;
2785 	unsigned long	 flags;
2786 
2787 	/* don't send internal command during diag reset */
2788 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2789 	if (ioc->ioc_reset_in_progress) {
2790 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2791 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2792 			"%s: busy with host reset\n", ioc->name, __func__));
2793 		return MPT_SCANDV_BUSY;
2794 	}
2795 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2796 
2797 	mutex_lock(&ioc->internal_cmds.mutex);
2798 
2799 	/* Set command specific information
2800 	 */
2801 	switch (cmd) {
2802 	case INQUIRY:
2803 		cmdLen = 6;
2804 		dir = MPI_SCSIIO_CONTROL_READ;
2805 		CDB[0] = cmd;
2806 		CDB[4] = io->size;
2807 		timeout = 10;
2808 		break;
2809 
2810 	case TEST_UNIT_READY:
2811 		cmdLen = 6;
2812 		dir = MPI_SCSIIO_CONTROL_READ;
2813 		timeout = 10;
2814 		break;
2815 
2816 	case START_STOP:
2817 		cmdLen = 6;
2818 		dir = MPI_SCSIIO_CONTROL_READ;
2819 		CDB[0] = cmd;
2820 		CDB[4] = 1;	/*Spin up the disk */
2821 		timeout = 15;
2822 		break;
2823 
2824 	case REQUEST_SENSE:
2825 		cmdLen = 6;
2826 		CDB[0] = cmd;
2827 		CDB[4] = io->size;
2828 		dir = MPI_SCSIIO_CONTROL_READ;
2829 		timeout = 10;
2830 		break;
2831 
2832 	case READ_BUFFER:
2833 		cmdLen = 10;
2834 		dir = MPI_SCSIIO_CONTROL_READ;
2835 		CDB[0] = cmd;
2836 		if (io->flags & MPT_ICFLAG_ECHO) {
2837 			CDB[1] = 0x0A;
2838 		} else {
2839 			CDB[1] = 0x02;
2840 		}
2841 
2842 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2843 			CDB[1] |= 0x01;
2844 		}
2845 		CDB[6] = (io->size >> 16) & 0xFF;
2846 		CDB[7] = (io->size >>  8) & 0xFF;
2847 		CDB[8] = io->size & 0xFF;
2848 		timeout = 10;
2849 		break;
2850 
2851 	case WRITE_BUFFER:
2852 		cmdLen = 10;
2853 		dir = MPI_SCSIIO_CONTROL_WRITE;
2854 		CDB[0] = cmd;
2855 		if (io->flags & MPT_ICFLAG_ECHO) {
2856 			CDB[1] = 0x0A;
2857 		} else {
2858 			CDB[1] = 0x02;
2859 		}
2860 		CDB[6] = (io->size >> 16) & 0xFF;
2861 		CDB[7] = (io->size >>  8) & 0xFF;
2862 		CDB[8] = io->size & 0xFF;
2863 		timeout = 10;
2864 		break;
2865 
2866 	case RESERVE:
2867 		cmdLen = 6;
2868 		dir = MPI_SCSIIO_CONTROL_READ;
2869 		CDB[0] = cmd;
2870 		timeout = 10;
2871 		break;
2872 
2873 	case RELEASE:
2874 		cmdLen = 6;
2875 		dir = MPI_SCSIIO_CONTROL_READ;
2876 		CDB[0] = cmd;
2877 		timeout = 10;
2878 		break;
2879 
2880 	case SYNCHRONIZE_CACHE:
2881 		cmdLen = 10;
2882 		dir = MPI_SCSIIO_CONTROL_READ;
2883 		CDB[0] = cmd;
2884 //		CDB[1] = 0x02;	/* set immediate bit */
2885 		timeout = 10;
2886 		break;
2887 
2888 	default:
2889 		/* Error Case */
2890 		ret = -EFAULT;
2891 		goto out;
2892 	}
2893 
2894 	/* Get and Populate a free Frame
2895 	 * MsgContext set in mpt_get_msg_frame call
2896 	 */
2897 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2898 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2899 		    ioc->name, __func__));
2900 		ret = MPT_SCANDV_BUSY;
2901 		goto out;
2902 	}
2903 
2904 	pScsiReq = (SCSIIORequest_t *) mf;
2905 
2906 	/* Get the request index */
2907 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2908 	ADD_INDEX_LOG(my_idx); /* for debug */
2909 
2910 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2911 		pScsiReq->TargetID = io->physDiskNum;
2912 		pScsiReq->Bus = 0;
2913 		pScsiReq->ChainOffset = 0;
2914 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2915 	} else {
2916 		pScsiReq->TargetID = io->id;
2917 		pScsiReq->Bus = io->channel;
2918 		pScsiReq->ChainOffset = 0;
2919 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2920 	}
2921 
2922 	pScsiReq->CDBLength = cmdLen;
2923 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2924 
2925 	pScsiReq->Reserved = 0;
2926 
2927 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2928 	/* MsgContext set in mpt_get_msg_fram call  */
2929 
2930 	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2931 
2932 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2933 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2934 	else
2935 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2936 
2937 	if (cmd == REQUEST_SENSE) {
2938 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2939 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2940 		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2941 	}
2942 
2943 	for (ii = 0; ii < 16; ii++)
2944 		pScsiReq->CDB[ii] = CDB[ii];
2945 
2946 	pScsiReq->DataLength = cpu_to_le32(io->size);
2947 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2948 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2949 
2950 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2951 	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2952 	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2953 
2954 	if (dir == MPI_SCSIIO_CONTROL_READ)
2955 		ioc->add_sge((char *) &pScsiReq->SGL,
2956 		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2957 	else
2958 		ioc->add_sge((char *) &pScsiReq->SGL,
2959 		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2960 
2961 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2962 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2963 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2964 	    timeout*HZ);
2965 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2966 		ret = MPT_SCANDV_DID_RESET;
2967 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2968 		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2969 		    cmd));
2970 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2971 			mpt_free_msg_frame(ioc, mf);
2972 			goto out;
2973 		}
2974 		if (!timeleft) {
2975 			printk(MYIOC_s_WARN_FMT
2976 			       "Issuing Reset from %s!! doorbell=0x%08xh"
2977 			       " cmd=0x%02x\n",
2978 			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
2979 			       cmd);
2980 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2981 			mpt_free_msg_frame(ioc, mf);
2982 		}
2983 		goto out;
2984 	}
2985 
2986 	ret = ioc->internal_cmds.completion_code;
2987 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2988 			ioc->name, __func__, ret));
2989 
2990  out:
2991 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2992 	mutex_unlock(&ioc->internal_cmds.mutex);
2993 	return ret;
2994 }
2995 
2996 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2997 /**
2998  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
2999  *	@hd: Pointer to a SCSI HOST structure
3000  *	@vdevice: virtual target device
3001  *
3002  *	Uses the ISR, but with special processing.
3003  *	MUST be single-threaded.
3004  *
3005  */
3006 static void
3007 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3008 {
3009 	INTERNAL_CMD		 iocmd;
3010 
3011 	/* Ignore hidden raid components, this is handled when the command
3012 	 * is sent to the volume
3013 	 */
3014 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3015 		return;
3016 
3017 	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3018 	    !vdevice->configured_lun)
3019 		return;
3020 
3021 	/* Following parameters will not change
3022 	 * in this routine.
3023 	 */
3024 	iocmd.cmd = SYNCHRONIZE_CACHE;
3025 	iocmd.flags = 0;
3026 	iocmd.physDiskNum = -1;
3027 	iocmd.data = NULL;
3028 	iocmd.data_dma = -1;
3029 	iocmd.size = 0;
3030 	iocmd.rsvd = iocmd.rsvd2 = 0;
3031 	iocmd.channel = vdevice->vtarget->channel;
3032 	iocmd.id = vdevice->vtarget->id;
3033 	iocmd.lun = vdevice->lun;
3034 
3035 	mptscsih_do_cmd(hd, &iocmd);
3036 }
3037 
3038 static ssize_t
3039 mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3040 			 char *buf)
3041 {
3042 	struct Scsi_Host *host = class_to_shost(dev);
3043 	MPT_SCSI_HOST	*hd = shost_priv(host);
3044 	MPT_ADAPTER *ioc = hd->ioc;
3045 
3046 	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3047 	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3048 	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3049 	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3050 	    ioc->facts.FWVersion.Word & 0x000000FF);
3051 }
3052 static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3053 
3054 static ssize_t
3055 mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3056 			   char *buf)
3057 {
3058 	struct Scsi_Host *host = class_to_shost(dev);
3059 	MPT_SCSI_HOST	*hd = shost_priv(host);
3060 	MPT_ADAPTER *ioc = hd->ioc;
3061 
3062 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3063 	    (ioc->biosVersion & 0xFF000000) >> 24,
3064 	    (ioc->biosVersion & 0x00FF0000) >> 16,
3065 	    (ioc->biosVersion & 0x0000FF00) >> 8,
3066 	    ioc->biosVersion & 0x000000FF);
3067 }
3068 static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3069 
3070 static ssize_t
3071 mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3072 			  char *buf)
3073 {
3074 	struct Scsi_Host *host = class_to_shost(dev);
3075 	MPT_SCSI_HOST	*hd = shost_priv(host);
3076 	MPT_ADAPTER *ioc = hd->ioc;
3077 
3078 	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3079 }
3080 static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3081 
3082 static ssize_t
3083 mptscsih_version_product_show(struct device *dev,
3084 			      struct device_attribute *attr,
3085 char *buf)
3086 {
3087 	struct Scsi_Host *host = class_to_shost(dev);
3088 	MPT_SCSI_HOST	*hd = shost_priv(host);
3089 	MPT_ADAPTER *ioc = hd->ioc;
3090 
3091 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3092 }
3093 static DEVICE_ATTR(version_product, S_IRUGO,
3094     mptscsih_version_product_show, NULL);
3095 
3096 static ssize_t
3097 mptscsih_version_nvdata_persistent_show(struct device *dev,
3098 					struct device_attribute *attr,
3099 					char *buf)
3100 {
3101 	struct Scsi_Host *host = class_to_shost(dev);
3102 	MPT_SCSI_HOST	*hd = shost_priv(host);
3103 	MPT_ADAPTER *ioc = hd->ioc;
3104 
3105 	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3106 	    ioc->nvdata_version_persistent);
3107 }
3108 static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3109     mptscsih_version_nvdata_persistent_show, NULL);
3110 
3111 static ssize_t
3112 mptscsih_version_nvdata_default_show(struct device *dev,
3113 				     struct device_attribute *attr, char *buf)
3114 {
3115 	struct Scsi_Host *host = class_to_shost(dev);
3116 	MPT_SCSI_HOST	*hd = shost_priv(host);
3117 	MPT_ADAPTER *ioc = hd->ioc;
3118 
3119 	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3120 }
3121 static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3122     mptscsih_version_nvdata_default_show, NULL);
3123 
3124 static ssize_t
3125 mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3126 			 char *buf)
3127 {
3128 	struct Scsi_Host *host = class_to_shost(dev);
3129 	MPT_SCSI_HOST	*hd = shost_priv(host);
3130 	MPT_ADAPTER *ioc = hd->ioc;
3131 
3132 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3133 }
3134 static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3135 
3136 static ssize_t
3137 mptscsih_board_assembly_show(struct device *dev,
3138 			     struct device_attribute *attr, char *buf)
3139 {
3140 	struct Scsi_Host *host = class_to_shost(dev);
3141 	MPT_SCSI_HOST	*hd = shost_priv(host);
3142 	MPT_ADAPTER *ioc = hd->ioc;
3143 
3144 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3145 }
3146 static DEVICE_ATTR(board_assembly, S_IRUGO,
3147     mptscsih_board_assembly_show, NULL);
3148 
3149 static ssize_t
3150 mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3151 			   char *buf)
3152 {
3153 	struct Scsi_Host *host = class_to_shost(dev);
3154 	MPT_SCSI_HOST	*hd = shost_priv(host);
3155 	MPT_ADAPTER *ioc = hd->ioc;
3156 
3157 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3158 }
3159 static DEVICE_ATTR(board_tracer, S_IRUGO,
3160     mptscsih_board_tracer_show, NULL);
3161 
3162 static ssize_t
3163 mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3164 		       char *buf)
3165 {
3166 	struct Scsi_Host *host = class_to_shost(dev);
3167 	MPT_SCSI_HOST	*hd = shost_priv(host);
3168 	MPT_ADAPTER *ioc = hd->ioc;
3169 
3170 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3171 }
3172 static DEVICE_ATTR(io_delay, S_IRUGO,
3173     mptscsih_io_delay_show, NULL);
3174 
3175 static ssize_t
3176 mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3177 			   char *buf)
3178 {
3179 	struct Scsi_Host *host = class_to_shost(dev);
3180 	MPT_SCSI_HOST	*hd = shost_priv(host);
3181 	MPT_ADAPTER *ioc = hd->ioc;
3182 
3183 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3184 }
3185 static DEVICE_ATTR(device_delay, S_IRUGO,
3186     mptscsih_device_delay_show, NULL);
3187 
3188 static ssize_t
3189 mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3190 			  char *buf)
3191 {
3192 	struct Scsi_Host *host = class_to_shost(dev);
3193 	MPT_SCSI_HOST	*hd = shost_priv(host);
3194 	MPT_ADAPTER *ioc = hd->ioc;
3195 
3196 	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3197 }
3198 static ssize_t
3199 mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3200 			   const char *buf, size_t count)
3201 {
3202 	struct Scsi_Host *host = class_to_shost(dev);
3203 	MPT_SCSI_HOST	*hd = shost_priv(host);
3204 	MPT_ADAPTER *ioc = hd->ioc;
3205 	int val = 0;
3206 
3207 	if (sscanf(buf, "%x", &val) != 1)
3208 		return -EINVAL;
3209 
3210 	ioc->debug_level = val;
3211 	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3212 				ioc->name, ioc->debug_level);
3213 	return strlen(buf);
3214 }
3215 static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3216 	mptscsih_debug_level_show, mptscsih_debug_level_store);
3217 
3218 struct device_attribute *mptscsih_host_attrs[] = {
3219 	&dev_attr_version_fw,
3220 	&dev_attr_version_bios,
3221 	&dev_attr_version_mpi,
3222 	&dev_attr_version_product,
3223 	&dev_attr_version_nvdata_persistent,
3224 	&dev_attr_version_nvdata_default,
3225 	&dev_attr_board_name,
3226 	&dev_attr_board_assembly,
3227 	&dev_attr_board_tracer,
3228 	&dev_attr_io_delay,
3229 	&dev_attr_device_delay,
3230 	&dev_attr_debug_level,
3231 	NULL,
3232 };
3233 
3234 EXPORT_SYMBOL(mptscsih_host_attrs);
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_slave_destroy);
3246 EXPORT_SYMBOL(mptscsih_slave_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