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