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