xref: /linux/drivers/message/fusion/mptscsih.c (revision 2277ab4a1df50e05bc732fe9488d4e902bb8399a)
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 	sc->host_scribble = NULL;
632 	sc->result = DID_OK << 16;		/* Set default reply as OK */
633 	pScsiReq = (SCSIIORequest_t *) mf;
634 	pScsiReply = (SCSIIOReply_t *) mr;
635 
636 	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
637 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
638 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
639 			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
640 	}else{
641 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
642 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
643 			ioc->name, mf, mr, sc, req_idx));
644 	}
645 
646 	if (pScsiReply == NULL) {
647 		/* special context reply handling */
648 		;
649 	} else {
650 		u32	 xfer_cnt;
651 		u16	 status;
652 		u8	 scsi_state, scsi_status;
653 		u32	 log_info;
654 
655 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
656 		scsi_state = pScsiReply->SCSIState;
657 		scsi_status = pScsiReply->SCSIStatus;
658 		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
659 		scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
660 		log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
661 
662 		/*
663 		 *  if we get a data underrun indication, yet no data was
664 		 *  transferred and the SCSI status indicates that the
665 		 *  command was never started, change the data underrun
666 		 *  to success
667 		 */
668 		if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
669 		    (scsi_status == MPI_SCSI_STATUS_BUSY ||
670 		     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
671 		     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
672 			status = MPI_IOCSTATUS_SUCCESS;
673 		}
674 
675 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
676 			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
677 
678 		/*
679 		 *  Look for + dump FCP ResponseInfo[]!
680 		 */
681 		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
682 		    pScsiReply->ResponseInfo) {
683 			printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
684 			"FCP_ResponseInfo=%08xh\n", ioc->name,
685 			sc->device->host->host_no, sc->device->channel,
686 			sc->device->id, sc->device->lun,
687 			le32_to_cpu(pScsiReply->ResponseInfo));
688 		}
689 
690 		switch(status) {
691 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
692 			/* CHECKME!
693 			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
694 			 * But not: DID_BUS_BUSY lest one risk
695 			 * killing interrupt handler:-(
696 			 */
697 			sc->result = SAM_STAT_BUSY;
698 			break;
699 
700 		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
701 		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
702 			sc->result = DID_BAD_TARGET << 16;
703 			break;
704 
705 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
706 			/* Spoof to SCSI Selection Timeout! */
707 			if (ioc->bus_type != FC)
708 				sc->result = DID_NO_CONNECT << 16;
709 			/* else fibre, just stall until rescan event */
710 			else
711 				sc->result = DID_REQUEUE << 16;
712 
713 			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
714 				hd->sel_timeout[pScsiReq->TargetID]++;
715 
716 			vdevice = sc->device->hostdata;
717 			if (!vdevice)
718 				break;
719 			vtarget = vdevice->vtarget;
720 			if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
721 				mptscsih_issue_sep_command(ioc, vtarget,
722 				    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
723 				vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
724 			}
725 			break;
726 
727 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
728 			if ( ioc->bus_type == SAS ) {
729 				u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
730 				if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
731 					if ((log_info & SAS_LOGINFO_MASK)
732 					    == SAS_LOGINFO_NEXUS_LOSS) {
733 						sc->result = (DID_BUS_BUSY << 16);
734 						break;
735 					}
736 				}
737 			} else if (ioc->bus_type == FC) {
738 				/*
739 				 * The FC IOC may kill a request for variety of
740 				 * reasons, some of which may be recovered by a
741 				 * retry, some which are unlikely to be
742 				 * recovered. Return DID_ERROR instead of
743 				 * DID_RESET to permit retry of the command,
744 				 * just not an infinite number of them
745 				 */
746 				sc->result = DID_ERROR << 16;
747 				break;
748 			}
749 
750 			/*
751 			 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
752 			 */
753 
754 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
755 			/* Linux handles an unsolicited DID_RESET better
756 			 * than an unsolicited DID_ABORT.
757 			 */
758 			sc->result = DID_RESET << 16;
759 
760 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
761 			if (ioc->bus_type == FC)
762 				sc->result = DID_ERROR << 16;
763 			else
764 				sc->result = DID_RESET << 16;
765 			break;
766 
767 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
768 			scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
769 			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
770 				sc->result=DID_SOFT_ERROR << 16;
771 			else /* Sufficient data transfer occurred */
772 				sc->result = (DID_OK << 16) | scsi_status;
773 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
774 			    "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
775 			    ioc->name, sc->result, sc->device->channel, sc->device->id));
776 			break;
777 
778 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
779 			/*
780 			 *  Do upfront check for valid SenseData and give it
781 			 *  precedence!
782 			 */
783 			sc->result = (DID_OK << 16) | scsi_status;
784 			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
785 				/* Have already saved the status and sense data
786 				 */
787 				;
788 			} else {
789 				if (xfer_cnt < sc->underflow) {
790 					if (scsi_status == SAM_STAT_BUSY)
791 						sc->result = SAM_STAT_BUSY;
792 					else
793 						sc->result = DID_SOFT_ERROR << 16;
794 				}
795 				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
796 					/* What to do?
797 				 	*/
798 					sc->result = DID_SOFT_ERROR << 16;
799 				}
800 				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
801 					/*  Not real sure here either...  */
802 					sc->result = DID_RESET << 16;
803 				}
804 			}
805 
806 
807 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
808 			    "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
809 			    ioc->name, sc->underflow));
810 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
811 			    "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
812 
813 			/* Report Queue Full
814 			 */
815 			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
816 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
817 
818 			break;
819 
820 		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
821 			scsi_set_resid(sc, 0);
822 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
823 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
824 			sc->result = (DID_OK << 16) | scsi_status;
825 			if (scsi_state == 0) {
826 				;
827 			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
828 				/*
829 				 * If running against circa 200003dd 909 MPT f/w,
830 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
831 				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
832 				 * and with SenseBytes set to 0.
833 				 */
834 				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
835 					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
836 
837 			}
838 			else if (scsi_state &
839 			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
840 			   ) {
841 				/*
842 				 * What to do?
843 				 */
844 				sc->result = DID_SOFT_ERROR << 16;
845 			}
846 			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
847 				/*  Not real sure here either...  */
848 				sc->result = DID_RESET << 16;
849 			}
850 			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
851 				/* Device Inq. data indicates that it supports
852 				 * QTags, but rejects QTag messages.
853 				 * This command completed OK.
854 				 *
855 				 * Not real sure here either so do nothing...  */
856 			}
857 
858 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
859 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
860 
861 			/* Add handling of:
862 			 * Reservation Conflict, Busy,
863 			 * Command Terminated, CHECK
864 			 */
865 			break;
866 
867 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
868 			sc->result = DID_SOFT_ERROR << 16;
869 			break;
870 
871 		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
872 		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
873 		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
874 		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
875 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
876 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
877 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
878 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
879 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
880 		default:
881 			/*
882 			 * What to do?
883 			 */
884 			sc->result = DID_SOFT_ERROR << 16;
885 			break;
886 
887 		}	/* switch(status) */
888 
889 #ifdef CONFIG_FUSION_LOGGING
890 		if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
891 			mptscsih_info_scsiio(ioc, sc, pScsiReply);
892 #endif
893 
894 	} /* end of address reply case */
895 
896 	/* Unmap the DMA buffers, if any. */
897 	scsi_dma_unmap(sc);
898 
899 	sc->scsi_done(sc);		/* Issue the command callback */
900 
901 	/* Free Chain buffers */
902 	mptscsih_freeChainBuffers(ioc, req_idx);
903 	return 1;
904 }
905 
906 /*
907  *	mptscsih_flush_running_cmds - For each command found, search
908  *		Scsi_Host instance taskQ and reply to OS.
909  *		Called only if recovering from a FW reload.
910  *	@hd: Pointer to a SCSI HOST structure
911  *
912  *	Returns: None.
913  *
914  *	Must be called while new I/Os are being queued.
915  */
916 static void
917 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
918 {
919 	MPT_ADAPTER *ioc = hd->ioc;
920 	struct scsi_cmnd *sc;
921 	SCSIIORequest_t	*mf = NULL;
922 	int		 ii;
923 	int		 channel, id;
924 
925 	for (ii= 0; ii < ioc->req_depth; ii++) {
926 		sc = mptscsih_getclear_scsi_lookup(ioc, ii);
927 		if (!sc)
928 			continue;
929 		mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
930 		if (!mf)
931 			continue;
932 		channel = mf->Bus;
933 		id = mf->TargetID;
934 		mptscsih_freeChainBuffers(ioc, ii);
935 		mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
936 		if ((unsigned char *)mf != sc->host_scribble)
937 			continue;
938 		scsi_dma_unmap(sc);
939 		sc->result = DID_RESET << 16;
940 		sc->host_scribble = NULL;
941 		dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
942 		    "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
943 		    "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
944 		sc->scsi_done(sc);
945 	}
946 }
947 
948 /*
949  *	mptscsih_search_running_cmds - Delete any commands associated
950  *		with the specified target and lun. Function called only
951  *		when a lun is disable by mid-layer.
952  *		Do NOT access the referenced scsi_cmnd structure or
953  *		members. Will cause either a paging or NULL ptr error.
954  *		(BUT, BUT, BUT, the code does reference it! - mdr)
955  *      @hd: Pointer to a SCSI HOST structure
956  *	@vdevice: per device private data
957  *
958  *	Returns: None.
959  *
960  *	Called from slave_destroy.
961  */
962 static void
963 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
964 {
965 	SCSIIORequest_t	*mf = NULL;
966 	int		 ii;
967 	struct scsi_cmnd *sc;
968 	struct scsi_lun  lun;
969 	MPT_ADAPTER *ioc = hd->ioc;
970 	unsigned long	flags;
971 
972 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
973 	for (ii = 0; ii < ioc->req_depth; ii++) {
974 		if ((sc = ioc->ScsiLookup[ii]) != NULL) {
975 
976 			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
977 			if (mf == NULL)
978 				continue;
979 			/* If the device is a hidden raid component, then its
980 			 * expected that the mf->function will be RAID_SCSI_IO
981 			 */
982 			if (vdevice->vtarget->tflags &
983 			    MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
984 			    MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
985 				continue;
986 
987 			int_to_scsilun(vdevice->lun, &lun);
988 			if ((mf->Bus != vdevice->vtarget->channel) ||
989 			    (mf->TargetID != vdevice->vtarget->id) ||
990 			    memcmp(lun.scsi_lun, mf->LUN, 8))
991 				continue;
992 
993 			if ((unsigned char *)mf != sc->host_scribble)
994 				continue;
995 			ioc->ScsiLookup[ii] = NULL;
996 			spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
997 			mptscsih_freeChainBuffers(ioc, ii);
998 			mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
999 			scsi_dma_unmap(sc);
1000 			sc->host_scribble = NULL;
1001 			sc->result = DID_NO_CONNECT << 16;
1002 			dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
1003 			   MYIOC_s_FMT "completing cmds: fw_channel %d, "
1004 			   "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
1005 			   vdevice->vtarget->channel, vdevice->vtarget->id,
1006 			   sc, mf, ii));
1007 			sc->scsi_done(sc);
1008 			spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1009 		}
1010 	}
1011 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1012 	return;
1013 }
1014 
1015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016 
1017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1018 /*
1019  *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
1020  *	from a SCSI target device.
1021  *	@sc: Pointer to scsi_cmnd structure
1022  *	@pScsiReply: Pointer to SCSIIOReply_t
1023  *	@pScsiReq: Pointer to original SCSI request
1024  *
1025  *	This routine periodically reports QUEUE_FULL status returned from a
1026  *	SCSI target device.  It reports this to the console via kernel
1027  *	printk() API call, not more than once every 10 seconds.
1028  */
1029 static void
1030 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1031 {
1032 	long time = jiffies;
1033 	MPT_SCSI_HOST		*hd;
1034 	MPT_ADAPTER	*ioc;
1035 
1036 	if (sc->device == NULL)
1037 		return;
1038 	if (sc->device->host == NULL)
1039 		return;
1040 	if ((hd = shost_priv(sc->device->host)) == NULL)
1041 		return;
1042 	ioc = hd->ioc;
1043 	if (time - hd->last_queue_full > 10 * HZ) {
1044 		dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1045 				ioc->name, 0, sc->device->id, sc->device->lun));
1046 		hd->last_queue_full = time;
1047 	}
1048 }
1049 
1050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 /*
1052  *	mptscsih_remove - Removed scsi devices
1053  *	@pdev: Pointer to pci_dev structure
1054  *
1055  *
1056  */
1057 void
1058 mptscsih_remove(struct pci_dev *pdev)
1059 {
1060 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1061 	struct Scsi_Host 	*host = ioc->sh;
1062 	MPT_SCSI_HOST		*hd;
1063 	int sz1;
1064 
1065 	if(!host) {
1066 		mpt_detach(pdev);
1067 		return;
1068 	}
1069 
1070 	scsi_remove_host(host);
1071 
1072 	if((hd = shost_priv(host)) == NULL)
1073 		return;
1074 
1075 	mptscsih_shutdown(pdev);
1076 
1077 	sz1=0;
1078 
1079 	if (ioc->ScsiLookup != NULL) {
1080 		sz1 = ioc->req_depth * sizeof(void *);
1081 		kfree(ioc->ScsiLookup);
1082 		ioc->ScsiLookup = NULL;
1083 	}
1084 
1085 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1086 	    "Free'd ScsiLookup (%d) memory\n",
1087 	    ioc->name, sz1));
1088 
1089 	kfree(hd->info_kbuf);
1090 
1091 	/* NULL the Scsi_Host pointer
1092 	 */
1093 	ioc->sh = NULL;
1094 
1095 	scsi_host_put(host);
1096 
1097 	mpt_detach(pdev);
1098 
1099 }
1100 
1101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1102 /*
1103  *	mptscsih_shutdown - reboot notifier
1104  *
1105  */
1106 void
1107 mptscsih_shutdown(struct pci_dev *pdev)
1108 {
1109 }
1110 
1111 #ifdef CONFIG_PM
1112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1113 /*
1114  *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1115  *
1116  *
1117  */
1118 int
1119 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1120 {
1121 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1122 
1123 	scsi_block_requests(ioc->sh);
1124 	flush_scheduled_work();
1125 	mptscsih_shutdown(pdev);
1126 	return mpt_suspend(pdev,state);
1127 }
1128 
1129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1130 /*
1131  *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1132  *
1133  *
1134  */
1135 int
1136 mptscsih_resume(struct pci_dev *pdev)
1137 {
1138 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1139 	int rc;
1140 
1141 	rc = mpt_resume(pdev);
1142 	scsi_unblock_requests(ioc->sh);
1143 	return rc;
1144 }
1145 
1146 #endif
1147 
1148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1149 /**
1150  *	mptscsih_info - Return information about MPT adapter
1151  *	@SChost: Pointer to Scsi_Host structure
1152  *
1153  *	(linux scsi_host_template.info routine)
1154  *
1155  *	Returns pointer to buffer where information was written.
1156  */
1157 const char *
1158 mptscsih_info(struct Scsi_Host *SChost)
1159 {
1160 	MPT_SCSI_HOST *h;
1161 	int size = 0;
1162 
1163 	h = shost_priv(SChost);
1164 
1165 	if (h) {
1166 		if (h->info_kbuf == NULL)
1167 			if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1168 				return h->info_kbuf;
1169 		h->info_kbuf[0] = '\0';
1170 
1171 		mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1172 		h->info_kbuf[size-1] = '\0';
1173 	}
1174 
1175 	return h->info_kbuf;
1176 }
1177 
1178 struct info_str {
1179 	char *buffer;
1180 	int   length;
1181 	int   offset;
1182 	int   pos;
1183 };
1184 
1185 static void
1186 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1187 {
1188 	if (info->pos + len > info->length)
1189 		len = info->length - info->pos;
1190 
1191 	if (info->pos + len < info->offset) {
1192 		info->pos += len;
1193 		return;
1194 	}
1195 
1196 	if (info->pos < info->offset) {
1197 	        data += (info->offset - info->pos);
1198 	        len  -= (info->offset - info->pos);
1199 	}
1200 
1201 	if (len > 0) {
1202                 memcpy(info->buffer + info->pos, data, len);
1203                 info->pos += len;
1204 	}
1205 }
1206 
1207 static int
1208 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1209 {
1210 	va_list args;
1211 	char buf[81];
1212 	int len;
1213 
1214 	va_start(args, fmt);
1215 	len = vsprintf(buf, fmt, args);
1216 	va_end(args);
1217 
1218 	mptscsih_copy_mem_info(info, buf, len);
1219 	return len;
1220 }
1221 
1222 static int
1223 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1224 {
1225 	struct info_str info;
1226 
1227 	info.buffer	= pbuf;
1228 	info.length	= len;
1229 	info.offset	= offset;
1230 	info.pos	= 0;
1231 
1232 	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1233 	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1234 	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1235 	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1236 
1237 	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1238 }
1239 
1240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1241 /**
1242  *	mptscsih_proc_info - Return information about MPT adapter
1243  * 	@host:   scsi host struct
1244  * 	@buffer: if write, user data; if read, buffer for user
1245  *	@start: returns the buffer address
1246  * 	@offset: if write, 0; if read, the current offset into the buffer from
1247  * 		 the previous read.
1248  * 	@length: if write, return length;
1249  *	@func:   write = 1; read = 0
1250  *
1251  *	(linux scsi_host_template.info routine)
1252  */
1253 int
1254 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1255 			int length, int func)
1256 {
1257 	MPT_SCSI_HOST	*hd = shost_priv(host);
1258 	MPT_ADAPTER	*ioc = hd->ioc;
1259 	int size = 0;
1260 
1261 	if (func) {
1262 		/*
1263 		 * write is not supported
1264 		 */
1265 	} else {
1266 		if (start)
1267 			*start = buffer;
1268 
1269 		size = mptscsih_host_info(ioc, buffer, offset, length);
1270 	}
1271 
1272 	return size;
1273 }
1274 
1275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1276 #define ADD_INDEX_LOG(req_ent)	do { } while(0)
1277 
1278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1279 /**
1280  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1281  *	@SCpnt: Pointer to scsi_cmnd structure
1282  *	@done: Pointer SCSI mid-layer IO completion function
1283  *
1284  *	(linux scsi_host_template.queuecommand routine)
1285  *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1286  *	from a linux scsi_cmnd request and send it to the IOC.
1287  *
1288  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1289  */
1290 int
1291 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1292 {
1293 	MPT_SCSI_HOST		*hd;
1294 	MPT_FRAME_HDR		*mf;
1295 	SCSIIORequest_t		*pScsiReq;
1296 	VirtDevice		*vdevice = SCpnt->device->hostdata;
1297 	u32	 datalen;
1298 	u32	 scsictl;
1299 	u32	 scsidir;
1300 	u32	 cmd_len;
1301 	int	 my_idx;
1302 	int	 ii;
1303 	MPT_ADAPTER *ioc;
1304 
1305 	hd = shost_priv(SCpnt->device->host);
1306 	ioc = hd->ioc;
1307 	SCpnt->scsi_done = done;
1308 
1309 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
1310 		ioc->name, SCpnt, done));
1311 
1312 	if (ioc->taskmgmt_quiesce_io) {
1313 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1314 			ioc->name, SCpnt));
1315 		return SCSI_MLQUEUE_HOST_BUSY;
1316 	}
1317 
1318 	/*
1319 	 *  Put together a MPT SCSI request...
1320 	 */
1321 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1322 		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1323 				ioc->name));
1324 		return SCSI_MLQUEUE_HOST_BUSY;
1325 	}
1326 
1327 	pScsiReq = (SCSIIORequest_t *) mf;
1328 
1329 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1330 
1331 	ADD_INDEX_LOG(my_idx);
1332 
1333 	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1334 	 *    Seems we may receive a buffer (datalen>0) even when there
1335 	 *    will be no data transfer!  GRRRRR...
1336 	 */
1337 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1338 		datalen = scsi_bufflen(SCpnt);
1339 		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1340 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1341 		datalen = scsi_bufflen(SCpnt);
1342 		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1343 	} else {
1344 		datalen = 0;
1345 		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1346 	}
1347 
1348 	/* Default to untagged. Once a target structure has been allocated,
1349 	 * use the Inquiry data to determine if device supports tagged.
1350 	 */
1351 	if (vdevice
1352 	    && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1353 	    && (SCpnt->device->tagged_supported)) {
1354 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1355 	} else {
1356 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1357 	}
1358 
1359 	/* Use the above information to set up the message frame
1360 	 */
1361 	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1362 	pScsiReq->Bus = vdevice->vtarget->channel;
1363 	pScsiReq->ChainOffset = 0;
1364 	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1365 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1366 	else
1367 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1368 	pScsiReq->CDBLength = SCpnt->cmd_len;
1369 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1370 	pScsiReq->Reserved = 0;
1371 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1372 	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1373 	pScsiReq->Control = cpu_to_le32(scsictl);
1374 
1375 	/*
1376 	 *  Write SCSI CDB into the message
1377 	 */
1378 	cmd_len = SCpnt->cmd_len;
1379 	for (ii=0; ii < cmd_len; ii++)
1380 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1381 
1382 	for (ii=cmd_len; ii < 16; ii++)
1383 		pScsiReq->CDB[ii] = 0;
1384 
1385 	/* DataLength */
1386 	pScsiReq->DataLength = cpu_to_le32(datalen);
1387 
1388 	/* SenseBuffer low address */
1389 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1390 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1391 
1392 	/* Now add the SG list
1393 	 * Always have a SGE even if null length.
1394 	 */
1395 	if (datalen == 0) {
1396 		/* Add a NULL SGE */
1397 		ioc->add_sge((char *)&pScsiReq->SGL,
1398 			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1399 			(dma_addr_t) -1);
1400 	} else {
1401 		/* Add a 32 or 64 bit SGE */
1402 		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1403 			goto fail;
1404 	}
1405 
1406 	SCpnt->host_scribble = (unsigned char *)mf;
1407 	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1408 
1409 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1410 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1411 			ioc->name, SCpnt, mf, my_idx));
1412 	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1413 	return 0;
1414 
1415  fail:
1416 	mptscsih_freeChainBuffers(ioc, my_idx);
1417 	mpt_free_msg_frame(ioc, mf);
1418 	return SCSI_MLQUEUE_HOST_BUSY;
1419 }
1420 
1421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1422 /*
1423  *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1424  *	with a SCSI IO request
1425  *	@hd: Pointer to the MPT_SCSI_HOST instance
1426  *	@req_idx: Index of the SCSI IO request frame.
1427  *
1428  *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1429  *	No return.
1430  */
1431 static void
1432 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1433 {
1434 	MPT_FRAME_HDR *chain;
1435 	unsigned long flags;
1436 	int chain_idx;
1437 	int next;
1438 
1439 	/* Get the first chain index and reset
1440 	 * tracker state.
1441 	 */
1442 	chain_idx = ioc->ReqToChain[req_idx];
1443 	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1444 
1445 	while (chain_idx != MPT_HOST_NO_CHAIN) {
1446 
1447 		/* Save the next chain buffer index */
1448 		next = ioc->ChainToChain[chain_idx];
1449 
1450 		/* Free this chain buffer and reset
1451 		 * tracker
1452 		 */
1453 		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1454 
1455 		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1456 					+ (chain_idx * ioc->req_sz));
1457 
1458 		spin_lock_irqsave(&ioc->FreeQlock, flags);
1459 		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1460 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1461 
1462 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1463 				ioc->name, chain_idx));
1464 
1465 		/* handle next */
1466 		chain_idx = next;
1467 	}
1468 	return;
1469 }
1470 
1471 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1472 /*
1473  *	Reset Handling
1474  */
1475 
1476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1477 /**
1478  *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1479  *	@hd: Pointer to MPT_SCSI_HOST structure
1480  *	@type: Task Management type
1481  *	@channel: channel number for task management
1482  *	@id: Logical Target ID for reset (if appropriate)
1483  *	@lun: Logical Unit for reset (if appropriate)
1484  *	@ctx2abort: Context for the task to be aborted (if appropriate)
1485  *	@timeout: timeout for task management control
1486  *
1487  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1488  *	or a non-interrupt thread.  In the former, must not call schedule().
1489  *
1490  *	Not all fields are meaningfull for all task types.
1491  *
1492  *	Returns 0 for SUCCESS, or FAILED.
1493  *
1494  **/
1495 int
1496 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1497 	int ctx2abort, ulong timeout)
1498 {
1499 	MPT_FRAME_HDR	*mf;
1500 	SCSITaskMgmt_t	*pScsiTm;
1501 	int		 ii;
1502 	int		 retval;
1503 	MPT_ADAPTER 	*ioc = hd->ioc;
1504 	unsigned long	 timeleft;
1505 	u8		 issue_hard_reset;
1506 	u32		 ioc_raw_state;
1507 	unsigned long	 time_count;
1508 
1509 	issue_hard_reset = 0;
1510 	ioc_raw_state = mpt_GetIocState(ioc, 0);
1511 
1512 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1513 		printk(MYIOC_s_WARN_FMT
1514 			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
1515 			ioc->name, type, ioc_raw_state);
1516 		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
1517 		    ioc->name, __func__);
1518 		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1519 			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
1520 			    "FAILED!!\n", ioc->name);
1521 		return 0;
1522 	}
1523 
1524 	if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1525 		printk(MYIOC_s_WARN_FMT
1526 			"TaskMgmt type=%x: ioc_state: "
1527 			"DOORBELL_ACTIVE (0x%x)!\n",
1528 			ioc->name, type, ioc_raw_state);
1529 		return FAILED;
1530 	}
1531 
1532 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
1533 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
1534 		mf = NULL;
1535 		retval = FAILED;
1536 		goto out;
1537 	}
1538 
1539 	/* Return Fail to calling function if no message frames available.
1540 	 */
1541 	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1542 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1543 			"TaskMgmt no msg frames!!\n", ioc->name));
1544 		retval = FAILED;
1545 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1546 		goto out;
1547 	}
1548 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1549 			ioc->name, mf));
1550 
1551 	/* Format the Request
1552 	 */
1553 	pScsiTm = (SCSITaskMgmt_t *) mf;
1554 	pScsiTm->TargetID = id;
1555 	pScsiTm->Bus = channel;
1556 	pScsiTm->ChainOffset = 0;
1557 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1558 
1559 	pScsiTm->Reserved = 0;
1560 	pScsiTm->TaskType = type;
1561 	pScsiTm->Reserved1 = 0;
1562 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1563                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1564 
1565 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1566 
1567 	for (ii=0; ii < 7; ii++)
1568 		pScsiTm->Reserved2[ii] = 0;
1569 
1570 	pScsiTm->TaskMsgContext = ctx2abort;
1571 
1572 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
1573 		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
1574 		type, timeout));
1575 
1576 	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1577 
1578 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1579 	time_count = jiffies;
1580 	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1581 	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1582 		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1583 	else {
1584 		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1585 			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1586 		if (retval) {
1587 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1588 				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
1589 				ioc->name, mf, retval));
1590 			mpt_free_msg_frame(ioc, mf);
1591 			mpt_clear_taskmgmt_in_progress_flag(ioc);
1592 			goto out;
1593 		}
1594 	}
1595 
1596 	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
1597 		timeout*HZ);
1598 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
1599 		retval = FAILED;
1600 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
1601 		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
1602 		mpt_clear_taskmgmt_in_progress_flag(ioc);
1603 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
1604 			goto out;
1605 		issue_hard_reset = 1;
1606 		goto out;
1607 	}
1608 
1609 	retval = mptscsih_taskmgmt_reply(ioc, type,
1610 	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
1611 
1612 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1613 	    "TaskMgmt completed (%d seconds)\n",
1614 	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
1615 
1616  out:
1617 
1618 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
1619 	if (issue_hard_reset) {
1620 		printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
1621 			ioc->name, __func__);
1622 		retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1623 		mpt_free_msg_frame(ioc, mf);
1624 	}
1625 
1626 	retval = (retval == 0) ? 0 : FAILED;
1627 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
1628 	return retval;
1629 }
1630 EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
1631 
1632 static int
1633 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1634 {
1635 	switch (ioc->bus_type) {
1636 	case FC:
1637 		return 40;
1638 	case SAS:
1639 	case SPI:
1640 	default:
1641 		return 10;
1642 	}
1643 }
1644 
1645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1646 /**
1647  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1648  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1649  *
1650  *	(linux scsi_host_template.eh_abort_handler routine)
1651  *
1652  *	Returns SUCCESS or FAILED.
1653  **/
1654 int
1655 mptscsih_abort(struct scsi_cmnd * SCpnt)
1656 {
1657 	MPT_SCSI_HOST	*hd;
1658 	MPT_FRAME_HDR	*mf;
1659 	u32		 ctx2abort;
1660 	int		 scpnt_idx;
1661 	int		 retval;
1662 	VirtDevice	 *vdevice;
1663 	ulong	 	 sn = SCpnt->serial_number;
1664 	MPT_ADAPTER	*ioc;
1665 
1666 	/* If we can't locate our host adapter structure, return FAILED status.
1667 	 */
1668 	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1669 		SCpnt->result = DID_RESET << 16;
1670 		SCpnt->scsi_done(SCpnt);
1671 		printk(KERN_ERR MYNAM ": task abort: "
1672 		    "can't locate host! (sc=%p)\n", SCpnt);
1673 		return FAILED;
1674 	}
1675 
1676 	ioc = hd->ioc;
1677 	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1678 	       ioc->name, SCpnt);
1679 	scsi_print_command(SCpnt);
1680 
1681 	vdevice = SCpnt->device->hostdata;
1682 	if (!vdevice || !vdevice->vtarget) {
1683 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1684 		    "task abort: device has been deleted (sc=%p)\n",
1685 		    ioc->name, SCpnt));
1686 		SCpnt->result = DID_NO_CONNECT << 16;
1687 		SCpnt->scsi_done(SCpnt);
1688 		retval = 0;
1689 		goto out;
1690 	}
1691 
1692 	/* Task aborts are not supported for hidden raid components.
1693 	 */
1694 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1695 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1696 		    "task abort: hidden raid component (sc=%p)\n",
1697 		    ioc->name, SCpnt));
1698 		SCpnt->result = DID_RESET << 16;
1699 		retval = FAILED;
1700 		goto out;
1701 	}
1702 
1703 	/* Find this command
1704 	 */
1705 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
1706 		/* Cmd not found in ScsiLookup.
1707 		 * Do OS callback.
1708 		 */
1709 		SCpnt->result = DID_RESET << 16;
1710 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1711 		   "Command not in the active list! (sc=%p)\n", ioc->name,
1712 		   SCpnt));
1713 		retval = 0;
1714 		goto out;
1715 	}
1716 
1717 	if (ioc->timeouts < -1)
1718 		ioc->timeouts++;
1719 
1720 	if (mpt_fwfault_debug)
1721 		mpt_halt_firmware(ioc);
1722 
1723 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1724 	 * (the IO to be ABORT'd)
1725 	 *
1726 	 * NOTE: Since we do not byteswap MsgContext, we do not
1727 	 *	 swap it here either.  It is an opaque cookie to
1728 	 *	 the controller, so it does not matter. -DaveM
1729 	 */
1730 	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1731 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1732 
1733 	hd->abortSCpnt = SCpnt;
1734 
1735 	retval = mptscsih_IssueTaskMgmt(hd,
1736 			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1737 			 vdevice->vtarget->channel,
1738 			 vdevice->vtarget->id, vdevice->lun,
1739 			 ctx2abort, mptscsih_get_tm_timeout(ioc));
1740 
1741 	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx &&
1742 	    SCpnt->serial_number == sn) {
1743 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1744 		    "task abort: command still in active list! (sc=%p)\n",
1745 		    ioc->name, SCpnt));
1746 		retval = FAILED;
1747 	} else {
1748 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1749 		    "task abort: command cleared from active list! (sc=%p)\n",
1750 		    ioc->name, SCpnt));
1751 		retval = SUCCESS;
1752 	}
1753 
1754  out:
1755 	printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
1756 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt);
1757 
1758 	return retval;
1759 }
1760 
1761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1762 /**
1763  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1764  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1765  *
1766  *	(linux scsi_host_template.eh_dev_reset_handler routine)
1767  *
1768  *	Returns SUCCESS or FAILED.
1769  **/
1770 int
1771 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1772 {
1773 	MPT_SCSI_HOST	*hd;
1774 	int		 retval;
1775 	VirtDevice	 *vdevice;
1776 	MPT_ADAPTER	*ioc;
1777 
1778 	/* If we can't locate our host adapter structure, return FAILED status.
1779 	 */
1780 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1781 		printk(KERN_ERR MYNAM ": target reset: "
1782 		   "Can't locate host! (sc=%p)\n", SCpnt);
1783 		return FAILED;
1784 	}
1785 
1786 	ioc = hd->ioc;
1787 	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1788 	       ioc->name, SCpnt);
1789 	scsi_print_command(SCpnt);
1790 
1791 	vdevice = SCpnt->device->hostdata;
1792 	if (!vdevice || !vdevice->vtarget) {
1793 		retval = SUCCESS;
1794 		goto out;
1795 	}
1796 
1797 	/* Target reset to hidden raid component is not supported
1798 	 */
1799 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1800 		retval = FAILED;
1801 		goto out;
1802 	}
1803 
1804 	retval = mptscsih_IssueTaskMgmt(hd,
1805 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1806 				vdevice->vtarget->channel,
1807 				vdevice->vtarget->id, 0, 0,
1808 				mptscsih_get_tm_timeout(ioc));
1809 
1810  out:
1811 	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1812 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1813 
1814 	if (retval == 0)
1815 		return SUCCESS;
1816 	else
1817 		return FAILED;
1818 }
1819 
1820 
1821 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1822 /**
1823  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1824  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1825  *
1826  *	(linux scsi_host_template.eh_bus_reset_handler routine)
1827  *
1828  *	Returns SUCCESS or FAILED.
1829  **/
1830 int
1831 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1832 {
1833 	MPT_SCSI_HOST	*hd;
1834 	int		 retval;
1835 	VirtDevice	 *vdevice;
1836 	MPT_ADAPTER	*ioc;
1837 
1838 	/* If we can't locate our host adapter structure, return FAILED status.
1839 	 */
1840 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1841 		printk(KERN_ERR MYNAM ": bus reset: "
1842 		   "Can't locate host! (sc=%p)\n", SCpnt);
1843 		return FAILED;
1844 	}
1845 
1846 	ioc = hd->ioc;
1847 	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1848 	       ioc->name, SCpnt);
1849 	scsi_print_command(SCpnt);
1850 
1851 	if (ioc->timeouts < -1)
1852 		ioc->timeouts++;
1853 
1854 	vdevice = SCpnt->device->hostdata;
1855 	if (!vdevice || !vdevice->vtarget)
1856 		return SUCCESS;
1857 	retval = mptscsih_IssueTaskMgmt(hd,
1858 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1859 					vdevice->vtarget->channel, 0, 0, 0,
1860 					mptscsih_get_tm_timeout(ioc));
1861 
1862 	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1863 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1864 
1865 	if (retval == 0)
1866 		return SUCCESS;
1867 	else
1868 		return FAILED;
1869 }
1870 
1871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1872 /**
1873  *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1874  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1875  *
1876  *	(linux scsi_host_template.eh_host_reset_handler routine)
1877  *
1878  *	Returns SUCCESS or FAILED.
1879  */
1880 int
1881 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1882 {
1883 	MPT_SCSI_HOST *  hd;
1884 	int              status = SUCCESS;
1885 	MPT_ADAPTER	*ioc;
1886 	int		retval;
1887 
1888 	/*  If we can't locate the host to reset, then we failed. */
1889 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1890 		printk(KERN_ERR MYNAM ": host reset: "
1891 		    "Can't locate host! (sc=%p)\n", SCpnt);
1892 		return FAILED;
1893 	}
1894 
1895 	/* make sure we have no outstanding commands at this stage */
1896 	mptscsih_flush_running_cmds(hd);
1897 
1898 	ioc = hd->ioc;
1899 	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
1900 	    ioc->name, SCpnt);
1901 
1902 	/*  If our attempts to reset the host failed, then return a failed
1903 	 *  status.  The host will be taken off line by the SCSI mid-layer.
1904 	 */
1905     retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1906 	if (retval < 0)
1907 		status = FAILED;
1908 	else
1909 		status = SUCCESS;
1910 
1911 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
1912 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1913 
1914 	return status;
1915 }
1916 
1917 static int
1918 mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
1919 	SCSITaskMgmtReply_t *pScsiTmReply)
1920 {
1921 	u16			 iocstatus;
1922 	u32			 termination_count;
1923 	int			 retval;
1924 
1925 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
1926 		retval = FAILED;
1927 		goto out;
1928 	}
1929 
1930 	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
1931 
1932 	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
1933 	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
1934 
1935 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1936 	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
1937 	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
1938 	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
1939 	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
1940 	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
1941 	    termination_count));
1942 
1943 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
1944 	    pScsiTmReply->ResponseCode)
1945 		mptscsih_taskmgmt_response_code(ioc,
1946 		    pScsiTmReply->ResponseCode);
1947 
1948 	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
1949 		retval = 0;
1950 		goto out;
1951 	}
1952 
1953 	retval = FAILED;
1954 	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1955 		if (termination_count == 1)
1956 			retval = 0;
1957 		goto out;
1958 	}
1959 
1960 	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1961 	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1962 		retval = 0;
1963 
1964  out:
1965 	return retval;
1966 }
1967 
1968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1969 void
1970 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
1971 {
1972 	char *desc;
1973 
1974 	switch (response_code) {
1975 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
1976 		desc = "The task completed.";
1977 		break;
1978 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
1979 		desc = "The IOC received an invalid frame status.";
1980 		break;
1981 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1982 		desc = "The task type is not supported.";
1983 		break;
1984 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
1985 		desc = "The requested task failed.";
1986 		break;
1987 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1988 		desc = "The task completed successfully.";
1989 		break;
1990 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1991 		desc = "The LUN request is invalid.";
1992 		break;
1993 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1994 		desc = "The task is in the IOC queue and has not been sent to target.";
1995 		break;
1996 	default:
1997 		desc = "unknown";
1998 		break;
1999 	}
2000 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2001 		ioc->name, response_code, desc);
2002 }
2003 EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
2004 
2005 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2006 /**
2007  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2008  *	@ioc: Pointer to MPT_ADAPTER structure
2009  *	@mf: Pointer to SCSI task mgmt request frame
2010  *	@mr: Pointer to SCSI task mgmt reply frame
2011  *
2012  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2013  *	of any SCSI task management request.
2014  *	This routine is registered with the MPT (base) driver at driver
2015  *	load/init time via the mpt_register() API call.
2016  *
2017  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2018  **/
2019 int
2020 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
2021 	MPT_FRAME_HDR *mr)
2022 {
2023 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2024 		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
2025 
2026 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2027 
2028 	if (!mr)
2029 		goto out;
2030 
2031 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2032 	memcpy(ioc->taskmgmt_cmds.reply, mr,
2033 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
2034  out:
2035 	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
2036 		mpt_clear_taskmgmt_in_progress_flag(ioc);
2037 		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2038 		complete(&ioc->taskmgmt_cmds.done);
2039 		return 1;
2040 	}
2041 	return 0;
2042 }
2043 
2044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2045 /*
2046  *	This is anyones guess quite frankly.
2047  */
2048 int
2049 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2050 		sector_t capacity, int geom[])
2051 {
2052 	int		heads;
2053 	int		sectors;
2054 	sector_t	cylinders;
2055 	ulong 		dummy;
2056 
2057 	heads = 64;
2058 	sectors = 32;
2059 
2060 	dummy = heads * sectors;
2061 	cylinders = capacity;
2062 	sector_div(cylinders,dummy);
2063 
2064 	/*
2065 	 * Handle extended translation size for logical drives
2066 	 * > 1Gb
2067 	 */
2068 	if ((ulong)capacity >= 0x200000) {
2069 		heads = 255;
2070 		sectors = 63;
2071 		dummy = heads * sectors;
2072 		cylinders = capacity;
2073 		sector_div(cylinders,dummy);
2074 	}
2075 
2076 	/* return result */
2077 	geom[0] = heads;
2078 	geom[1] = sectors;
2079 	geom[2] = cylinders;
2080 
2081 	return 0;
2082 }
2083 
2084 /* Search IOC page 3 to determine if this is hidden physical disk
2085  *
2086  */
2087 int
2088 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2089 {
2090 	struct inactive_raid_component_info *component_info;
2091 	int i, j;
2092 	RaidPhysDiskPage1_t *phys_disk;
2093 	int rc = 0;
2094 	int num_paths;
2095 
2096 	if (!ioc->raid_data.pIocPg3)
2097 		goto out;
2098 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2099 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2100 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2101 			rc = 1;
2102 			goto out;
2103 		}
2104 	}
2105 
2106 	if (ioc->bus_type != SAS)
2107 		goto out;
2108 
2109 	/*
2110 	 * Check if dual path
2111 	 */
2112 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2113 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2114 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2115 		if (num_paths < 2)
2116 			continue;
2117 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2118 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2119 		if (!phys_disk)
2120 			continue;
2121 		if ((mpt_raid_phys_disk_pg1(ioc,
2122 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2123 		    phys_disk))) {
2124 			kfree(phys_disk);
2125 			continue;
2126 		}
2127 		for (j = 0; j < num_paths; j++) {
2128 			if ((phys_disk->Path[j].Flags &
2129 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2130 				continue;
2131 			if ((phys_disk->Path[j].Flags &
2132 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2133 				continue;
2134 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2135 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2136 				rc = 1;
2137 				kfree(phys_disk);
2138 				goto out;
2139 			}
2140 		}
2141 		kfree(phys_disk);
2142 	}
2143 
2144 
2145 	/*
2146 	 * Check inactive list for matching phys disks
2147 	 */
2148 	if (list_empty(&ioc->raid_data.inactive_list))
2149 		goto out;
2150 
2151 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2152 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2153 	    list) {
2154 		if ((component_info->d.PhysDiskID == id) &&
2155 		    (component_info->d.PhysDiskBus == channel))
2156 			rc = 1;
2157 	}
2158 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2159 
2160  out:
2161 	return rc;
2162 }
2163 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2164 
2165 u8
2166 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2167 {
2168 	struct inactive_raid_component_info *component_info;
2169 	int i, j;
2170 	RaidPhysDiskPage1_t *phys_disk;
2171 	int rc = -ENXIO;
2172 	int num_paths;
2173 
2174 	if (!ioc->raid_data.pIocPg3)
2175 		goto out;
2176 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2177 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2178 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2179 			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2180 			goto out;
2181 		}
2182 	}
2183 
2184 	if (ioc->bus_type != SAS)
2185 		goto out;
2186 
2187 	/*
2188 	 * Check if dual path
2189 	 */
2190 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2191 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2192 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2193 		if (num_paths < 2)
2194 			continue;
2195 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2196 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2197 		if (!phys_disk)
2198 			continue;
2199 		if ((mpt_raid_phys_disk_pg1(ioc,
2200 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2201 		    phys_disk))) {
2202 			kfree(phys_disk);
2203 			continue;
2204 		}
2205 		for (j = 0; j < num_paths; j++) {
2206 			if ((phys_disk->Path[j].Flags &
2207 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
2208 				continue;
2209 			if ((phys_disk->Path[j].Flags &
2210 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2211 				continue;
2212 			if ((id == phys_disk->Path[j].PhysDiskID) &&
2213 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
2214 				rc = phys_disk->PhysDiskNum;
2215 				kfree(phys_disk);
2216 				goto out;
2217 			}
2218 		}
2219 		kfree(phys_disk);
2220 	}
2221 
2222 	/*
2223 	 * Check inactive list for matching phys disks
2224 	 */
2225 	if (list_empty(&ioc->raid_data.inactive_list))
2226 		goto out;
2227 
2228 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
2229 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2230 	    list) {
2231 		if ((component_info->d.PhysDiskID == id) &&
2232 		    (component_info->d.PhysDiskBus == channel))
2233 			rc = component_info->d.PhysDiskNum;
2234 	}
2235 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
2236 
2237  out:
2238 	return rc;
2239 }
2240 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2241 
2242 /*
2243  *	OS entry point to allow for host driver to free allocated memory
2244  *	Called if no device present or device being unloaded
2245  */
2246 void
2247 mptscsih_slave_destroy(struct scsi_device *sdev)
2248 {
2249 	struct Scsi_Host	*host = sdev->host;
2250 	MPT_SCSI_HOST		*hd = shost_priv(host);
2251 	VirtTarget		*vtarget;
2252 	VirtDevice		*vdevice;
2253 	struct scsi_target 	*starget;
2254 
2255 	starget = scsi_target(sdev);
2256 	vtarget = starget->hostdata;
2257 	vdevice = sdev->hostdata;
2258 
2259 	mptscsih_search_running_cmds(hd, vdevice);
2260 	vtarget->num_luns--;
2261 	mptscsih_synchronize_cache(hd, vdevice);
2262 	kfree(vdevice);
2263 	sdev->hostdata = NULL;
2264 }
2265 
2266 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2267 /*
2268  *	mptscsih_change_queue_depth - This function will set a devices queue depth
2269  *	@sdev: per scsi_device pointer
2270  *	@qdepth: requested queue depth
2271  *
2272  *	Adding support for new 'change_queue_depth' api.
2273 */
2274 int
2275 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2276 {
2277 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
2278 	VirtTarget 		*vtarget;
2279 	struct scsi_target 	*starget;
2280 	int			max_depth;
2281 	int			tagged;
2282 	MPT_ADAPTER		*ioc = hd->ioc;
2283 
2284 	starget = scsi_target(sdev);
2285 	vtarget = starget->hostdata;
2286 
2287 	if (ioc->bus_type == SPI) {
2288 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2289 			max_depth = 1;
2290 		else if (sdev->type == TYPE_DISK &&
2291 			 vtarget->minSyncFactor <= MPT_ULTRA160)
2292 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2293 		else
2294 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2295 	} else
2296 		max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2297 
2298 	if (qdepth > max_depth)
2299 		qdepth = max_depth;
2300 	if (qdepth == 1)
2301 		tagged = 0;
2302 	else
2303 		tagged = MSG_SIMPLE_TAG;
2304 
2305 	scsi_adjust_queue_depth(sdev, tagged, qdepth);
2306 	return sdev->queue_depth;
2307 }
2308 
2309 /*
2310  *	OS entry point to adjust the queue_depths on a per-device basis.
2311  *	Called once per device the bus scan. Use it to force the queue_depth
2312  *	member to 1 if a device does not support Q tags.
2313  *	Return non-zero if fails.
2314  */
2315 int
2316 mptscsih_slave_configure(struct scsi_device *sdev)
2317 {
2318 	struct Scsi_Host	*sh = sdev->host;
2319 	VirtTarget		*vtarget;
2320 	VirtDevice		*vdevice;
2321 	struct scsi_target 	*starget;
2322 	MPT_SCSI_HOST		*hd = shost_priv(sh);
2323 	MPT_ADAPTER		*ioc = hd->ioc;
2324 
2325 	starget = scsi_target(sdev);
2326 	vtarget = starget->hostdata;
2327 	vdevice = sdev->hostdata;
2328 
2329 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2330 		"device @ %p, channel=%d, id=%d, lun=%d\n",
2331 		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2332 	if (ioc->bus_type == SPI)
2333 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2334 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2335 		    ioc->name, sdev->sdtr, sdev->wdtr,
2336 		    sdev->ppr, sdev->inquiry_len));
2337 
2338 	vdevice->configured_lun = 1;
2339 
2340 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2341 		"Queue depth=%d, tflags=%x\n",
2342 		ioc->name, sdev->queue_depth, vtarget->tflags));
2343 
2344 	if (ioc->bus_type == SPI)
2345 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2346 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2347 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2348 		    vtarget->minSyncFactor));
2349 
2350 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2351 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2352 		"tagged %d, simple %d, ordered %d\n",
2353 		ioc->name,sdev->tagged_supported, sdev->simple_tags,
2354 		sdev->ordered_tags));
2355 
2356 	return 0;
2357 }
2358 
2359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2360 /*
2361  *  Private routines...
2362  */
2363 
2364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2365 /* Utility function to copy sense data from the scsi_cmnd buffer
2366  * to the FC and SCSI target structures.
2367  *
2368  */
2369 static void
2370 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2371 {
2372 	VirtDevice	*vdevice;
2373 	SCSIIORequest_t	*pReq;
2374 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2375 	MPT_ADAPTER 	*ioc = hd->ioc;
2376 
2377 	/* Get target structure
2378 	 */
2379 	pReq = (SCSIIORequest_t *) mf;
2380 	vdevice = sc->device->hostdata;
2381 
2382 	if (sense_count) {
2383 		u8 *sense_data;
2384 		int req_index;
2385 
2386 		/* Copy the sense received into the scsi command block. */
2387 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2388 		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2389 		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2390 
2391 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2392 		 */
2393 		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2394 			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2395 				int idx;
2396 
2397 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2398 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2399 				ioc->events[idx].eventContext = ioc->eventContext;
2400 
2401 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2402 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2403 					(sc->device->channel << 8) | sc->device->id;
2404 
2405 				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2406 
2407 				ioc->eventContext++;
2408 				if (ioc->pcidev->vendor ==
2409 				    PCI_VENDOR_ID_IBM) {
2410 					mptscsih_issue_sep_command(ioc,
2411 					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2412 					vdevice->vtarget->tflags |=
2413 					    MPT_TARGET_FLAGS_LED_ON;
2414 				}
2415 			}
2416 		}
2417 	} else {
2418 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2419 				ioc->name));
2420 	}
2421 }
2422 
2423 /**
2424  * mptscsih_get_scsi_lookup - retrieves scmd entry
2425  * @ioc: Pointer to MPT_ADAPTER structure
2426  * @i: index into the array
2427  *
2428  * Returns the scsi_cmd pointer
2429  */
2430 struct scsi_cmnd *
2431 mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
2432 {
2433 	unsigned long	flags;
2434 	struct scsi_cmnd *scmd;
2435 
2436 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2437 	scmd = ioc->ScsiLookup[i];
2438 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2439 
2440 	return scmd;
2441 }
2442 EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
2443 
2444 /**
2445  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
2446  * @ioc: Pointer to MPT_ADAPTER structure
2447  * @i: index into the array
2448  *
2449  * Returns the scsi_cmd pointer
2450  *
2451  **/
2452 static struct scsi_cmnd *
2453 mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
2454 {
2455 	unsigned long	flags;
2456 	struct scsi_cmnd *scmd;
2457 
2458 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2459 	scmd = ioc->ScsiLookup[i];
2460 	ioc->ScsiLookup[i] = NULL;
2461 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2462 
2463 	return scmd;
2464 }
2465 
2466 /**
2467  * mptscsih_set_scsi_lookup
2468  *
2469  * writes a scmd entry into the ScsiLookup[] array list
2470  *
2471  * @ioc: Pointer to MPT_ADAPTER structure
2472  * @i: index into the array
2473  * @scmd: scsi_cmnd pointer
2474  *
2475  **/
2476 static void
2477 mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2478 {
2479 	unsigned long	flags;
2480 
2481 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2482 	ioc->ScsiLookup[i] = scmd;
2483 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2484 }
2485 
2486 /**
2487  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2488  * @ioc: Pointer to MPT_ADAPTER structure
2489  * @sc: scsi_cmnd pointer
2490  */
2491 static int
2492 SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2493 {
2494 	unsigned long	flags;
2495 	int i, index=-1;
2496 
2497 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
2498 	for (i = 0; i < ioc->req_depth; i++) {
2499 		if (ioc->ScsiLookup[i] == sc) {
2500 			index = i;
2501 			goto out;
2502 		}
2503 	}
2504 
2505  out:
2506 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
2507 	return index;
2508 }
2509 
2510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2511 int
2512 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2513 {
2514 	MPT_SCSI_HOST	*hd;
2515 
2516 	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2517 		return 0;
2518 
2519 	hd = shost_priv(ioc->sh);
2520 	switch (reset_phase) {
2521 	case MPT_IOC_SETUP_RESET:
2522 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2523 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
2524 		break;
2525 	case MPT_IOC_PRE_RESET:
2526 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2527 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
2528 		mptscsih_flush_running_cmds(hd);
2529 		break;
2530 	case MPT_IOC_POST_RESET:
2531 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2532 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
2533 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
2534 			ioc->internal_cmds.status |=
2535 				MPT_MGMT_STATUS_DID_IOCRESET;
2536 			complete(&ioc->internal_cmds.done);
2537 		}
2538 		break;
2539 	default:
2540 		break;
2541 	}
2542 	return 1;		/* currently means nothing really */
2543 }
2544 
2545 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2546 int
2547 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2548 {
2549 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2550 
2551 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2552 		"MPT event (=%02Xh) routed to SCSI host driver!\n",
2553 		ioc->name, event));
2554 
2555 	if ((event == MPI_EVENT_IOC_BUS_RESET ||
2556 	    event == MPI_EVENT_EXT_BUS_RESET) &&
2557 	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
2558 			ioc->soft_resets++;
2559 
2560 	return 1;		/* currently means nothing really */
2561 }
2562 
2563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2564 /*
2565  *  Bus Scan and Domain Validation functionality ...
2566  */
2567 
2568 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2569 /*
2570  *	mptscsih_scandv_complete - Scan and DV callback routine registered
2571  *	to Fustion MPT (base) driver.
2572  *
2573  *	@ioc: Pointer to MPT_ADAPTER structure
2574  *	@mf: Pointer to original MPT request frame
2575  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2576  *
2577  *	This routine is called from mpt.c::mpt_interrupt() at the completion
2578  *	of any SCSI IO request.
2579  *	This routine is registered with the Fusion MPT (base) driver at driver
2580  *	load/init time via the mpt_register() API call.
2581  *
2582  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2583  *
2584  *	Remark: Sets a completion code and (possibly) saves sense data
2585  *	in the IOC member localReply structure.
2586  *	Used ONLY for DV and other internal commands.
2587  */
2588 int
2589 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2590 				MPT_FRAME_HDR *reply)
2591 {
2592 	SCSIIORequest_t *pReq;
2593 	SCSIIOReply_t	*pReply;
2594 	u8		 cmd;
2595 	u16		 req_idx;
2596 	u8	*sense_data;
2597 	int		 sz;
2598 
2599 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2600 	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
2601 	if (!reply)
2602 		goto out;
2603 
2604 	pReply = (SCSIIOReply_t *) reply;
2605 	pReq = (SCSIIORequest_t *) req;
2606 	ioc->internal_cmds.completion_code =
2607 	    mptscsih_get_completion_code(ioc, req, reply);
2608 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
2609 	memcpy(ioc->internal_cmds.reply, reply,
2610 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
2611 	cmd = reply->u.hdr.Function;
2612 	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
2613 	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
2614 	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
2615 		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
2616 		sense_data = ((u8 *)ioc->sense_buf_pool +
2617 		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
2618 		sz = min_t(int, pReq->SenseBufferLength,
2619 		    MPT_SENSE_BUFFER_ALLOC);
2620 		memcpy(ioc->internal_cmds.sense, sense_data, sz);
2621 	}
2622  out:
2623 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
2624 		return 0;
2625 	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
2626 	complete(&ioc->internal_cmds.done);
2627 	return 1;
2628 }
2629 
2630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2631 /*	mptscsih_timer_expired - Call back for timer process.
2632  *	Used only for dv functionality.
2633  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2634  *
2635  */
2636 void
2637 mptscsih_timer_expired(unsigned long data)
2638 {
2639 	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2640 	MPT_ADAPTER 	*ioc = hd->ioc;
2641 
2642 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr));
2643 
2644 	if (hd->cmdPtr) {
2645 		MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2646 
2647 		if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2648 			/* Desire to issue a task management request here.
2649 			 * TM requests MUST be single threaded.
2650 			 * If old eh code and no TM current, issue request.
2651 			 * If new eh code, do nothing. Wait for OS cmd timeout
2652 			 *	for bus reset.
2653 			 */
2654 		} else {
2655 			/* Perform a FW reload */
2656 			if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2657 				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
2658 			}
2659 		}
2660 	} else {
2661 		/* This should NEVER happen */
2662 		printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name);
2663 	}
2664 
2665 	/* No more processing.
2666 	 * TM call will generate an interrupt for SCSI TM Management.
2667 	 * The FW will reply to all outstanding commands, callback will finish cleanup.
2668 	 * Hard reset clean-up will free all resources.
2669 	 */
2670 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name));
2671 
2672 	return;
2673 }
2674 
2675 /**
2676  *	mptscsih_get_completion_code -
2677  *	@ioc: Pointer to MPT_ADAPTER structure
2678  *	@req: Pointer to original MPT request frame
2679  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
2680  *
2681  **/
2682 static int
2683 mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2684 				MPT_FRAME_HDR *reply)
2685 {
2686 	SCSIIOReply_t	*pReply;
2687 	MpiRaidActionReply_t *pr;
2688 	u8		 scsi_status;
2689 	u16		 status;
2690 	int		 completion_code;
2691 
2692 	pReply = (SCSIIOReply_t *)reply;
2693 	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2694 	scsi_status = pReply->SCSIStatus;
2695 
2696 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2697 	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
2698 	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
2699 	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
2700 
2701 	switch (status) {
2702 
2703 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2704 		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
2705 		break;
2706 
2707 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2708 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2709 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2710 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2711 		completion_code = MPT_SCANDV_DID_RESET;
2712 		break;
2713 
2714 	case MPI_IOCSTATUS_BUSY:
2715 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
2716 		completion_code = MPT_SCANDV_BUSY;
2717 		break;
2718 
2719 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2720 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2721 	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2722 		if (pReply->Function == MPI_FUNCTION_CONFIG) {
2723 			completion_code = MPT_SCANDV_GOOD;
2724 		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2725 			pr = (MpiRaidActionReply_t *)reply;
2726 			if (le16_to_cpu(pr->ActionStatus) ==
2727 				MPI_RAID_ACTION_ASTATUS_SUCCESS)
2728 				completion_code = MPT_SCANDV_GOOD;
2729 			else
2730 				completion_code = MPT_SCANDV_SOME_ERROR;
2731 		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
2732 			completion_code = MPT_SCANDV_SENSE;
2733 		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2734 			if (req->u.scsireq.CDB[0] == INQUIRY)
2735 				completion_code = MPT_SCANDV_ISSUE_SENSE;
2736 			else
2737 				completion_code = MPT_SCANDV_DID_RESET;
2738 		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2739 			completion_code = MPT_SCANDV_DID_RESET;
2740 		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2741 			completion_code = MPT_SCANDV_DID_RESET;
2742 		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
2743 			completion_code = MPT_SCANDV_BUSY;
2744 		else
2745 			completion_code = MPT_SCANDV_GOOD;
2746 		break;
2747 
2748 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
2749 		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2750 			completion_code = MPT_SCANDV_DID_RESET;
2751 		else
2752 			completion_code = MPT_SCANDV_SOME_ERROR;
2753 		break;
2754 	default:
2755 		completion_code = MPT_SCANDV_SOME_ERROR;
2756 		break;
2757 
2758 	}	/* switch(status) */
2759 
2760 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2761 	    "  completionCode set to %08xh\n", ioc->name, completion_code));
2762 	return completion_code;
2763 }
2764 
2765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2766 /**
2767  *	mptscsih_do_cmd - Do internal command.
2768  *	@hd: MPT_SCSI_HOST pointer
2769  *	@io: INTERNAL_CMD pointer.
2770  *
2771  *	Issue the specified internally generated command and do command
2772  *	specific cleanup. For bus scan / DV only.
2773  *	NOTES: If command is Inquiry and status is good,
2774  *	initialize a target structure, save the data
2775  *
2776  *	Remark: Single threaded access only.
2777  *
2778  *	Return:
2779  *		< 0 if an illegal command or no resources
2780  *
2781  *		   0 if good
2782  *
2783  *		 > 0 if command complete but some type of completion error.
2784  */
2785 static int
2786 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2787 {
2788 	MPT_FRAME_HDR	*mf;
2789 	SCSIIORequest_t	*pScsiReq;
2790 	int		 my_idx, ii, dir;
2791 	int		 timeout;
2792 	char		 cmdLen;
2793 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2794 	u8		 cmd = io->cmd;
2795 	MPT_ADAPTER *ioc = hd->ioc;
2796 	int		 ret = 0;
2797 	unsigned long	 timeleft;
2798 	unsigned long	 flags;
2799 
2800 	/* don't send internal command during diag reset */
2801 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2802 	if (ioc->ioc_reset_in_progress) {
2803 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2804 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2805 			"%s: busy with host reset\n", ioc->name, __func__));
2806 		return MPT_SCANDV_BUSY;
2807 	}
2808 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2809 
2810 	mutex_lock(&ioc->internal_cmds.mutex);
2811 
2812 	/* Set command specific information
2813 	 */
2814 	switch (cmd) {
2815 	case INQUIRY:
2816 		cmdLen = 6;
2817 		dir = MPI_SCSIIO_CONTROL_READ;
2818 		CDB[0] = cmd;
2819 		CDB[4] = io->size;
2820 		timeout = 10;
2821 		break;
2822 
2823 	case TEST_UNIT_READY:
2824 		cmdLen = 6;
2825 		dir = MPI_SCSIIO_CONTROL_READ;
2826 		timeout = 10;
2827 		break;
2828 
2829 	case START_STOP:
2830 		cmdLen = 6;
2831 		dir = MPI_SCSIIO_CONTROL_READ;
2832 		CDB[0] = cmd;
2833 		CDB[4] = 1;	/*Spin up the disk */
2834 		timeout = 15;
2835 		break;
2836 
2837 	case REQUEST_SENSE:
2838 		cmdLen = 6;
2839 		CDB[0] = cmd;
2840 		CDB[4] = io->size;
2841 		dir = MPI_SCSIIO_CONTROL_READ;
2842 		timeout = 10;
2843 		break;
2844 
2845 	case READ_BUFFER:
2846 		cmdLen = 10;
2847 		dir = MPI_SCSIIO_CONTROL_READ;
2848 		CDB[0] = cmd;
2849 		if (io->flags & MPT_ICFLAG_ECHO) {
2850 			CDB[1] = 0x0A;
2851 		} else {
2852 			CDB[1] = 0x02;
2853 		}
2854 
2855 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
2856 			CDB[1] |= 0x01;
2857 		}
2858 		CDB[6] = (io->size >> 16) & 0xFF;
2859 		CDB[7] = (io->size >>  8) & 0xFF;
2860 		CDB[8] = io->size & 0xFF;
2861 		timeout = 10;
2862 		break;
2863 
2864 	case WRITE_BUFFER:
2865 		cmdLen = 10;
2866 		dir = MPI_SCSIIO_CONTROL_WRITE;
2867 		CDB[0] = cmd;
2868 		if (io->flags & MPT_ICFLAG_ECHO) {
2869 			CDB[1] = 0x0A;
2870 		} else {
2871 			CDB[1] = 0x02;
2872 		}
2873 		CDB[6] = (io->size >> 16) & 0xFF;
2874 		CDB[7] = (io->size >>  8) & 0xFF;
2875 		CDB[8] = io->size & 0xFF;
2876 		timeout = 10;
2877 		break;
2878 
2879 	case RESERVE:
2880 		cmdLen = 6;
2881 		dir = MPI_SCSIIO_CONTROL_READ;
2882 		CDB[0] = cmd;
2883 		timeout = 10;
2884 		break;
2885 
2886 	case RELEASE:
2887 		cmdLen = 6;
2888 		dir = MPI_SCSIIO_CONTROL_READ;
2889 		CDB[0] = cmd;
2890 		timeout = 10;
2891 		break;
2892 
2893 	case SYNCHRONIZE_CACHE:
2894 		cmdLen = 10;
2895 		dir = MPI_SCSIIO_CONTROL_READ;
2896 		CDB[0] = cmd;
2897 //		CDB[1] = 0x02;	/* set immediate bit */
2898 		timeout = 10;
2899 		break;
2900 
2901 	default:
2902 		/* Error Case */
2903 		ret = -EFAULT;
2904 		goto out;
2905 	}
2906 
2907 	/* Get and Populate a free Frame
2908 	 * MsgContext set in mpt_get_msg_frame call
2909 	 */
2910 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
2911 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
2912 		    ioc->name, __func__));
2913 		ret = MPT_SCANDV_BUSY;
2914 		goto out;
2915 	}
2916 
2917 	pScsiReq = (SCSIIORequest_t *) mf;
2918 
2919 	/* Get the request index */
2920 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2921 	ADD_INDEX_LOG(my_idx); /* for debug */
2922 
2923 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
2924 		pScsiReq->TargetID = io->physDiskNum;
2925 		pScsiReq->Bus = 0;
2926 		pScsiReq->ChainOffset = 0;
2927 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
2928 	} else {
2929 		pScsiReq->TargetID = io->id;
2930 		pScsiReq->Bus = io->channel;
2931 		pScsiReq->ChainOffset = 0;
2932 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
2933 	}
2934 
2935 	pScsiReq->CDBLength = cmdLen;
2936 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2937 
2938 	pScsiReq->Reserved = 0;
2939 
2940 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
2941 	/* MsgContext set in mpt_get_msg_fram call  */
2942 
2943 	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
2944 
2945 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
2946 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
2947 	else
2948 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2949 
2950 	if (cmd == REQUEST_SENSE) {
2951 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
2952 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2953 		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
2954 	}
2955 
2956 	for (ii = 0; ii < 16; ii++)
2957 		pScsiReq->CDB[ii] = CDB[ii];
2958 
2959 	pScsiReq->DataLength = cpu_to_le32(io->size);
2960 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
2961 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
2962 
2963 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2964 	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%d\n",
2965 	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
2966 
2967 	if (dir == MPI_SCSIIO_CONTROL_READ)
2968 		ioc->add_sge((char *) &pScsiReq->SGL,
2969 		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
2970 	else
2971 		ioc->add_sge((char *) &pScsiReq->SGL,
2972 		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
2973 
2974 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
2975 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
2976 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
2977 	    timeout*HZ);
2978 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2979 		ret = MPT_SCANDV_DID_RESET;
2980 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2981 		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
2982 		    cmd));
2983 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2984 			mpt_free_msg_frame(ioc, mf);
2985 			goto out;
2986 		}
2987 		if (!timeleft) {
2988 			printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
2989 			    ioc->name, __func__);
2990 			mpt_HardResetHandler(ioc, CAN_SLEEP);
2991 			mpt_free_msg_frame(ioc, mf);
2992 		}
2993 		goto out;
2994 	}
2995 
2996 	ret = ioc->internal_cmds.completion_code;
2997 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
2998 			ioc->name, __func__, ret));
2999 
3000  out:
3001 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
3002 	mutex_unlock(&ioc->internal_cmds.mutex);
3003 	return ret;
3004 }
3005 
3006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3007 /**
3008  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3009  *	@hd: Pointer to a SCSI HOST structure
3010  *	@vdevice: virtual target device
3011  *
3012  *	Uses the ISR, but with special processing.
3013  *	MUST be single-threaded.
3014  *
3015  */
3016 static void
3017 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3018 {
3019 	INTERNAL_CMD		 iocmd;
3020 
3021 	/* Ignore hidden raid components, this is handled when the command
3022 	 * is sent to the volume
3023 	 */
3024 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3025 		return;
3026 
3027 	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3028 	    !vdevice->configured_lun)
3029 		return;
3030 
3031 	/* Following parameters will not change
3032 	 * in this routine.
3033 	 */
3034 	iocmd.cmd = SYNCHRONIZE_CACHE;
3035 	iocmd.flags = 0;
3036 	iocmd.physDiskNum = -1;
3037 	iocmd.data = NULL;
3038 	iocmd.data_dma = -1;
3039 	iocmd.size = 0;
3040 	iocmd.rsvd = iocmd.rsvd2 = 0;
3041 	iocmd.channel = vdevice->vtarget->channel;
3042 	iocmd.id = vdevice->vtarget->id;
3043 	iocmd.lun = vdevice->lun;
3044 
3045 	mptscsih_do_cmd(hd, &iocmd);
3046 }
3047 
3048 static ssize_t
3049 mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
3050 			 char *buf)
3051 {
3052 	struct Scsi_Host *host = class_to_shost(dev);
3053 	MPT_SCSI_HOST	*hd = shost_priv(host);
3054 	MPT_ADAPTER *ioc = hd->ioc;
3055 
3056 	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3057 	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3058 	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3059 	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3060 	    ioc->facts.FWVersion.Word & 0x000000FF);
3061 }
3062 static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3063 
3064 static ssize_t
3065 mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
3066 			   char *buf)
3067 {
3068 	struct Scsi_Host *host = class_to_shost(dev);
3069 	MPT_SCSI_HOST	*hd = shost_priv(host);
3070 	MPT_ADAPTER *ioc = hd->ioc;
3071 
3072 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3073 	    (ioc->biosVersion & 0xFF000000) >> 24,
3074 	    (ioc->biosVersion & 0x00FF0000) >> 16,
3075 	    (ioc->biosVersion & 0x0000FF00) >> 8,
3076 	    ioc->biosVersion & 0x000000FF);
3077 }
3078 static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3079 
3080 static ssize_t
3081 mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
3082 			  char *buf)
3083 {
3084 	struct Scsi_Host *host = class_to_shost(dev);
3085 	MPT_SCSI_HOST	*hd = shost_priv(host);
3086 	MPT_ADAPTER *ioc = hd->ioc;
3087 
3088 	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3089 }
3090 static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3091 
3092 static ssize_t
3093 mptscsih_version_product_show(struct device *dev,
3094 			      struct device_attribute *attr,
3095 char *buf)
3096 {
3097 	struct Scsi_Host *host = class_to_shost(dev);
3098 	MPT_SCSI_HOST	*hd = shost_priv(host);
3099 	MPT_ADAPTER *ioc = hd->ioc;
3100 
3101 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3102 }
3103 static DEVICE_ATTR(version_product, S_IRUGO,
3104     mptscsih_version_product_show, NULL);
3105 
3106 static ssize_t
3107 mptscsih_version_nvdata_persistent_show(struct device *dev,
3108 					struct device_attribute *attr,
3109 					char *buf)
3110 {
3111 	struct Scsi_Host *host = class_to_shost(dev);
3112 	MPT_SCSI_HOST	*hd = shost_priv(host);
3113 	MPT_ADAPTER *ioc = hd->ioc;
3114 
3115 	return snprintf(buf, PAGE_SIZE, "%02xh\n",
3116 	    ioc->nvdata_version_persistent);
3117 }
3118 static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3119     mptscsih_version_nvdata_persistent_show, NULL);
3120 
3121 static ssize_t
3122 mptscsih_version_nvdata_default_show(struct device *dev,
3123 				     struct device_attribute *attr, char *buf)
3124 {
3125 	struct Scsi_Host *host = class_to_shost(dev);
3126 	MPT_SCSI_HOST	*hd = shost_priv(host);
3127 	MPT_ADAPTER *ioc = hd->ioc;
3128 
3129 	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3130 }
3131 static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3132     mptscsih_version_nvdata_default_show, NULL);
3133 
3134 static ssize_t
3135 mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
3136 			 char *buf)
3137 {
3138 	struct Scsi_Host *host = class_to_shost(dev);
3139 	MPT_SCSI_HOST	*hd = shost_priv(host);
3140 	MPT_ADAPTER *ioc = hd->ioc;
3141 
3142 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3143 }
3144 static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3145 
3146 static ssize_t
3147 mptscsih_board_assembly_show(struct device *dev,
3148 			     struct device_attribute *attr, char *buf)
3149 {
3150 	struct Scsi_Host *host = class_to_shost(dev);
3151 	MPT_SCSI_HOST	*hd = shost_priv(host);
3152 	MPT_ADAPTER *ioc = hd->ioc;
3153 
3154 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3155 }
3156 static DEVICE_ATTR(board_assembly, S_IRUGO,
3157     mptscsih_board_assembly_show, NULL);
3158 
3159 static ssize_t
3160 mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
3161 			   char *buf)
3162 {
3163 	struct Scsi_Host *host = class_to_shost(dev);
3164 	MPT_SCSI_HOST	*hd = shost_priv(host);
3165 	MPT_ADAPTER *ioc = hd->ioc;
3166 
3167 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3168 }
3169 static DEVICE_ATTR(board_tracer, S_IRUGO,
3170     mptscsih_board_tracer_show, NULL);
3171 
3172 static ssize_t
3173 mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
3174 		       char *buf)
3175 {
3176 	struct Scsi_Host *host = class_to_shost(dev);
3177 	MPT_SCSI_HOST	*hd = shost_priv(host);
3178 	MPT_ADAPTER *ioc = hd->ioc;
3179 
3180 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3181 }
3182 static DEVICE_ATTR(io_delay, S_IRUGO,
3183     mptscsih_io_delay_show, NULL);
3184 
3185 static ssize_t
3186 mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
3187 			   char *buf)
3188 {
3189 	struct Scsi_Host *host = class_to_shost(dev);
3190 	MPT_SCSI_HOST	*hd = shost_priv(host);
3191 	MPT_ADAPTER *ioc = hd->ioc;
3192 
3193 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3194 }
3195 static DEVICE_ATTR(device_delay, S_IRUGO,
3196     mptscsih_device_delay_show, NULL);
3197 
3198 static ssize_t
3199 mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
3200 			  char *buf)
3201 {
3202 	struct Scsi_Host *host = class_to_shost(dev);
3203 	MPT_SCSI_HOST	*hd = shost_priv(host);
3204 	MPT_ADAPTER *ioc = hd->ioc;
3205 
3206 	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3207 }
3208 static ssize_t
3209 mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
3210 			   const char *buf, size_t count)
3211 {
3212 	struct Scsi_Host *host = class_to_shost(dev);
3213 	MPT_SCSI_HOST	*hd = shost_priv(host);
3214 	MPT_ADAPTER *ioc = hd->ioc;
3215 	int val = 0;
3216 
3217 	if (sscanf(buf, "%x", &val) != 1)
3218 		return -EINVAL;
3219 
3220 	ioc->debug_level = val;
3221 	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3222 				ioc->name, ioc->debug_level);
3223 	return strlen(buf);
3224 }
3225 static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3226 	mptscsih_debug_level_show, mptscsih_debug_level_store);
3227 
3228 struct device_attribute *mptscsih_host_attrs[] = {
3229 	&dev_attr_version_fw,
3230 	&dev_attr_version_bios,
3231 	&dev_attr_version_mpi,
3232 	&dev_attr_version_product,
3233 	&dev_attr_version_nvdata_persistent,
3234 	&dev_attr_version_nvdata_default,
3235 	&dev_attr_board_name,
3236 	&dev_attr_board_assembly,
3237 	&dev_attr_board_tracer,
3238 	&dev_attr_io_delay,
3239 	&dev_attr_device_delay,
3240 	&dev_attr_debug_level,
3241 	NULL,
3242 };
3243 
3244 EXPORT_SYMBOL(mptscsih_host_attrs);
3245 
3246 EXPORT_SYMBOL(mptscsih_remove);
3247 EXPORT_SYMBOL(mptscsih_shutdown);
3248 #ifdef CONFIG_PM
3249 EXPORT_SYMBOL(mptscsih_suspend);
3250 EXPORT_SYMBOL(mptscsih_resume);
3251 #endif
3252 EXPORT_SYMBOL(mptscsih_proc_info);
3253 EXPORT_SYMBOL(mptscsih_info);
3254 EXPORT_SYMBOL(mptscsih_qcmd);
3255 EXPORT_SYMBOL(mptscsih_slave_destroy);
3256 EXPORT_SYMBOL(mptscsih_slave_configure);
3257 EXPORT_SYMBOL(mptscsih_abort);
3258 EXPORT_SYMBOL(mptscsih_dev_reset);
3259 EXPORT_SYMBOL(mptscsih_bus_reset);
3260 EXPORT_SYMBOL(mptscsih_host_reset);
3261 EXPORT_SYMBOL(mptscsih_bios_param);
3262 EXPORT_SYMBOL(mptscsih_io_done);
3263 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3264 EXPORT_SYMBOL(mptscsih_scandv_complete);
3265 EXPORT_SYMBOL(mptscsih_event_process);
3266 EXPORT_SYMBOL(mptscsih_ioc_reset);
3267 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3268 EXPORT_SYMBOL(mptscsih_timer_expired);
3269 
3270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3271