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