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 			/* Fall through */
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 			/* Fall through */
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 	unsigned long	 timeleft;
1520 	u8		 issue_hard_reset;
1521 	u32		 ioc_raw_state;
1522 	unsigned long	 time_count;
1523 
1524 	issue_hard_reset = 0;
1525 	ioc_raw_state = mpt_GetIocState(ioc, 0);
1526 
1527 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1528 		printk(MYIOC_s_WARN_FMT
1529 			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1530 			ioc->name, type, ioc_raw_state);
1531 		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1532 		    ioc->name, __func__);
1533 		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1534 			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1535 			    "FAILED!!\n", ioc->name);
1536 		return 0;
1537 	}
1538 
1539 	/* DOORBELL ACTIVE check is not required if
1540 	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1541 	*/
1542 
1543 	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1544 		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1545 		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1546 		printk(MYIOC_s_WARN_FMT
1547 			"TaskMgmt type=%x: ioc_state: "
1548 			"DOORBELL_ACTIVE (0x%x)!\n",
1549 			ioc->name, type, ioc_raw_state);
1550 		return FAILED;
1551 	}
1552 
1553 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1554 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1555 		mf = NULL;
1556 		retval = FAILED;
1557 		goto out;
1558 	}
1559 
1560 	/* Return Fail to calling function if no message frames available.
1561 	 */
1562 	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1563 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1564 			"TaskMgmt no msg frames!!\n", ioc->name));
1565 		retval = FAILED;
1566 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1567 		goto out;
1568 	}
1569 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1570 			ioc->name, mf));
1571 
1572 	/* Format the Request
1573 	 */
1574 	pScsiTm = (SCSITaskMgmt_t *) mf;
1575 	pScsiTm->TargetID = id;
1576 	pScsiTm->Bus = channel;
1577 	pScsiTm->ChainOffset = 0;
1578 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1579 
1580 	pScsiTm->Reserved = 0;
1581 	pScsiTm->TaskType = type;
1582 	pScsiTm->Reserved1 = 0;
1583 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1584                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1585 
1586 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1587 
1588 	for (ii=0; ii < 7; ii++)
1589 		pScsiTm->Reserved2[ii] = 0;
1590 
1591 	pScsiTm->TaskMsgContext = ctx2abort;
1592 
1593 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1594 		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1595 		type, timeout));
1596 
1597 	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1598 
1599 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1600 	time_count = jiffies;
1601 	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1602 	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1603 		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1604 	else {
1605 		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1606 			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1607 		if (retval) {
1608 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1609 				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1610 				ioc->name, mf, retval));
1611 			mpt_free_msg_frame(ioc, mf);
1612 			mpt_clear_taskmgmt_in_progress_flag(ioc);
1613 			goto out;
1614 		}
1615 	}
1616 
1617 	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1618 		timeout*HZ);
1619 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1620 		retval = FAILED;
1621 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1622 		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1623 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1624 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1625 			goto out;
1626 		issue_hard_reset = 1;
1627 		goto out;
1628 	}
1629 
1630 	retval = mptscsih_taskmgmt_reply(ioc, type,
1631 	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1632 
1633 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1634 	    "TaskMgmt completed (%d seconds)\n",
1635 	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1636 
1637  out:
1638 
1639 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1640 	if (issue_hard_reset) {
1641 		printk(MYIOC_s_WARN_FMT
1642 		       "Issuing Reset from %s!! doorbell=0x%08x\n",
1643 		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
1644 		retval = (ioc->bus_type == SAS) ?
1645 			mpt_HardResetHandler(ioc, CAN_SLEEP) :
1646 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1647 		mpt_free_msg_frame(ioc, mf);
1648 	}
1649 
1650 	retval = (retval == 0) ? 0 : FAILED;
1651 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1652 	return retval;
1653 }
1654 EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1655 
1656 static int
1657 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1658 {
1659 	switch (ioc->bus_type) {
1660 	case FC:
1661 		return 40;
1662 	case SAS:
1663 		return 30;
1664 	case SPI:
1665 	default:
1666 		return 10;
1667 	}
1668 }
1669 
1670 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1671 /**
1672  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1673  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1674  *
1675  *	(linux scsi_host_template.eh_abort_handler routine)
1676  *
1677  *	Returns SUCCESS or FAILED.
1678  **/
1679 int
1680 mptscsih_abort(struct scsi_cmnd * SCpnt)
1681 {
1682 	MPT_SCSI_HOST	*hd;
1683 	MPT_FRAME_HDR	*mf;
1684 	u32		 ctx2abort;
1685 	int		 scpnt_idx;
1686 	int		 retval;
1687 	VirtDevice	 *vdevice;
1688 	MPT_ADAPTER	*ioc;
1689 
1690 	/* If we can't locate our host adapter structure, return FAILED status.
1691 	 */
1692 	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1693 		SCpnt->result = DID_RESET << 16;
1694 		SCpnt->scsi_done(SCpnt);
1695 		printk(KERN_ERR MYNAM ": task abort: "
1696 		    "can't locate host! (sc=%p)\n", SCpnt);
1697 		return FAILED;
1698 	}
1699 
1700 	ioc = hd->ioc;
1701 	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1702 	       ioc->name, SCpnt);
1703 	scsi_print_command(SCpnt);
1704 
1705 	vdevice = SCpnt->device->hostdata;
1706 	if (!vdevice || !vdevice->vtarget) {
1707 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1708 		    "task abort: device has been deleted (sc=%p)\n",
1709 		    ioc->name, SCpnt));
1710 		SCpnt->result = DID_NO_CONNECT << 16;
1711 		SCpnt->scsi_done(SCpnt);
1712 		retval = SUCCESS;
1713 		goto out;
1714 	}
1715 
1716 	/* Task aborts are not supported for hidden raid components.
1717 	 */
1718 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1719 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1720 		    "task abort: hidden raid component (sc=%p)\n",
1721 		    ioc->name, SCpnt));
1722 		SCpnt->result = DID_RESET << 16;
1723 		retval = FAILED;
1724 		goto out;
1725 	}
1726 
1727 	/* Task aborts are not supported for volumes.
1728 	 */
1729 	if (vdevice->vtarget->raidVolume) {
1730 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1731 		    "task abort: raid volume (sc=%p)\n",
1732 		    ioc->name, SCpnt));
1733 		SCpnt->result = DID_RESET << 16;
1734 		retval = FAILED;
1735 		goto out;
1736 	}
1737 
1738 	/* Find this command
1739 	 */
1740 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1741 		/* Cmd not found in ScsiLookup.
1742 		 * Do OS callback.
1743 		 */
1744 		SCpnt->result = DID_RESET << 16;
1745 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1746 		   "Command not in the active list! (sc=%p)\n", ioc->name,
1747 		   SCpnt));
1748 		retval = SUCCESS;
1749 		goto out;
1750 	}
1751 
1752 	if (ioc->timeouts < -1)
1753 		ioc->timeouts++;
1754 
1755 	if (mpt_fwfault_debug)
1756 		mpt_halt_firmware(ioc);
1757 
1758 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1759 	 * (the IO to be ABORT'd)
1760 	 *
1761 	 * NOTE: Since we do not byteswap MsgContext, we do not
1762 	 *	 swap it here either.  It is an opaque cookie to
1763 	 *	 the controller, so it does not matter. -DaveM
1764 	 */
1765 	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1766 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1767 	retval = mptscsih_IssueTaskMgmt(hd,
1768 			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1769 			 vdevice->vtarget->channel,
1770 			 vdevice->vtarget->id, vdevice->lun,
1771 			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1772 
1773 	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
1774 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1775 		    "task abort: command still in active list! (sc=%p)\n",
1776 		    ioc->name, SCpnt));
1777 		retval = FAILED;
1778 	} else {
1779 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1780 		    "task abort: command cleared from active list! (sc=%p)\n",
1781 		    ioc->name, SCpnt));
1782 		retval = SUCCESS;
1783 	}
1784 
1785  out:
1786 	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
1787 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
1788 	    SCpnt);
1789 
1790 	return retval;
1791 }
1792 
1793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1794 /**
1795  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1796  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1797  *
1798  *	(linux scsi_host_template.eh_dev_reset_handler routine)
1799  *
1800  *	Returns SUCCESS or FAILED.
1801  **/
1802 int
1803 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1804 {
1805 	MPT_SCSI_HOST	*hd;
1806 	int		 retval;
1807 	VirtDevice	 *vdevice;
1808 	MPT_ADAPTER	*ioc;
1809 
1810 	/* If we can't locate our host adapter structure, return FAILED status.
1811 	 */
1812 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1813 		printk(KERN_ERR MYNAM ": target reset: "
1814 		   "Can't locate host! (sc=%p)\n", SCpnt);
1815 		return FAILED;
1816 	}
1817 
1818 	ioc = hd->ioc;
1819 	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1820 	       ioc->name, SCpnt);
1821 	scsi_print_command(SCpnt);
1822 
1823 	vdevice = SCpnt->device->hostdata;
1824 	if (!vdevice || !vdevice->vtarget) {
1825 		retval = 0;
1826 		goto out;
1827 	}
1828 
1829 	/* Target reset to hidden raid component is not supported
1830 	 */
1831 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1832 		retval = FAILED;
1833 		goto out;
1834 	}
1835 
1836 	retval = mptscsih_IssueTaskMgmt(hd,
1837 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1838 				vdevice->vtarget->channel,
1839 				vdevice->vtarget->id, 0, 0,
1840 				mptscsih_get_tm_timeout(ioc));
1841 
1842  out:
1843 	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1844 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1845 
1846 	if (retval == 0)
1847 		return SUCCESS;
1848 	else
1849 		return FAILED;
1850 }
1851 
1852 
1853 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1854 /**
1855  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1856  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1857  *
1858  *	(linux scsi_host_template.eh_bus_reset_handler routine)
1859  *
1860  *	Returns SUCCESS or FAILED.
1861  **/
1862 int
1863 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1864 {
1865 	MPT_SCSI_HOST	*hd;
1866 	int		 retval;
1867 	VirtDevice	 *vdevice;
1868 	MPT_ADAPTER	*ioc;
1869 
1870 	/* If we can't locate our host adapter structure, return FAILED status.
1871 	 */
1872 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1873 		printk(KERN_ERR MYNAM ": bus reset: "
1874 		   "Can't locate host! (sc=%p)\n", SCpnt);
1875 		return FAILED;
1876 	}
1877 
1878 	ioc = hd->ioc;
1879 	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1880 	       ioc->name, SCpnt);
1881 	scsi_print_command(SCpnt);
1882 
1883 	if (ioc->timeouts < -1)
1884 		ioc->timeouts++;
1885 
1886 	vdevice = SCpnt->device->hostdata;
1887 	if (!vdevice || !vdevice->vtarget)
1888 		return SUCCESS;
1889 	retval = mptscsih_IssueTaskMgmt(hd,
1890 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1891 					vdevice->vtarget->channel, 0, 0, 0,
1892 					mptscsih_get_tm_timeout(ioc));
1893 
1894 	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1895 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1896 
1897 	if (retval == 0)
1898 		return SUCCESS;
1899 	else
1900 		return FAILED;
1901 }
1902 
1903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1904 /**
1905  *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1906  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1907  *
1908  *	(linux scsi_host_template.eh_host_reset_handler routine)
1909  *
1910  *	Returns SUCCESS or FAILED.
1911  */
1912 int
1913 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1914 {
1915 	MPT_SCSI_HOST *  hd;
1916 	int              status = SUCCESS;
1917 	MPT_ADAPTER	*ioc;
1918 	int		retval;
1919 
1920 	/*  If we can't locate the host to reset, then we failed. */
1921 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1922 		printk(KERN_ERR MYNAM ": host reset: "
1923 		    "Can't locate host! (sc=%p)\n", SCpnt);
1924 		return FAILED;
1925 	}
1926 
1927 	/* make sure we have no outstanding commands at this stage */
1928 	mptscsih_flush_running_cmds(hd);
1929 
1930 	ioc = hd->ioc;
1931 	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1932 	    ioc->name, SCpnt);
1933 
1934 	/*  If our attempts to reset the host failed, then return a failed
1935 	 *  status.  The host will be taken off line by the SCSI mid-layer.
1936 	 */
1937 	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1938 	if (retval < 0)
1939 		status = FAILED;
1940 	else
1941 		status = SUCCESS;
1942 
1943 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1944 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1945 
1946 	return status;
1947 }
1948 
1949 static int
1950 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1951 	SCSITaskMgmtReply_t *pScsiTmReply)
1952 {
1953 	u16			 iocstatus;
1954 	u32			 termination_count;
1955 	int			 retval;
1956 
1957 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1958 		retval = FAILED;
1959 		goto out;
1960 	}
1961 
1962 	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1963 
1964 	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1965 	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1966 
1967 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1968 	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1969 	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1970 	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1971 	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1972 	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1973 	    termination_count));
1974 
1975 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1976 	    pScsiTmReply->ResponseCode)
1977 		mptscsih_taskmgmt_response_code(ioc,
1978 		    pScsiTmReply->ResponseCode);
1979 
1980 	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1981 		retval = 0;
1982 		goto out;
1983 	}
1984 
1985 	retval = FAILED;
1986 	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1987 		if (termination_count == 1)
1988 			retval = 0;
1989 		goto out;
1990 	}
1991 
1992 	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1993 	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1994 		retval = 0;
1995 
1996  out:
1997 	return retval;
1998 }
1999 
2000 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2001 void
2002 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2003 {
2004 	char *desc;
2005 
2006 	switch (response_code) {
2007 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2008 		desc = "The task completed.";
2009 		break;
2010 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2011 		desc = "The IOC received an invalid frame status.";
2012 		break;
2013 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2014 		desc = "The task type is not supported.";
2015 		break;
2016 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2017 		desc = "The requested task failed.";
2018 		break;
2019 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2020 		desc = "The task completed successfully.";
2021 		break;
2022 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2023 		desc = "The LUN request is invalid.";
2024 		break;
2025 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2026 		desc = "The task is in the IOC queue and has not been sent to target.";
2027 		break;
2028 	default:
2029 		desc = "unknown";
2030 		break;
2031 	}
2032 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2033 		ioc->name, response_code, desc);
2034 }
2035 EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2036 
2037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2038 /**
2039  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2040  *	@ioc: Pointer to MPT_ADAPTER structure
2041  *	@mf: Pointer to SCSI task mgmt request frame
2042  *	@mr: Pointer to SCSI task mgmt reply frame
2043  *
2044  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2045  *	of any SCSI task management request.
2046  *	This routine is registered with the MPT (base) driver at driver
2047  *	load/init time via the mpt_register() API call.
2048  *
2049  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2050  **/
2051 int
2052 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2053 	MPT_FRAME_HDR *mr)
2054 {
2055 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2056 		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2057 
2058 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2059 
2060 	if (!mr)
2061 		goto out;
2062 
2063 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2064 	memcpy(ioc->taskmgmt_cmds.reply, mr,
2065 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2066  out:
2067 	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2068 		mpt_clear_taskmgmt_in_progress_flag(ioc);
2069 		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2070 		complete(&ioc->taskmgmt_cmds.done);
2071 		if (ioc->bus_type == SAS)
2072 			ioc->schedule_target_reset(ioc);
2073 		return 1;
2074 	}
2075 	return 0;
2076 }
2077 
2078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2079 /*
2080  *	This is anyones guess quite frankly.
2081  */
2082 int
2083 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2084 		sector_t capacity, int geom[])
2085 {
2086 	int		heads;
2087 	int		sectors;
2088 	sector_t	cylinders;
2089 	ulong 		dummy;
2090 
2091 	heads = 64;
2092 	sectors = 32;
2093 
2094 	dummy = heads * sectors;
2095 	cylinders = capacity;
2096 	sector_div(cylinders,dummy);
2097 
2098 	/*
2099 	 * Handle extended translation size for logical drives
2100 	 * > 1Gb
2101 	 */
2102 	if ((ulong)capacity >= 0x200000) {
2103 		heads = 255;
2104 		sectors = 63;
2105 		dummy = heads * sectors;
2106 		cylinders = capacity;
2107 		sector_div(cylinders,dummy);
2108 	}
2109 
2110 	/* return result */
2111 	geom[0] = heads;
2112 	geom[1] = sectors;
2113 	geom[2] = cylinders;
2114 
2115 	return 0;
2116 }
2117 
2118 /* Search IOC page 3 to determine if this is hidden physical disk
2119  *
2120  */
2121 int
2122 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2123 {
2124 	struct inactive_raid_component_info *component_info;
2125 	int i, j;
2126 	RaidPhysDiskPage1_t *phys_disk;
2127 	int rc = 0;
2128 	int num_paths;
2129 
2130 	if (!ioc->raid_data.pIocPg3)
2131 		goto out;
2132 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2133 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2134 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2135 			rc = 1;
2136 			goto out;
2137 		}
2138 	}
2139 
2140 	if (ioc->bus_type != SAS)
2141 		goto out;
2142 
2143 	/*
2144 	 * Check if dual path
2145 	 */
2146 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2147 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2148 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2149 		if (num_paths < 2)
2150 			continue;
2151 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2152 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2153 		if (!phys_disk)
2154 			continue;
2155 		if ((mpt_raid_phys_disk_pg1(ioc,
2156 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2157 		    phys_disk))) {
2158 			kfree(phys_disk);
2159 			continue;
2160 		}
2161 		for (j = 0; j < num_paths; j++) {
2162 			if ((phys_disk->Path[j].Flags &
2163 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2164 				continue;
2165 			if ((phys_disk->Path[j].Flags &
2166 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2167 				continue;
2168 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2169 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2170 				rc = 1;
2171 				kfree(phys_disk);
2172 				goto out;
2173 			}
2174 		}
2175 		kfree(phys_disk);
2176 	}
2177 
2178 
2179 	/*
2180 	 * Check inactive list for matching phys disks
2181 	 */
2182 	if (list_empty(&ioc->raid_data.inactive_list))
2183 		goto out;
2184 
2185 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2186 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2187 	    list) {
2188 		if ((component_info->d.PhysDiskID == id) &&
2189 		    (component_info->d.PhysDiskBus == channel))
2190 			rc = 1;
2191 	}
2192 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2193 
2194  out:
2195 	return rc;
2196 }
2197 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2198 
2199 u8
2200 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2201 {
2202 	struct inactive_raid_component_info *component_info;
2203 	int i, j;
2204 	RaidPhysDiskPage1_t *phys_disk;
2205 	int rc = -ENXIO;
2206 	int num_paths;
2207 
2208 	if (!ioc->raid_data.pIocPg3)
2209 		goto out;
2210 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2211 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2212 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2213 			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2214 			goto out;
2215 		}
2216 	}
2217 
2218 	if (ioc->bus_type != SAS)
2219 		goto out;
2220 
2221 	/*
2222 	 * Check if dual path
2223 	 */
2224 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2225 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2226 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2227 		if (num_paths < 2)
2228 			continue;
2229 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2230 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2231 		if (!phys_disk)
2232 			continue;
2233 		if ((mpt_raid_phys_disk_pg1(ioc,
2234 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2235 		    phys_disk))) {
2236 			kfree(phys_disk);
2237 			continue;
2238 		}
2239 		for (j = 0; j < num_paths; j++) {
2240 			if ((phys_disk->Path[j].Flags &
2241 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2242 				continue;
2243 			if ((phys_disk->Path[j].Flags &
2244 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2245 				continue;
2246 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2247 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2248 				rc = phys_disk->PhysDiskNum;
2249 				kfree(phys_disk);
2250 				goto out;
2251 			}
2252 		}
2253 		kfree(phys_disk);
2254 	}
2255 
2256 	/*
2257 	 * Check inactive list for matching phys disks
2258 	 */
2259 	if (list_empty(&ioc->raid_data.inactive_list))
2260 		goto out;
2261 
2262 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2263 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2264 	    list) {
2265 		if ((component_info->d.PhysDiskID == id) &&
2266 		    (component_info->d.PhysDiskBus == channel))
2267 			rc = component_info->d.PhysDiskNum;
2268 	}
2269 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2270 
2271  out:
2272 	return rc;
2273 }
2274 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2275 
2276 /*
2277  *	OS entry point to allow for host driver to free allocated memory
2278  *	Called if no device present or device being unloaded
2279  */
2280 void
2281 mptscsih_slave_destroy(struct scsi_device *sdev)
2282 {
2283 	struct Scsi_Host	*host = sdev->host;
2284 	MPT_SCSI_HOST		*hd = shost_priv(host);
2285 	VirtTarget		*vtarget;
2286 	VirtDevice		*vdevice;
2287 	struct scsi_target 	*starget;
2288 
2289 	starget = scsi_target(sdev);
2290 	vtarget = starget->hostdata;
2291 	vdevice = sdev->hostdata;
2292 	if (!vdevice)
2293 		return;
2294 
2295 	mptscsih_search_running_cmds(hd, vdevice);
2296 	vtarget->num_luns--;
2297 	mptscsih_synchronize_cache(hd, vdevice);
2298 	kfree(vdevice);
2299 	sdev->hostdata = NULL;
2300 }
2301 
2302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2303 /*
2304  *	mptscsih_change_queue_depth - This function will set a devices queue depth
2305  *	@sdev: per scsi_device pointer
2306  *	@qdepth: requested queue depth
2307  *
2308  *	Adding support for new 'change_queue_depth' api.
2309 */
2310 int
2311 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2312 {
2313 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2314 	VirtTarget 		*vtarget;
2315 	struct scsi_target 	*starget;
2316 	int			max_depth;
2317 	MPT_ADAPTER		*ioc = hd->ioc;
2318 
2319 	starget = scsi_target(sdev);
2320 	vtarget = starget->hostdata;
2321 
2322 	if (ioc->bus_type == SPI) {
2323 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2324 			max_depth = 1;
2325 		else if (sdev->type == TYPE_DISK &&
2326 			 vtarget->minSyncFactor <= MPT_ULTRA160)
2327 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2328 		else
2329 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2330 	} else
2331 		 max_depth = ioc->sh->can_queue;
2332 
2333 	if (!sdev->tagged_supported)
2334 		max_depth = 1;
2335 
2336 	if (qdepth > max_depth)
2337 		qdepth = max_depth;
2338 
2339 	return scsi_change_queue_depth(sdev, qdepth);
2340 }
2341 
2342 /*
2343  *	OS entry point to adjust the queue_depths on a per-device basis.
2344  *	Called once per device the bus scan. Use it to force the queue_depth
2345  *	member to 1 if a device does not support Q tags.
2346  *	Return non-zero if fails.
2347  */
2348 int
2349 mptscsih_slave_configure(struct scsi_device *sdev)
2350 {
2351 	struct Scsi_Host	*sh = sdev->host;
2352 	VirtTarget		*vtarget;
2353 	VirtDevice		*vdevice;
2354 	struct scsi_target 	*starget;
2355 	MPT_SCSI_HOST		*hd = shost_priv(sh);
2356 	MPT_ADAPTER		*ioc = hd->ioc;
2357 
2358 	starget = scsi_target(sdev);
2359 	vtarget = starget->hostdata;
2360 	vdevice = sdev->hostdata;
2361 
2362 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2363 		"device @ %p, channel=%d, id=%d, lun=%llu\n",
2364 		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2365 	if (ioc->bus_type == SPI)
2366 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2367 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2368 		    ioc->name, sdev->sdtr, sdev->wdtr,
2369 		    sdev->ppr, sdev->inquiry_len));
2370 
2371 	vdevice->configured_lun = 1;
2372 
2373 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2374 		"Queue depth=%d, tflags=%x\n",
2375 		ioc->name, sdev->queue_depth, vtarget->tflags));
2376 
2377 	if (ioc->bus_type == SPI)
2378 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2379 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2380 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2381 		    vtarget->minSyncFactor));
2382 
2383 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2384 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2385 		"tagged %d, simple %d\n",
2386 		ioc->name,sdev->tagged_supported, sdev->simple_tags));
2387 
2388 	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2389 
2390 	return 0;
2391 }
2392 
2393 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2394 /*
2395  *  Private routines...
2396  */
2397 
2398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2399 /* Utility function to copy sense data from the scsi_cmnd buffer
2400  * to the FC and SCSI target structures.
2401  *
2402  */
2403 static void
2404 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2405 {
2406 	VirtDevice	*vdevice;
2407 	SCSIIORequest_t	*pReq;
2408 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2409 	MPT_ADAPTER 	*ioc = hd->ioc;
2410 
2411 	/* Get target structure
2412 	 */
2413 	pReq = (SCSIIORequest_t *) mf;
2414 	vdevice = sc->device->hostdata;
2415 
2416 	if (sense_count) {
2417 		u8 *sense_data;
2418 		int req_index;
2419 
2420 		/* Copy the sense received into the scsi command block. */
2421 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2422 		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2423 		memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
2424 
2425 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2426 		 */
2427 		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2428 			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2429 				int idx;
2430 
2431 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2432 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2433 				ioc->events[idx].eventContext = ioc->eventContext;
2434 
2435 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2436 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2437 					(sc->device->channel << 8) | sc->device->id;
2438 
2439 				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2440 
2441 				ioc->eventContext++;
2442 				if (ioc->pcidev->vendor ==
2443 				    PCI_VENDOR_ID_IBM) {
2444 					mptscsih_issue_sep_command(ioc,
2445 					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2446 					vdevice->vtarget->tflags |=
2447 					    MPT_TARGET_FLAGS_LED_ON;
2448 				}
2449 			}
2450 		}
2451 	} else {
2452 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2453 				ioc->name));
2454 	}
2455 }
2456 
2457 /**
2458  * mptscsih_get_scsi_lookup - retrieves scmd entry
2459  * @ioc: Pointer to MPT_ADAPTER structure
2460  * @i: index into the array
2461  *
2462  * Returns the scsi_cmd pointer
2463  */
2464 struct scsi_cmnd *
2465 mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2466 {
2467 	unsigned long	flags;
2468 	struct scsi_cmnd *scmd;
2469 
2470 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2471 	scmd = ioc->ScsiLookup[i];
2472 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2473 
2474 	return scmd;
2475 }
2476 EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2477 
2478 /**
2479  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2480  * @ioc: Pointer to MPT_ADAPTER structure
2481  * @i: index into the array
2482  *
2483  * Returns the scsi_cmd pointer
2484  *
2485  **/
2486 static struct scsi_cmnd *
2487 mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2488 {
2489 	unsigned long	flags;
2490 	struct scsi_cmnd *scmd;
2491 
2492 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2493 	scmd = ioc->ScsiLookup[i];
2494 	ioc->ScsiLookup[i] = NULL;
2495 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2496 
2497 	return scmd;
2498 }
2499 
2500 /**
2501  * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2502  *
2503  * @ioc: Pointer to MPT_ADAPTER structure
2504  * @i: index into the array
2505  * @scmd: scsi_cmnd pointer
2506  *
2507  **/
2508 static void
2509 mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2510 {
2511 	unsigned long	flags;
2512 
2513 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2514 	ioc->ScsiLookup[i] = scmd;
2515 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2516 }
2517 
2518 /**
2519  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2520  * @ioc: Pointer to MPT_ADAPTER structure
2521  * @sc: scsi_cmnd pointer
2522  */
2523 static int
2524 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2525 {
2526 	unsigned long	flags;
2527 	int i, index=-1;
2528 
2529 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2530 	for (i = 0; i < ioc->req_depth; i++) {
2531 		if (ioc->ScsiLookup[i] == sc) {
2532 			index = i;
2533 			goto out;
2534 		}
2535 	}
2536 
2537  out:
2538 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2539 	return index;
2540 }
2541 
2542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2543 int
2544 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2545 {
2546 	MPT_SCSI_HOST	*hd;
2547 
2548 	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2549 		return 0;
2550 
2551 	hd = shost_priv(ioc->sh);
2552 	switch (reset_phase) {
2553 	case MPT_IOC_SETUP_RESET:
2554 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2555 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2556 		break;
2557 	case MPT_IOC_PRE_RESET:
2558 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2559 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2560 		mptscsih_flush_running_cmds(hd);
2561 		break;
2562 	case MPT_IOC_POST_RESET:
2563 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2564 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2565 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2566 			ioc->internal_cmds.status |=
2567 				MPT_MGMT_STATUS_DID_IOCRESET;
2568 			complete(&ioc->internal_cmds.done);
2569 		}
2570 		break;
2571 	default:
2572 		break;
2573 	}
2574 	return 1;		/* currently means nothing really */
2575 }
2576 
2577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2578 int
2579 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2580 {
2581 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2582 
2583 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2584 		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2585 		ioc->name, event));
2586 
2587 	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2588 	    event == MPI_EVENT_EXT_BUS_RESET) &&
2589 	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2590 			ioc->soft_resets++;
2591 
2592 	return 1;		/* currently means nothing really */
2593 }
2594 
2595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2596 /*
2597  *  Bus Scan and Domain Validation functionality ...
2598  */
2599 
2600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2601 /*
2602  *	mptscsih_scandv_complete - Scan and DV callback routine registered
2603  *	to Fustion MPT (base) driver.
2604  *
2605  *	@ioc: Pointer to MPT_ADAPTER structure
2606  *	@mf: Pointer to original MPT request frame
2607  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2608  *
2609  *	This routine is called from mpt.c::mpt_interrupt() at the completion
2610  *	of any SCSI IO request.
2611  *	This routine is registered with the Fusion MPT (base) driver at driver
2612  *	load/init time via the mpt_register() API call.
2613  *
2614  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2615  *
2616  *	Remark: Sets a completion code and (possibly) saves sense data
2617  *	in the IOC member localReply structure.
2618  *	Used ONLY for DV and other internal commands.
2619  */
2620 int
2621 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2622 				MPT_FRAME_HDR *reply)
2623 {
2624 	SCSIIORequest_t *pReq;
2625 	SCSIIOReply_t	*pReply;
2626 	u8		 cmd;
2627 	u16		 req_idx;
2628 	u8	*sense_data;
2629 	int		 sz;
2630 
2631 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2632 	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2633 	if (!reply)
2634 		goto out;
2635 
2636 	pReply = (SCSIIOReply_t *) reply;
2637 	pReq = (SCSIIORequest_t *) req;
2638 	ioc->internal_cmds.completion_code =
2639 	    mptscsih_get_completion_code(ioc, req, reply);
2640 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2641 	memcpy(ioc->internal_cmds.reply, reply,
2642 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2643 	cmd = reply->u.hdr.Function;
2644 	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2645 	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2646 	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2647 		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2648 		sense_data = ((u8 *)ioc->sense_buf_pool +
2649 		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2650 		sz = min_t(int, pReq->SenseBufferLength,
2651 		    MPT_SENSE_BUFFER_ALLOC);
2652 		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2653 	}
2654  out:
2655 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2656 		return 0;
2657 	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2658 	complete(&ioc->internal_cmds.done);
2659 	return 1;
2660 }
2661 
2662 
2663 /**
2664  *	mptscsih_get_completion_code - get completion code from MPT request
2665  *	@ioc: Pointer to MPT_ADAPTER structure
2666  *	@req: Pointer to original MPT request frame
2667  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2668  *
2669  **/
2670 static int
2671 mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2672 				MPT_FRAME_HDR *reply)
2673 {
2674 	SCSIIOReply_t	*pReply;
2675 	MpiRaidActionReply_t *pr;
2676 	u8		 scsi_status;
2677 	u16		 status;
2678 	int		 completion_code;
2679 
2680 	pReply = (SCSIIOReply_t *)reply;
2681 	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2682 	scsi_status = pReply->SCSIStatus;
2683 
2684 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2685 	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2686 	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2687 	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2688 
2689 	switch (status) {
2690 
2691 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2692 		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2693 		break;
2694 
2695 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2696 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2697 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2698 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2699 		completion_code = MPT_SCANDV_DID_RESET;
2700 		break;
2701 
2702 	case MPI_IOCSTATUS_BUSY:
2703 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2704 		completion_code = MPT_SCANDV_BUSY;
2705 		break;
2706 
2707 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2708 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2709 	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2710 		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2711 			completion_code = MPT_SCANDV_GOOD;
2712 		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2713 			pr = (MpiRaidActionReply_t *)reply;
2714 			if (le16_to_cpu(pr->ActionStatus) ==
2715 				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2716 				completion_code = MPT_SCANDV_GOOD;
2717 			else
2718 				completion_code = MPT_SCANDV_SOME_ERROR;
2719 		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2720 			completion_code = MPT_SCANDV_SENSE;
2721 		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2722 			if (req->u.scsireq.CDB[0] == INQUIRY)
2723 				completion_code = MPT_SCANDV_ISSUE_SENSE;
2724 			else
2725 				completion_code = MPT_SCANDV_DID_RESET;
2726 		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2727 			completion_code = MPT_SCANDV_DID_RESET;
2728 		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2729 			completion_code = MPT_SCANDV_DID_RESET;
2730 		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2731 			completion_code = MPT_SCANDV_BUSY;
2732 		else
2733 			completion_code = MPT_SCANDV_GOOD;
2734 		break;
2735 
2736 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2737 		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2738 			completion_code = MPT_SCANDV_DID_RESET;
2739 		else
2740 			completion_code = MPT_SCANDV_SOME_ERROR;
2741 		break;
2742 	default:
2743 		completion_code = MPT_SCANDV_SOME_ERROR;
2744 		break;
2745 
2746 	}	/* switch(status) */
2747 
2748 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2749 	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2750 	return completion_code;
2751 }
2752 
2753 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2754 /**
2755  *	mptscsih_do_cmd - Do internal command.
2756  *	@hd: MPT_SCSI_HOST pointer
2757  *	@io: INTERNAL_CMD pointer.
2758  *
2759  *	Issue the specified internally generated command and do command
2760  *	specific cleanup. For bus scan / DV only.
2761  *	NOTES: If command is Inquiry and status is good,
2762  *	initialize a target structure, save the data
2763  *
2764  *	Remark: Single threaded access only.
2765  *
2766  *	Return:
2767  *		< 0 if an illegal command or no resources
2768  *
2769  *		   0 if good
2770  *
2771  *		 > 0 if command complete but some type of completion error.
2772  */
2773 static int
2774 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2775 {
2776 	MPT_FRAME_HDR	*mf;
2777 	SCSIIORequest_t	*pScsiReq;
2778 	int		 my_idx, ii, dir;
2779 	int		 timeout;
2780 	char		 cmdLen;
2781 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2782 	u8		 cmd = io->cmd;
2783 	MPT_ADAPTER *ioc = hd->ioc;
2784 	int		 ret = 0;
2785 	unsigned long	 timeleft;
2786 	unsigned long	 flags;
2787 
2788 	/* don't send internal command during diag reset */
2789 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2790 	if (ioc->ioc_reset_in_progress) {
2791 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2792 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2793 			"%s: busy with host reset\n", ioc->name, __func__));
2794 		return MPT_SCANDV_BUSY;
2795 	}
2796 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2797 
2798 	mutex_lock(&ioc->internal_cmds.mutex);
2799 
2800 	/* Set command specific information
2801 	 */
2802 	switch (cmd) {
2803 	case INQUIRY:
2804 		cmdLen = 6;
2805 		dir = MPI_SCSIIO_CONTROL_READ;
2806 		CDB[0] = cmd;
2807 		CDB[4] = io->size;
2808 		timeout = 10;
2809 		break;
2810 
2811 	case TEST_UNIT_READY:
2812 		cmdLen = 6;
2813 		dir = MPI_SCSIIO_CONTROL_READ;
2814 		timeout = 10;
2815 		break;
2816 
2817 	case START_STOP:
2818 		cmdLen = 6;
2819 		dir = MPI_SCSIIO_CONTROL_READ;
2820 		CDB[0] = cmd;
2821 		CDB[4] = 1;	/*Spin up the disk */
2822 		timeout = 15;
2823 		break;
2824 
2825 	case REQUEST_SENSE:
2826 		cmdLen = 6;
2827 		CDB[0] = cmd;
2828 		CDB[4] = io->size;
2829 		dir = MPI_SCSIIO_CONTROL_READ;
2830 		timeout = 10;
2831 		break;
2832 
2833 	case READ_BUFFER:
2834 		cmdLen = 10;
2835 		dir = MPI_SCSIIO_CONTROL_READ;
2836 		CDB[0] = cmd;
2837 		if (io->flags & MPT_ICFLAG_ECHO) {
2838 			CDB[1] = 0x0A;
2839 		} else {
2840 			CDB[1] = 0x02;
2841 		}
2842 
2843 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2844 			CDB[1] |= 0x01;
2845 		}
2846 		CDB[6] = (io->size >> 16) & 0xFF;
2847 		CDB[7] = (io->size >>  8) & 0xFF;
2848 		CDB[8] = io->size & 0xFF;
2849 		timeout = 10;
2850 		break;
2851 
2852 	case WRITE_BUFFER:
2853 		cmdLen = 10;
2854 		dir = MPI_SCSIIO_CONTROL_WRITE;
2855 		CDB[0] = cmd;
2856 		if (io->flags & MPT_ICFLAG_ECHO) {
2857 			CDB[1] = 0x0A;
2858 		} else {
2859 			CDB[1] = 0x02;
2860 		}
2861 		CDB[6] = (io->size >> 16) & 0xFF;
2862 		CDB[7] = (io->size >>  8) & 0xFF;
2863 		CDB[8] = io->size & 0xFF;
2864 		timeout = 10;
2865 		break;
2866 
2867 	case RESERVE:
2868 		cmdLen = 6;
2869 		dir = MPI_SCSIIO_CONTROL_READ;
2870 		CDB[0] = cmd;
2871 		timeout = 10;
2872 		break;
2873 
2874 	case RELEASE:
2875 		cmdLen = 6;
2876 		dir = MPI_SCSIIO_CONTROL_READ;
2877 		CDB[0] = cmd;
2878 		timeout = 10;
2879 		break;
2880 
2881 	case SYNCHRONIZE_CACHE:
2882 		cmdLen = 10;
2883 		dir = MPI_SCSIIO_CONTROL_READ;
2884 		CDB[0] = cmd;
2885 //		CDB[1] = 0x02;	/* set immediate bit */
2886 		timeout = 10;
2887 		break;
2888 
2889 	default:
2890 		/* Error Case */
2891 		ret = -EFAULT;
2892 		goto out;
2893 	}
2894 
2895 	/* Get and Populate a free Frame
2896 	 * MsgContext set in mpt_get_msg_frame call
2897 	 */
2898 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2899 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2900 		    ioc->name, __func__));
2901 		ret = MPT_SCANDV_BUSY;
2902 		goto out;
2903 	}
2904 
2905 	pScsiReq = (SCSIIORequest_t *) mf;
2906 
2907 	/* Get the request index */
2908 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2909 	ADD_INDEX_LOG(my_idx); /* for debug */
2910 
2911 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2912 		pScsiReq->TargetID = io->physDiskNum;
2913 		pScsiReq->Bus = 0;
2914 		pScsiReq->ChainOffset = 0;
2915 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2916 	} else {
2917 		pScsiReq->TargetID = io->id;
2918 		pScsiReq->Bus = io->channel;
2919 		pScsiReq->ChainOffset = 0;
2920 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2921 	}
2922 
2923 	pScsiReq->CDBLength = cmdLen;
2924 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2925 
2926 	pScsiReq->Reserved = 0;
2927 
2928 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2929 	/* MsgContext set in mpt_get_msg_fram call  */
2930 
2931 	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2932 
2933 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2934 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2935 	else
2936 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2937 
2938 	if (cmd == REQUEST_SENSE) {
2939 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2940 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2941 		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2942 	}
2943 
2944 	for (ii = 0; ii < 16; ii++)
2945 		pScsiReq->CDB[ii] = CDB[ii];
2946 
2947 	pScsiReq->DataLength = cpu_to_le32(io->size);
2948 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2949 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2950 
2951 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2952 	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
2953 	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2954 
2955 	if (dir == MPI_SCSIIO_CONTROL_READ)
2956 		ioc->add_sge((char *) &pScsiReq->SGL,
2957 		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2958 	else
2959 		ioc->add_sge((char *) &pScsiReq->SGL,
2960 		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2961 
2962 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2963 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2964 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2965 	    timeout*HZ);
2966 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2967 		ret = MPT_SCANDV_DID_RESET;
2968 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2969 		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2970 		    cmd));
2971 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2972 			mpt_free_msg_frame(ioc, mf);
2973 			goto out;
2974 		}
2975 		if (!timeleft) {
2976 			printk(MYIOC_s_WARN_FMT
2977 			       "Issuing Reset from %s!! doorbell=0x%08xh"
2978 			       " cmd=0x%02x\n",
2979 			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
2980 			       cmd);
2981 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2982 			mpt_free_msg_frame(ioc, mf);
2983 		}
2984 		goto out;
2985 	}
2986 
2987 	ret = ioc->internal_cmds.completion_code;
2988 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2989 			ioc->name, __func__, ret));
2990 
2991  out:
2992 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
2993 	mutex_unlock(&ioc->internal_cmds.mutex);
2994 	return ret;
2995 }
2996 
2997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2998 /**
2999  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3000  *	@hd: Pointer to a SCSI HOST structure
3001  *	@vdevice: virtual target device
3002  *
3003  *	Uses the ISR, but with special processing.
3004  *	MUST be single-threaded.
3005  *
3006  */
3007 static void
3008 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3009 {
3010 	INTERNAL_CMD		 iocmd;
3011 
3012 	/* Ignore hidden raid components, this is handled when the command
3013 	 * is sent to the volume
3014 	 */
3015 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3016 		return;
3017 
3018 	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3019 	    !vdevice->configured_lun)
3020 		return;
3021 
3022 	/* Following parameters will not change
3023 	 * in this routine.
3024 	 */
3025 	iocmd.cmd = SYNCHRONIZE_CACHE;
3026 	iocmd.flags = 0;
3027 	iocmd.physDiskNum = -1;
3028 	iocmd.data = NULL;
3029 	iocmd.data_dma = -1;
3030 	iocmd.size = 0;
3031 	iocmd.rsvd = iocmd.rsvd2 = 0;
3032 	iocmd.channel = vdevice->vtarget->channel;
3033 	iocmd.id = vdevice->vtarget->id;
3034 	iocmd.lun = vdevice->lun;
3035 
3036 	mptscsih_do_cmd(hd, &iocmd);
3037 }
3038 
3039 static ssize_t
3040 mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3041 			 char *buf)
3042 {
3043 	struct Scsi_Host *host = class_to_shost(dev);
3044 	MPT_SCSI_HOST	*hd = shost_priv(host);
3045 	MPT_ADAPTER *ioc = hd->ioc;
3046 
3047 	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3048 	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3049 	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3050 	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3051 	    ioc->facts.FWVersion.Word & 0x000000FF);
3052 }
3053 static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3054 
3055 static ssize_t
3056 mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3057 			   char *buf)
3058 {
3059 	struct Scsi_Host *host = class_to_shost(dev);
3060 	MPT_SCSI_HOST	*hd = shost_priv(host);
3061 	MPT_ADAPTER *ioc = hd->ioc;
3062 
3063 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3064 	    (ioc->biosVersion & 0xFF000000) >> 24,
3065 	    (ioc->biosVersion & 0x00FF0000) >> 16,
3066 	    (ioc->biosVersion & 0x0000FF00) >> 8,
3067 	    ioc->biosVersion & 0x000000FF);
3068 }
3069 static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3070 
3071 static ssize_t
3072 mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3073 			  char *buf)
3074 {
3075 	struct Scsi_Host *host = class_to_shost(dev);
3076 	MPT_SCSI_HOST	*hd = shost_priv(host);
3077 	MPT_ADAPTER *ioc = hd->ioc;
3078 
3079 	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3080 }
3081 static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3082 
3083 static ssize_t
3084 mptscsih_version_product_show(struct device *dev,
3085 			      struct device_attribute *attr,
3086 char *buf)
3087 {
3088 	struct Scsi_Host *host = class_to_shost(dev);
3089 	MPT_SCSI_HOST	*hd = shost_priv(host);
3090 	MPT_ADAPTER *ioc = hd->ioc;
3091 
3092 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3093 }
3094 static DEVICE_ATTR(version_product, S_IRUGO,
3095     mptscsih_version_product_show, NULL);
3096 
3097 static ssize_t
3098 mptscsih_version_nvdata_persistent_show(struct device *dev,
3099 					struct device_attribute *attr,
3100 					char *buf)
3101 {
3102 	struct Scsi_Host *host = class_to_shost(dev);
3103 	MPT_SCSI_HOST	*hd = shost_priv(host);
3104 	MPT_ADAPTER *ioc = hd->ioc;
3105 
3106 	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3107 	    ioc->nvdata_version_persistent);
3108 }
3109 static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3110     mptscsih_version_nvdata_persistent_show, NULL);
3111 
3112 static ssize_t
3113 mptscsih_version_nvdata_default_show(struct device *dev,
3114 				     struct device_attribute *attr, char *buf)
3115 {
3116 	struct Scsi_Host *host = class_to_shost(dev);
3117 	MPT_SCSI_HOST	*hd = shost_priv(host);
3118 	MPT_ADAPTER *ioc = hd->ioc;
3119 
3120 	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3121 }
3122 static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3123     mptscsih_version_nvdata_default_show, NULL);
3124 
3125 static ssize_t
3126 mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3127 			 char *buf)
3128 {
3129 	struct Scsi_Host *host = class_to_shost(dev);
3130 	MPT_SCSI_HOST	*hd = shost_priv(host);
3131 	MPT_ADAPTER *ioc = hd->ioc;
3132 
3133 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3134 }
3135 static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3136 
3137 static ssize_t
3138 mptscsih_board_assembly_show(struct device *dev,
3139 			     struct device_attribute *attr, char *buf)
3140 {
3141 	struct Scsi_Host *host = class_to_shost(dev);
3142 	MPT_SCSI_HOST	*hd = shost_priv(host);
3143 	MPT_ADAPTER *ioc = hd->ioc;
3144 
3145 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3146 }
3147 static DEVICE_ATTR(board_assembly, S_IRUGO,
3148     mptscsih_board_assembly_show, NULL);
3149 
3150 static ssize_t
3151 mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3152 			   char *buf)
3153 {
3154 	struct Scsi_Host *host = class_to_shost(dev);
3155 	MPT_SCSI_HOST	*hd = shost_priv(host);
3156 	MPT_ADAPTER *ioc = hd->ioc;
3157 
3158 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3159 }
3160 static DEVICE_ATTR(board_tracer, S_IRUGO,
3161     mptscsih_board_tracer_show, NULL);
3162 
3163 static ssize_t
3164 mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3165 		       char *buf)
3166 {
3167 	struct Scsi_Host *host = class_to_shost(dev);
3168 	MPT_SCSI_HOST	*hd = shost_priv(host);
3169 	MPT_ADAPTER *ioc = hd->ioc;
3170 
3171 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3172 }
3173 static DEVICE_ATTR(io_delay, S_IRUGO,
3174     mptscsih_io_delay_show, NULL);
3175 
3176 static ssize_t
3177 mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3178 			   char *buf)
3179 {
3180 	struct Scsi_Host *host = class_to_shost(dev);
3181 	MPT_SCSI_HOST	*hd = shost_priv(host);
3182 	MPT_ADAPTER *ioc = hd->ioc;
3183 
3184 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3185 }
3186 static DEVICE_ATTR(device_delay, S_IRUGO,
3187     mptscsih_device_delay_show, NULL);
3188 
3189 static ssize_t
3190 mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3191 			  char *buf)
3192 {
3193 	struct Scsi_Host *host = class_to_shost(dev);
3194 	MPT_SCSI_HOST	*hd = shost_priv(host);
3195 	MPT_ADAPTER *ioc = hd->ioc;
3196 
3197 	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3198 }
3199 static ssize_t
3200 mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3201 			   const char *buf, size_t count)
3202 {
3203 	struct Scsi_Host *host = class_to_shost(dev);
3204 	MPT_SCSI_HOST	*hd = shost_priv(host);
3205 	MPT_ADAPTER *ioc = hd->ioc;
3206 	int val = 0;
3207 
3208 	if (sscanf(buf, "%x", &val) != 1)
3209 		return -EINVAL;
3210 
3211 	ioc->debug_level = val;
3212 	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3213 				ioc->name, ioc->debug_level);
3214 	return strlen(buf);
3215 }
3216 static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3217 	mptscsih_debug_level_show, mptscsih_debug_level_store);
3218 
3219 struct device_attribute *mptscsih_host_attrs[] = {
3220 	&dev_attr_version_fw,
3221 	&dev_attr_version_bios,
3222 	&dev_attr_version_mpi,
3223 	&dev_attr_version_product,
3224 	&dev_attr_version_nvdata_persistent,
3225 	&dev_attr_version_nvdata_default,
3226 	&dev_attr_board_name,
3227 	&dev_attr_board_assembly,
3228 	&dev_attr_board_tracer,
3229 	&dev_attr_io_delay,
3230 	&dev_attr_device_delay,
3231 	&dev_attr_debug_level,
3232 	NULL,
3233 };
3234 
3235 EXPORT_SYMBOL(mptscsih_host_attrs);
3236 
3237 EXPORT_SYMBOL(mptscsih_remove);
3238 EXPORT_SYMBOL(mptscsih_shutdown);
3239 #ifdef CONFIG_PM
3240 EXPORT_SYMBOL(mptscsih_suspend);
3241 EXPORT_SYMBOL(mptscsih_resume);
3242 #endif
3243 EXPORT_SYMBOL(mptscsih_show_info);
3244 EXPORT_SYMBOL(mptscsih_info);
3245 EXPORT_SYMBOL(mptscsih_qcmd);
3246 EXPORT_SYMBOL(mptscsih_slave_destroy);
3247 EXPORT_SYMBOL(mptscsih_slave_configure);
3248 EXPORT_SYMBOL(mptscsih_abort);
3249 EXPORT_SYMBOL(mptscsih_dev_reset);
3250 EXPORT_SYMBOL(mptscsih_bus_reset);
3251 EXPORT_SYMBOL(mptscsih_host_reset);
3252 EXPORT_SYMBOL(mptscsih_bios_param);
3253 EXPORT_SYMBOL(mptscsih_io_done);
3254 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3255 EXPORT_SYMBOL(mptscsih_scandv_complete);
3256 EXPORT_SYMBOL(mptscsih_event_process);
3257 EXPORT_SYMBOL(mptscsih_ioc_reset);
3258 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3259 
3260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3261