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