xref: /linux/drivers/message/fusion/mptscsih.c (revision cc4589ebfae6f8dbb5cf880a0a67eedab3416492)
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 (sc=%p)\n",
1877 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt);
1878 
1879 	return retval;
1880 }
1881 
1882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1883 /**
1884  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1885  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1886  *
1887  *	(linux scsi_host_template.eh_dev_reset_handler routine)
1888  *
1889  *	Returns SUCCESS or FAILED.
1890  **/
1891 int
1892 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1893 {
1894 	MPT_SCSI_HOST	*hd;
1895 	int		 retval;
1896 	VirtDevice	 *vdevice;
1897 	MPT_ADAPTER	*ioc;
1898 
1899 	/* If we can't locate our host adapter structure, return FAILED status.
1900 	 */
1901 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1902 		printk(KERN_ERR MYNAM ": target reset: "
1903 		   "Can't locate host! (sc=%p)\n", SCpnt);
1904 		return FAILED;
1905 	}
1906 
1907 	ioc = hd->ioc;
1908 	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1909 	       ioc->name, SCpnt);
1910 	scsi_print_command(SCpnt);
1911 
1912 	vdevice = SCpnt->device->hostdata;
1913 	if (!vdevice || !vdevice->vtarget) {
1914 		retval = SUCCESS;
1915 		goto out;
1916 	}
1917 
1918 	/* Target reset to hidden raid component is not supported
1919 	 */
1920 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1921 		retval = FAILED;
1922 		goto out;
1923 	}
1924 
1925 	retval = mptscsih_IssueTaskMgmt(hd,
1926 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1927 				vdevice->vtarget->channel,
1928 				vdevice->vtarget->id, 0, 0,
1929 				mptscsih_get_tm_timeout(ioc));
1930 
1931  out:
1932 	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1933 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1934 
1935 	if (retval == 0)
1936 		return SUCCESS;
1937 	else
1938 		return FAILED;
1939 }
1940 
1941 
1942 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1943 /**
1944  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1945  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1946  *
1947  *	(linux scsi_host_template.eh_bus_reset_handler routine)
1948  *
1949  *	Returns SUCCESS or FAILED.
1950  **/
1951 int
1952 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1953 {
1954 	MPT_SCSI_HOST	*hd;
1955 	int		 retval;
1956 	VirtDevice	 *vdevice;
1957 	MPT_ADAPTER	*ioc;
1958 
1959 	/* If we can't locate our host adapter structure, return FAILED status.
1960 	 */
1961 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1962 		printk(KERN_ERR MYNAM ": bus reset: "
1963 		   "Can't locate host! (sc=%p)\n", SCpnt);
1964 		return FAILED;
1965 	}
1966 
1967 	ioc = hd->ioc;
1968 	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1969 	       ioc->name, SCpnt);
1970 	scsi_print_command(SCpnt);
1971 
1972 	if (ioc->timeouts < -1)
1973 		ioc->timeouts++;
1974 
1975 	vdevice = SCpnt->device->hostdata;
1976 	if (!vdevice || !vdevice->vtarget)
1977 		return SUCCESS;
1978 	retval = mptscsih_IssueTaskMgmt(hd,
1979 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1980 					vdevice->vtarget->channel, 0, 0, 0,
1981 					mptscsih_get_tm_timeout(ioc));
1982 
1983 	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1984 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1985 
1986 	if (retval == 0)
1987 		return SUCCESS;
1988 	else
1989 		return FAILED;
1990 }
1991 
1992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1993 /**
1994  *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1995  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1996  *
1997  *	(linux scsi_host_template.eh_host_reset_handler routine)
1998  *
1999  *	Returns SUCCESS or FAILED.
2000  */
2001 int
2002 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2003 {
2004 	MPT_SCSI_HOST *  hd;
2005 	int              status = SUCCESS;
2006 	MPT_ADAPTER	*ioc;
2007 	int		retval;
2008 
2009 	/*  If we can't locate the host to reset, then we failed. */
2010 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
2011 		printk(KERN_ERR MYNAM ": host reset: "
2012 		    "Can't locate host! (sc=%p)\n", SCpnt);
2013 		return FAILED;
2014 	}
2015 
2016 	/* make sure we have no outstanding commands at this stage */
2017 	mptscsih_flush_running_cmds(hd);
2018 
2019 	ioc = hd->ioc;
2020 	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
2021 	    ioc->name, SCpnt);
2022 
2023 	/*  If our attempts to reset the host failed, then return a failed
2024 	 *  status.  The host will be taken off line by the SCSI mid-layer.
2025 	 */
2026     retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2027 	if (retval < 0)
2028 		status = FAILED;
2029 	else
2030 		status = SUCCESS;
2031 
2032 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
2033 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
2034 
2035 	return status;
2036 }
2037 
2038 static int
2039 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
2040 	SCSITaskMgmtReply_t *pScsiTmReply)
2041 {
2042 	u16			 iocstatus;
2043 	u32			 termination_count;
2044 	int			 retval;
2045 
2046 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
2047 		retval = FAILED;
2048 		goto out;
2049 	}
2050 
2051 	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2052 
2053 	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2054 	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2055 
2056 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2057 	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
2058 	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
2059 	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
2060 	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
2061 	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
2062 	    termination_count));
2063 
2064 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2065 	    pScsiTmReply->ResponseCode)
2066 		mptscsih_taskmgmt_response_code(ioc,
2067 		    pScsiTmReply->ResponseCode);
2068 
2069 	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
2070 		retval = 0;
2071 		goto out;
2072 	}
2073 
2074 	retval = FAILED;
2075 	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
2076 		if (termination_count == 1)
2077 			retval = 0;
2078 		goto out;
2079 	}
2080 
2081 	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
2082 	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
2083 		retval = 0;
2084 
2085  out:
2086 	return retval;
2087 }
2088 
2089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2090 void
2091 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2092 {
2093 	char *desc;
2094 
2095 	switch (response_code) {
2096 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2097 		desc = "The task completed.";
2098 		break;
2099 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2100 		desc = "The IOC received an invalid frame status.";
2101 		break;
2102 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2103 		desc = "The task type is not supported.";
2104 		break;
2105 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2106 		desc = "The requested task failed.";
2107 		break;
2108 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2109 		desc = "The task completed successfully.";
2110 		break;
2111 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2112 		desc = "The LUN request is invalid.";
2113 		break;
2114 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2115 		desc = "The task is in the IOC queue and has not been sent to target.";
2116 		break;
2117 	default:
2118 		desc = "unknown";
2119 		break;
2120 	}
2121 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2122 		ioc->name, response_code, desc);
2123 }
2124 EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2125 
2126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2127 /**
2128  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2129  *	@ioc: Pointer to MPT_ADAPTER structure
2130  *	@mf: Pointer to SCSI task mgmt request frame
2131  *	@mr: Pointer to SCSI task mgmt reply frame
2132  *
2133  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2134  *	of any SCSI task management request.
2135  *	This routine is registered with the MPT (base) driver at driver
2136  *	load/init time via the mpt_register() API call.
2137  *
2138  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2139  **/
2140 int
2141 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2142 	MPT_FRAME_HDR *mr)
2143 {
2144 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2145 		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2146 
2147 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2148 
2149 	if (!mr)
2150 		goto out;
2151 
2152 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2153 	memcpy(ioc->taskmgmt_cmds.reply, mr,
2154 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2155  out:
2156 	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2157 		mpt_clear_taskmgmt_in_progress_flag(ioc);
2158 		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2159 		complete(&ioc->taskmgmt_cmds.done);
2160 		if (ioc->bus_type == SAS)
2161 			ioc->schedule_target_reset(ioc);
2162 		return 1;
2163 	}
2164 	return 0;
2165 }
2166 
2167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2168 /*
2169  *	This is anyones guess quite frankly.
2170  */
2171 int
2172 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2173 		sector_t capacity, int geom[])
2174 {
2175 	int		heads;
2176 	int		sectors;
2177 	sector_t	cylinders;
2178 	ulong 		dummy;
2179 
2180 	heads = 64;
2181 	sectors = 32;
2182 
2183 	dummy = heads * sectors;
2184 	cylinders = capacity;
2185 	sector_div(cylinders,dummy);
2186 
2187 	/*
2188 	 * Handle extended translation size for logical drives
2189 	 * > 1Gb
2190 	 */
2191 	if ((ulong)capacity >= 0x200000) {
2192 		heads = 255;
2193 		sectors = 63;
2194 		dummy = heads * sectors;
2195 		cylinders = capacity;
2196 		sector_div(cylinders,dummy);
2197 	}
2198 
2199 	/* return result */
2200 	geom[0] = heads;
2201 	geom[1] = sectors;
2202 	geom[2] = cylinders;
2203 
2204 	return 0;
2205 }
2206 
2207 /* Search IOC page 3 to determine if this is hidden physical disk
2208  *
2209  */
2210 int
2211 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2212 {
2213 	struct inactive_raid_component_info *component_info;
2214 	int i, j;
2215 	RaidPhysDiskPage1_t *phys_disk;
2216 	int rc = 0;
2217 	int num_paths;
2218 
2219 	if (!ioc->raid_data.pIocPg3)
2220 		goto out;
2221 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2222 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2223 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2224 			rc = 1;
2225 			goto out;
2226 		}
2227 	}
2228 
2229 	if (ioc->bus_type != SAS)
2230 		goto out;
2231 
2232 	/*
2233 	 * Check if dual path
2234 	 */
2235 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2236 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2237 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2238 		if (num_paths < 2)
2239 			continue;
2240 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2241 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2242 		if (!phys_disk)
2243 			continue;
2244 		if ((mpt_raid_phys_disk_pg1(ioc,
2245 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2246 		    phys_disk))) {
2247 			kfree(phys_disk);
2248 			continue;
2249 		}
2250 		for (j = 0; j < num_paths; j++) {
2251 			if ((phys_disk->Path[j].Flags &
2252 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2253 				continue;
2254 			if ((phys_disk->Path[j].Flags &
2255 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2256 				continue;
2257 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2258 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2259 				rc = 1;
2260 				kfree(phys_disk);
2261 				goto out;
2262 			}
2263 		}
2264 		kfree(phys_disk);
2265 	}
2266 
2267 
2268 	/*
2269 	 * Check inactive list for matching phys disks
2270 	 */
2271 	if (list_empty(&ioc->raid_data.inactive_list))
2272 		goto out;
2273 
2274 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2275 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2276 	    list) {
2277 		if ((component_info->d.PhysDiskID == id) &&
2278 		    (component_info->d.PhysDiskBus == channel))
2279 			rc = 1;
2280 	}
2281 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2282 
2283  out:
2284 	return rc;
2285 }
2286 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2287 
2288 u8
2289 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2290 {
2291 	struct inactive_raid_component_info *component_info;
2292 	int i, j;
2293 	RaidPhysDiskPage1_t *phys_disk;
2294 	int rc = -ENXIO;
2295 	int num_paths;
2296 
2297 	if (!ioc->raid_data.pIocPg3)
2298 		goto out;
2299 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2300 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2301 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2302 			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2303 			goto out;
2304 		}
2305 	}
2306 
2307 	if (ioc->bus_type != SAS)
2308 		goto out;
2309 
2310 	/*
2311 	 * Check if dual path
2312 	 */
2313 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2314 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2315 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2316 		if (num_paths < 2)
2317 			continue;
2318 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2319 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2320 		if (!phys_disk)
2321 			continue;
2322 		if ((mpt_raid_phys_disk_pg1(ioc,
2323 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2324 		    phys_disk))) {
2325 			kfree(phys_disk);
2326 			continue;
2327 		}
2328 		for (j = 0; j < num_paths; j++) {
2329 			if ((phys_disk->Path[j].Flags &
2330 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2331 				continue;
2332 			if ((phys_disk->Path[j].Flags &
2333 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2334 				continue;
2335 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2336 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2337 				rc = phys_disk->PhysDiskNum;
2338 				kfree(phys_disk);
2339 				goto out;
2340 			}
2341 		}
2342 		kfree(phys_disk);
2343 	}
2344 
2345 	/*
2346 	 * Check inactive list for matching phys disks
2347 	 */
2348 	if (list_empty(&ioc->raid_data.inactive_list))
2349 		goto out;
2350 
2351 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2352 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2353 	    list) {
2354 		if ((component_info->d.PhysDiskID == id) &&
2355 		    (component_info->d.PhysDiskBus == channel))
2356 			rc = component_info->d.PhysDiskNum;
2357 	}
2358 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2359 
2360  out:
2361 	return rc;
2362 }
2363 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2364 
2365 /*
2366  *	OS entry point to allow for host driver to free allocated memory
2367  *	Called if no device present or device being unloaded
2368  */
2369 void
2370 mptscsih_slave_destroy(struct scsi_device *sdev)
2371 {
2372 	struct Scsi_Host	*host = sdev->host;
2373 	MPT_SCSI_HOST		*hd = shost_priv(host);
2374 	VirtTarget		*vtarget;
2375 	VirtDevice		*vdevice;
2376 	struct scsi_target 	*starget;
2377 
2378 	starget = scsi_target(sdev);
2379 	vtarget = starget->hostdata;
2380 	vdevice = sdev->hostdata;
2381 	if (!vdevice)
2382 		return;
2383 
2384 	mptscsih_search_running_cmds(hd, vdevice);
2385 	vtarget->num_luns--;
2386 	mptscsih_synchronize_cache(hd, vdevice);
2387 	kfree(vdevice);
2388 	sdev->hostdata = NULL;
2389 }
2390 
2391 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2392 /*
2393  *	mptscsih_change_queue_depth - This function will set a devices queue depth
2394  *	@sdev: per scsi_device pointer
2395  *	@qdepth: requested queue depth
2396  *	@reason: calling context
2397  *
2398  *	Adding support for new 'change_queue_depth' api.
2399 */
2400 int
2401 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
2402 {
2403 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2404 	VirtTarget 		*vtarget;
2405 	struct scsi_target 	*starget;
2406 	int			max_depth;
2407 	int			tagged;
2408 	MPT_ADAPTER		*ioc = hd->ioc;
2409 
2410 	starget = scsi_target(sdev);
2411 	vtarget = starget->hostdata;
2412 
2413 	if (reason != SCSI_QDEPTH_DEFAULT)
2414 		return -EOPNOTSUPP;
2415 
2416 	if (ioc->bus_type == SPI) {
2417 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2418 			max_depth = 1;
2419 		else if (sdev->type == TYPE_DISK &&
2420 			 vtarget->minSyncFactor <= MPT_ULTRA160)
2421 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2422 		else
2423 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2424 	} else
2425 		 max_depth = ioc->sh->can_queue;
2426 
2427 	if (!sdev->tagged_supported)
2428 		max_depth = 1;
2429 
2430 	if (qdepth > max_depth)
2431 		qdepth = max_depth;
2432 	if (qdepth == 1)
2433 		tagged = 0;
2434 	else
2435 		tagged = MSG_SIMPLE_TAG;
2436 
2437 	scsi_adjust_queue_depth(sdev, tagged, qdepth);
2438 	return sdev->queue_depth;
2439 }
2440 
2441 /*
2442  *	OS entry point to adjust the queue_depths on a per-device basis.
2443  *	Called once per device the bus scan. Use it to force the queue_depth
2444  *	member to 1 if a device does not support Q tags.
2445  *	Return non-zero if fails.
2446  */
2447 int
2448 mptscsih_slave_configure(struct scsi_device *sdev)
2449 {
2450 	struct Scsi_Host	*sh = sdev->host;
2451 	VirtTarget		*vtarget;
2452 	VirtDevice		*vdevice;
2453 	struct scsi_target 	*starget;
2454 	MPT_SCSI_HOST		*hd = shost_priv(sh);
2455 	MPT_ADAPTER		*ioc = hd->ioc;
2456 
2457 	starget = scsi_target(sdev);
2458 	vtarget = starget->hostdata;
2459 	vdevice = sdev->hostdata;
2460 
2461 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2462 		"device @ %p, channel=%d, id=%d, lun=%d\n",
2463 		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2464 	if (ioc->bus_type == SPI)
2465 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2466 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2467 		    ioc->name, sdev->sdtr, sdev->wdtr,
2468 		    sdev->ppr, sdev->inquiry_len));
2469 
2470 	vdevice->configured_lun = 1;
2471 
2472 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2473 		"Queue depth=%d, tflags=%x\n",
2474 		ioc->name, sdev->queue_depth, vtarget->tflags));
2475 
2476 	if (ioc->bus_type == SPI)
2477 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2478 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2479 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2480 		    vtarget->minSyncFactor));
2481 
2482 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH,
2483 				    SCSI_QDEPTH_DEFAULT);
2484 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2485 		"tagged %d, simple %d, ordered %d\n",
2486 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
2487 		sdev->ordered_tags));
2488 
2489 	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
2490 
2491 	return 0;
2492 }
2493 
2494 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2495 /*
2496  *  Private routines...
2497  */
2498 
2499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2500 /* Utility function to copy sense data from the scsi_cmnd buffer
2501  * to the FC and SCSI target structures.
2502  *
2503  */
2504 static void
2505 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2506 {
2507 	VirtDevice	*vdevice;
2508 	SCSIIORequest_t	*pReq;
2509 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2510 	MPT_ADAPTER 	*ioc = hd->ioc;
2511 
2512 	/* Get target structure
2513 	 */
2514 	pReq = (SCSIIORequest_t *) mf;
2515 	vdevice = sc->device->hostdata;
2516 
2517 	if (sense_count) {
2518 		u8 *sense_data;
2519 		int req_index;
2520 
2521 		/* Copy the sense received into the scsi command block. */
2522 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2523 		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2524 		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2525 
2526 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2527 		 */
2528 		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2529 			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2530 				int idx;
2531 
2532 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2533 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2534 				ioc->events[idx].eventContext = ioc->eventContext;
2535 
2536 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2537 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2538 					(sc->device->channel << 8) | sc->device->id;
2539 
2540 				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2541 
2542 				ioc->eventContext++;
2543 				if (ioc->pcidev->vendor ==
2544 				    PCI_VENDOR_ID_IBM) {
2545 					mptscsih_issue_sep_command(ioc,
2546 					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2547 					vdevice->vtarget->tflags |=
2548 					    MPT_TARGET_FLAGS_LED_ON;
2549 				}
2550 			}
2551 		}
2552 	} else {
2553 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2554 				ioc->name));
2555 	}
2556 }
2557 
2558 /**
2559  * mptscsih_get_scsi_lookup - retrieves scmd entry
2560  * @ioc: Pointer to MPT_ADAPTER structure
2561  * @i: index into the array
2562  *
2563  * Returns the scsi_cmd pointer
2564  */
2565 struct scsi_cmnd *
2566 mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2567 {
2568 	unsigned long	flags;
2569 	struct scsi_cmnd *scmd;
2570 
2571 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2572 	scmd = ioc->ScsiLookup[i];
2573 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2574 
2575 	return scmd;
2576 }
2577 EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2578 
2579 /**
2580  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2581  * @ioc: Pointer to MPT_ADAPTER structure
2582  * @i: index into the array
2583  *
2584  * Returns the scsi_cmd pointer
2585  *
2586  **/
2587 static struct scsi_cmnd *
2588 mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2589 {
2590 	unsigned long	flags;
2591 	struct scsi_cmnd *scmd;
2592 
2593 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2594 	scmd = ioc->ScsiLookup[i];
2595 	ioc->ScsiLookup[i] = NULL;
2596 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2597 
2598 	return scmd;
2599 }
2600 
2601 /**
2602  * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
2603  *
2604  * @ioc: Pointer to MPT_ADAPTER structure
2605  * @i: index into the array
2606  * @scmd: scsi_cmnd pointer
2607  *
2608  **/
2609 static void
2610 mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2611 {
2612 	unsigned long	flags;
2613 
2614 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2615 	ioc->ScsiLookup[i] = scmd;
2616 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2617 }
2618 
2619 /**
2620  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2621  * @ioc: Pointer to MPT_ADAPTER structure
2622  * @sc: scsi_cmnd pointer
2623  */
2624 static int
2625 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2626 {
2627 	unsigned long	flags;
2628 	int i, index=-1;
2629 
2630 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2631 	for (i = 0; i < ioc->req_depth; i++) {
2632 		if (ioc->ScsiLookup[i] == sc) {
2633 			index = i;
2634 			goto out;
2635 		}
2636 	}
2637 
2638  out:
2639 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2640 	return index;
2641 }
2642 
2643 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2644 int
2645 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2646 {
2647 	MPT_SCSI_HOST	*hd;
2648 
2649 	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2650 		return 0;
2651 
2652 	hd = shost_priv(ioc->sh);
2653 	switch (reset_phase) {
2654 	case MPT_IOC_SETUP_RESET:
2655 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2656 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2657 		break;
2658 	case MPT_IOC_PRE_RESET:
2659 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2660 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2661 		mptscsih_flush_running_cmds(hd);
2662 		break;
2663 	case MPT_IOC_POST_RESET:
2664 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2665 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2666 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2667 			ioc->internal_cmds.status |=
2668 				MPT_MGMT_STATUS_DID_IOCRESET;
2669 			complete(&ioc->internal_cmds.done);
2670 		}
2671 		break;
2672 	default:
2673 		break;
2674 	}
2675 	return 1;		/* currently means nothing really */
2676 }
2677 
2678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2679 int
2680 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2681 {
2682 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2683 
2684 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2685 		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2686 		ioc->name, event));
2687 
2688 	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2689 	    event == MPI_EVENT_EXT_BUS_RESET) &&
2690 	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2691 			ioc->soft_resets++;
2692 
2693 	return 1;		/* currently means nothing really */
2694 }
2695 
2696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2697 /*
2698  *  Bus Scan and Domain Validation functionality ...
2699  */
2700 
2701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2702 /*
2703  *	mptscsih_scandv_complete - Scan and DV callback routine registered
2704  *	to Fustion MPT (base) driver.
2705  *
2706  *	@ioc: Pointer to MPT_ADAPTER structure
2707  *	@mf: Pointer to original MPT request frame
2708  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2709  *
2710  *	This routine is called from mpt.c::mpt_interrupt() at the completion
2711  *	of any SCSI IO request.
2712  *	This routine is registered with the Fusion MPT (base) driver at driver
2713  *	load/init time via the mpt_register() API call.
2714  *
2715  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2716  *
2717  *	Remark: Sets a completion code and (possibly) saves sense data
2718  *	in the IOC member localReply structure.
2719  *	Used ONLY for DV and other internal commands.
2720  */
2721 int
2722 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2723 				MPT_FRAME_HDR *reply)
2724 {
2725 	SCSIIORequest_t *pReq;
2726 	SCSIIOReply_t	*pReply;
2727 	u8		 cmd;
2728 	u16		 req_idx;
2729 	u8	*sense_data;
2730 	int		 sz;
2731 
2732 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2733 	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2734 	if (!reply)
2735 		goto out;
2736 
2737 	pReply = (SCSIIOReply_t *) reply;
2738 	pReq = (SCSIIORequest_t *) req;
2739 	ioc->internal_cmds.completion_code =
2740 	    mptscsih_get_completion_code(ioc, req, reply);
2741 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2742 	memcpy(ioc->internal_cmds.reply, reply,
2743 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2744 	cmd = reply->u.hdr.Function;
2745 	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2746 	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2747 	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2748 		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2749 		sense_data = ((u8 *)ioc->sense_buf_pool +
2750 		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2751 		sz = min_t(int, pReq->SenseBufferLength,
2752 		    MPT_SENSE_BUFFER_ALLOC);
2753 		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2754 	}
2755  out:
2756 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2757 		return 0;
2758 	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2759 	complete(&ioc->internal_cmds.done);
2760 	return 1;
2761 }
2762 
2763 
2764 /**
2765  *	mptscsih_get_completion_code - get completion code from MPT request
2766  *	@ioc: Pointer to MPT_ADAPTER structure
2767  *	@req: Pointer to original MPT request frame
2768  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2769  *
2770  **/
2771 static int
2772 mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2773 				MPT_FRAME_HDR *reply)
2774 {
2775 	SCSIIOReply_t	*pReply;
2776 	MpiRaidActionReply_t *pr;
2777 	u8		 scsi_status;
2778 	u16		 status;
2779 	int		 completion_code;
2780 
2781 	pReply = (SCSIIOReply_t *)reply;
2782 	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2783 	scsi_status = pReply->SCSIStatus;
2784 
2785 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2786 	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2787 	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2788 	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2789 
2790 	switch (status) {
2791 
2792 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2793 		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2794 		break;
2795 
2796 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2797 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2798 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2799 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2800 		completion_code = MPT_SCANDV_DID_RESET;
2801 		break;
2802 
2803 	case MPI_IOCSTATUS_BUSY:
2804 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2805 		completion_code = MPT_SCANDV_BUSY;
2806 		break;
2807 
2808 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2809 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2810 	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2811 		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2812 			completion_code = MPT_SCANDV_GOOD;
2813 		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2814 			pr = (MpiRaidActionReply_t *)reply;
2815 			if (le16_to_cpu(pr->ActionStatus) ==
2816 				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2817 				completion_code = MPT_SCANDV_GOOD;
2818 			else
2819 				completion_code = MPT_SCANDV_SOME_ERROR;
2820 		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2821 			completion_code = MPT_SCANDV_SENSE;
2822 		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2823 			if (req->u.scsireq.CDB[0] == INQUIRY)
2824 				completion_code = MPT_SCANDV_ISSUE_SENSE;
2825 			else
2826 				completion_code = MPT_SCANDV_DID_RESET;
2827 		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2828 			completion_code = MPT_SCANDV_DID_RESET;
2829 		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2830 			completion_code = MPT_SCANDV_DID_RESET;
2831 		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2832 			completion_code = MPT_SCANDV_BUSY;
2833 		else
2834 			completion_code = MPT_SCANDV_GOOD;
2835 		break;
2836 
2837 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2838 		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2839 			completion_code = MPT_SCANDV_DID_RESET;
2840 		else
2841 			completion_code = MPT_SCANDV_SOME_ERROR;
2842 		break;
2843 	default:
2844 		completion_code = MPT_SCANDV_SOME_ERROR;
2845 		break;
2846 
2847 	}	/* switch(status) */
2848 
2849 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2850 	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2851 	return completion_code;
2852 }
2853 
2854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2855 /**
2856  *	mptscsih_do_cmd - Do internal command.
2857  *	@hd: MPT_SCSI_HOST pointer
2858  *	@io: INTERNAL_CMD pointer.
2859  *
2860  *	Issue the specified internally generated command and do command
2861  *	specific cleanup. For bus scan / DV only.
2862  *	NOTES: If command is Inquiry and status is good,
2863  *	initialize a target structure, save the data
2864  *
2865  *	Remark: Single threaded access only.
2866  *
2867  *	Return:
2868  *		< 0 if an illegal command or no resources
2869  *
2870  *		   0 if good
2871  *
2872  *		 > 0 if command complete but some type of completion error.
2873  */
2874 static int
2875 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2876 {
2877 	MPT_FRAME_HDR	*mf;
2878 	SCSIIORequest_t	*pScsiReq;
2879 	int		 my_idx, ii, dir;
2880 	int		 timeout;
2881 	char		 cmdLen;
2882 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2883 	u8		 cmd = io->cmd;
2884 	MPT_ADAPTER *ioc = hd->ioc;
2885 	int		 ret = 0;
2886 	unsigned long	 timeleft;
2887 	unsigned long	 flags;
2888 
2889 	/* don't send internal command during diag reset */
2890 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2891 	if (ioc->ioc_reset_in_progress) {
2892 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2893 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2894 			"%s: busy with host reset\n", ioc->name, __func__));
2895 		return MPT_SCANDV_BUSY;
2896 	}
2897 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2898 
2899 	mutex_lock(&ioc->internal_cmds.mutex);
2900 
2901 	/* Set command specific information
2902 	 */
2903 	switch (cmd) {
2904 	case INQUIRY:
2905 		cmdLen = 6;
2906 		dir = MPI_SCSIIO_CONTROL_READ;
2907 		CDB[0] = cmd;
2908 		CDB[4] = io->size;
2909 		timeout = 10;
2910 		break;
2911 
2912 	case TEST_UNIT_READY:
2913 		cmdLen = 6;
2914 		dir = MPI_SCSIIO_CONTROL_READ;
2915 		timeout = 10;
2916 		break;
2917 
2918 	case START_STOP:
2919 		cmdLen = 6;
2920 		dir = MPI_SCSIIO_CONTROL_READ;
2921 		CDB[0] = cmd;
2922 		CDB[4] = 1;	/*Spin up the disk */
2923 		timeout = 15;
2924 		break;
2925 
2926 	case REQUEST_SENSE:
2927 		cmdLen = 6;
2928 		CDB[0] = cmd;
2929 		CDB[4] = io->size;
2930 		dir = MPI_SCSIIO_CONTROL_READ;
2931 		timeout = 10;
2932 		break;
2933 
2934 	case READ_BUFFER:
2935 		cmdLen = 10;
2936 		dir = MPI_SCSIIO_CONTROL_READ;
2937 		CDB[0] = cmd;
2938 		if (io->flags & MPT_ICFLAG_ECHO) {
2939 			CDB[1] = 0x0A;
2940 		} else {
2941 			CDB[1] = 0x02;
2942 		}
2943 
2944 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2945 			CDB[1] |= 0x01;
2946 		}
2947 		CDB[6] = (io->size >> 16) & 0xFF;
2948 		CDB[7] = (io->size >>  8) & 0xFF;
2949 		CDB[8] = io->size & 0xFF;
2950 		timeout = 10;
2951 		break;
2952 
2953 	case WRITE_BUFFER:
2954 		cmdLen = 10;
2955 		dir = MPI_SCSIIO_CONTROL_WRITE;
2956 		CDB[0] = cmd;
2957 		if (io->flags & MPT_ICFLAG_ECHO) {
2958 			CDB[1] = 0x0A;
2959 		} else {
2960 			CDB[1] = 0x02;
2961 		}
2962 		CDB[6] = (io->size >> 16) & 0xFF;
2963 		CDB[7] = (io->size >>  8) & 0xFF;
2964 		CDB[8] = io->size & 0xFF;
2965 		timeout = 10;
2966 		break;
2967 
2968 	case RESERVE:
2969 		cmdLen = 6;
2970 		dir = MPI_SCSIIO_CONTROL_READ;
2971 		CDB[0] = cmd;
2972 		timeout = 10;
2973 		break;
2974 
2975 	case RELEASE:
2976 		cmdLen = 6;
2977 		dir = MPI_SCSIIO_CONTROL_READ;
2978 		CDB[0] = cmd;
2979 		timeout = 10;
2980 		break;
2981 
2982 	case SYNCHRONIZE_CACHE:
2983 		cmdLen = 10;
2984 		dir = MPI_SCSIIO_CONTROL_READ;
2985 		CDB[0] = cmd;
2986 //		CDB[1] = 0x02;	/* set immediate bit */
2987 		timeout = 10;
2988 		break;
2989 
2990 	default:
2991 		/* Error Case */
2992 		ret = -EFAULT;
2993 		goto out;
2994 	}
2995 
2996 	/* Get and Populate a free Frame
2997 	 * MsgContext set in mpt_get_msg_frame call
2998 	 */
2999 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3000 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
3001 		    ioc->name, __func__));
3002 		ret = MPT_SCANDV_BUSY;
3003 		goto out;
3004 	}
3005 
3006 	pScsiReq = (SCSIIORequest_t *) mf;
3007 
3008 	/* Get the request index */
3009 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3010 	ADD_INDEX_LOG(my_idx); /* for debug */
3011 
3012 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3013 		pScsiReq->TargetID = io->physDiskNum;
3014 		pScsiReq->Bus = 0;
3015 		pScsiReq->ChainOffset = 0;
3016 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3017 	} else {
3018 		pScsiReq->TargetID = io->id;
3019 		pScsiReq->Bus = io->channel;
3020 		pScsiReq->ChainOffset = 0;
3021 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3022 	}
3023 
3024 	pScsiReq->CDBLength = cmdLen;
3025 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3026 
3027 	pScsiReq->Reserved = 0;
3028 
3029 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
3030 	/* MsgContext set in mpt_get_msg_fram call  */
3031 
3032 	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3033 
3034 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3035 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3036 	else
3037 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3038 
3039 	if (cmd == REQUEST_SENSE) {
3040 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3041 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3042 		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
3043 	}
3044 
3045 	for (ii = 0; ii < 16; ii++)
3046 		pScsiReq->CDB[ii] = CDB[ii];
3047 
3048 	pScsiReq->DataLength = cpu_to_le32(io->size);
3049 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3050 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3051 
3052 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3053 	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
3054 	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
3055 
3056 	if (dir == MPI_SCSIIO_CONTROL_READ)
3057 		ioc->add_sge((char *) &pScsiReq->SGL,
3058 		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
3059 	else
3060 		ioc->add_sge((char *) &pScsiReq->SGL,
3061 		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
3062 
3063 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
3064 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3065 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
3066 	    timeout*HZ);
3067 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
3068 		ret = MPT_SCANDV_DID_RESET;
3069 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3070 		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
3071 		    cmd));
3072 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
3073 			mpt_free_msg_frame(ioc, mf);
3074 			goto out;
3075 		}
3076 		if (!timeleft) {
3077 			printk(MYIOC_s_WARN_FMT
3078 			       "Issuing Reset from %s!! doorbell=0x%08xh"
3079 			       " cmd=0x%02x\n",
3080 			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
3081 			       cmd);
3082 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
3083 			mpt_free_msg_frame(ioc, mf);
3084 		}
3085 		goto out;
3086 	}
3087 
3088 	ret = ioc->internal_cmds.completion_code;
3089 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
3090 			ioc->name, __func__, ret));
3091 
3092  out:
3093 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
3094 	mutex_unlock(&ioc->internal_cmds.mutex);
3095 	return ret;
3096 }
3097 
3098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3099 /**
3100  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3101  *	@hd: Pointer to a SCSI HOST structure
3102  *	@vdevice: virtual target device
3103  *
3104  *	Uses the ISR, but with special processing.
3105  *	MUST be single-threaded.
3106  *
3107  */
3108 static void
3109 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3110 {
3111 	INTERNAL_CMD		 iocmd;
3112 
3113 	/* Ignore hidden raid components, this is handled when the command
3114 	 * is sent to the volume
3115 	 */
3116 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3117 		return;
3118 
3119 	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3120 	    !vdevice->configured_lun)
3121 		return;
3122 
3123 	/* Following parameters will not change
3124 	 * in this routine.
3125 	 */
3126 	iocmd.cmd = SYNCHRONIZE_CACHE;
3127 	iocmd.flags = 0;
3128 	iocmd.physDiskNum = -1;
3129 	iocmd.data = NULL;
3130 	iocmd.data_dma = -1;
3131 	iocmd.size = 0;
3132 	iocmd.rsvd = iocmd.rsvd2 = 0;
3133 	iocmd.channel = vdevice->vtarget->channel;
3134 	iocmd.id = vdevice->vtarget->id;
3135 	iocmd.lun = vdevice->lun;
3136 
3137 	mptscsih_do_cmd(hd, &iocmd);
3138 }
3139 
3140 static ssize_t
3141 mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3142 			 char *buf)
3143 {
3144 	struct Scsi_Host *host = class_to_shost(dev);
3145 	MPT_SCSI_HOST	*hd = shost_priv(host);
3146 	MPT_ADAPTER *ioc = hd->ioc;
3147 
3148 	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3149 	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3150 	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3151 	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3152 	    ioc->facts.FWVersion.Word & 0x000000FF);
3153 }
3154 static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3155 
3156 static ssize_t
3157 mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3158 			   char *buf)
3159 {
3160 	struct Scsi_Host *host = class_to_shost(dev);
3161 	MPT_SCSI_HOST	*hd = shost_priv(host);
3162 	MPT_ADAPTER *ioc = hd->ioc;
3163 
3164 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3165 	    (ioc->biosVersion & 0xFF000000) >> 24,
3166 	    (ioc->biosVersion & 0x00FF0000) >> 16,
3167 	    (ioc->biosVersion & 0x0000FF00) >> 8,
3168 	    ioc->biosVersion & 0x000000FF);
3169 }
3170 static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3171 
3172 static ssize_t
3173 mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3174 			  char *buf)
3175 {
3176 	struct Scsi_Host *host = class_to_shost(dev);
3177 	MPT_SCSI_HOST	*hd = shost_priv(host);
3178 	MPT_ADAPTER *ioc = hd->ioc;
3179 
3180 	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3181 }
3182 static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3183 
3184 static ssize_t
3185 mptscsih_version_product_show(struct device *dev,
3186 			      struct device_attribute *attr,
3187 char *buf)
3188 {
3189 	struct Scsi_Host *host = class_to_shost(dev);
3190 	MPT_SCSI_HOST	*hd = shost_priv(host);
3191 	MPT_ADAPTER *ioc = hd->ioc;
3192 
3193 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3194 }
3195 static DEVICE_ATTR(version_product, S_IRUGO,
3196     mptscsih_version_product_show, NULL);
3197 
3198 static ssize_t
3199 mptscsih_version_nvdata_persistent_show(struct device *dev,
3200 					struct device_attribute *attr,
3201 					char *buf)
3202 {
3203 	struct Scsi_Host *host = class_to_shost(dev);
3204 	MPT_SCSI_HOST	*hd = shost_priv(host);
3205 	MPT_ADAPTER *ioc = hd->ioc;
3206 
3207 	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3208 	    ioc->nvdata_version_persistent);
3209 }
3210 static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3211     mptscsih_version_nvdata_persistent_show, NULL);
3212 
3213 static ssize_t
3214 mptscsih_version_nvdata_default_show(struct device *dev,
3215 				     struct device_attribute *attr, char *buf)
3216 {
3217 	struct Scsi_Host *host = class_to_shost(dev);
3218 	MPT_SCSI_HOST	*hd = shost_priv(host);
3219 	MPT_ADAPTER *ioc = hd->ioc;
3220 
3221 	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3222 }
3223 static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3224     mptscsih_version_nvdata_default_show, NULL);
3225 
3226 static ssize_t
3227 mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3228 			 char *buf)
3229 {
3230 	struct Scsi_Host *host = class_to_shost(dev);
3231 	MPT_SCSI_HOST	*hd = shost_priv(host);
3232 	MPT_ADAPTER *ioc = hd->ioc;
3233 
3234 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3235 }
3236 static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3237 
3238 static ssize_t
3239 mptscsih_board_assembly_show(struct device *dev,
3240 			     struct device_attribute *attr, char *buf)
3241 {
3242 	struct Scsi_Host *host = class_to_shost(dev);
3243 	MPT_SCSI_HOST	*hd = shost_priv(host);
3244 	MPT_ADAPTER *ioc = hd->ioc;
3245 
3246 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3247 }
3248 static DEVICE_ATTR(board_assembly, S_IRUGO,
3249     mptscsih_board_assembly_show, NULL);
3250 
3251 static ssize_t
3252 mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3253 			   char *buf)
3254 {
3255 	struct Scsi_Host *host = class_to_shost(dev);
3256 	MPT_SCSI_HOST	*hd = shost_priv(host);
3257 	MPT_ADAPTER *ioc = hd->ioc;
3258 
3259 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3260 }
3261 static DEVICE_ATTR(board_tracer, S_IRUGO,
3262     mptscsih_board_tracer_show, NULL);
3263 
3264 static ssize_t
3265 mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3266 		       char *buf)
3267 {
3268 	struct Scsi_Host *host = class_to_shost(dev);
3269 	MPT_SCSI_HOST	*hd = shost_priv(host);
3270 	MPT_ADAPTER *ioc = hd->ioc;
3271 
3272 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3273 }
3274 static DEVICE_ATTR(io_delay, S_IRUGO,
3275     mptscsih_io_delay_show, NULL);
3276 
3277 static ssize_t
3278 mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3279 			   char *buf)
3280 {
3281 	struct Scsi_Host *host = class_to_shost(dev);
3282 	MPT_SCSI_HOST	*hd = shost_priv(host);
3283 	MPT_ADAPTER *ioc = hd->ioc;
3284 
3285 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3286 }
3287 static DEVICE_ATTR(device_delay, S_IRUGO,
3288     mptscsih_device_delay_show, NULL);
3289 
3290 static ssize_t
3291 mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3292 			  char *buf)
3293 {
3294 	struct Scsi_Host *host = class_to_shost(dev);
3295 	MPT_SCSI_HOST	*hd = shost_priv(host);
3296 	MPT_ADAPTER *ioc = hd->ioc;
3297 
3298 	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3299 }
3300 static ssize_t
3301 mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3302 			   const char *buf, size_t count)
3303 {
3304 	struct Scsi_Host *host = class_to_shost(dev);
3305 	MPT_SCSI_HOST	*hd = shost_priv(host);
3306 	MPT_ADAPTER *ioc = hd->ioc;
3307 	int val = 0;
3308 
3309 	if (sscanf(buf, "%x", &val) != 1)
3310 		return -EINVAL;
3311 
3312 	ioc->debug_level = val;
3313 	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3314 				ioc->name, ioc->debug_level);
3315 	return strlen(buf);
3316 }
3317 static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3318 	mptscsih_debug_level_show, mptscsih_debug_level_store);
3319 
3320 struct device_attribute *mptscsih_host_attrs[] = {
3321 	&dev_attr_version_fw,
3322 	&dev_attr_version_bios,
3323 	&dev_attr_version_mpi,
3324 	&dev_attr_version_product,
3325 	&dev_attr_version_nvdata_persistent,
3326 	&dev_attr_version_nvdata_default,
3327 	&dev_attr_board_name,
3328 	&dev_attr_board_assembly,
3329 	&dev_attr_board_tracer,
3330 	&dev_attr_io_delay,
3331 	&dev_attr_device_delay,
3332 	&dev_attr_debug_level,
3333 	NULL,
3334 };
3335 
3336 EXPORT_SYMBOL(mptscsih_host_attrs);
3337 
3338 EXPORT_SYMBOL(mptscsih_remove);
3339 EXPORT_SYMBOL(mptscsih_shutdown);
3340 #ifdef CONFIG_PM
3341 EXPORT_SYMBOL(mptscsih_suspend);
3342 EXPORT_SYMBOL(mptscsih_resume);
3343 #endif
3344 EXPORT_SYMBOL(mptscsih_proc_info);
3345 EXPORT_SYMBOL(mptscsih_info);
3346 EXPORT_SYMBOL(mptscsih_qcmd);
3347 EXPORT_SYMBOL(mptscsih_slave_destroy);
3348 EXPORT_SYMBOL(mptscsih_slave_configure);
3349 EXPORT_SYMBOL(mptscsih_abort);
3350 EXPORT_SYMBOL(mptscsih_dev_reset);
3351 EXPORT_SYMBOL(mptscsih_bus_reset);
3352 EXPORT_SYMBOL(mptscsih_host_reset);
3353 EXPORT_SYMBOL(mptscsih_bios_param);
3354 EXPORT_SYMBOL(mptscsih_io_done);
3355 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3356 EXPORT_SYMBOL(mptscsih_scandv_complete);
3357 EXPORT_SYMBOL(mptscsih_event_process);
3358 EXPORT_SYMBOL(mptscsih_ioc_reset);
3359 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3360 
3361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3362