xref: /openbmc/linux/drivers/message/fusion/mptscsih.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  *  linux/drivers/message/fusion/mptscsih.c
3  *      High performance SCSI / Fibre Channel SCSI Host device driver.
4  *      For use with PCI chip/adapter(s):
5  *          LSIFC9xx/LSI409xx Fibre Channel
6  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7  *
8  *  Credits:
9  *      This driver would not exist if not for Alan Cox's development
10  *      of the linux i2o driver.
11  *
12  *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
13  *      and countless enhancements while adding support for the 1030
14  *      chip family.  Pam has been instrumental in the development of
15  *      of the 2.xx.xx series fusion drivers, and her contributions are
16  *      far too numerous to hope to list in one place.
17  *
18  *      A huge debt of gratitude is owed to David S. Miller (DaveM)
19  *      for fixing much of the stupid and broken stuff in the early
20  *      driver while porting to sparc64 platform.  THANK YOU!
21  *
22  *      (see mptbase.c)
23  *
24  *  Copyright (c) 1999-2004 LSI Logic Corporation
25  *  Original author: Steven J. Ralston
26  *  (mailto:sjralston1@netscape.net)
27  *  (mailto:mpt_linux_developer@lsil.com)
28  *
29  *  $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
30  */
31 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
32 /*
33     This program is free software; you can redistribute it and/or modify
34     it under the terms of the GNU General Public License as published by
35     the Free Software Foundation; version 2 of the License.
36 
37     This program is distributed in the hope that it will be useful,
38     but WITHOUT ANY WARRANTY; without even the implied warranty of
39     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40     GNU General Public License for more details.
41 
42     NO WARRANTY
43     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
44     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
45     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
46     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
47     solely responsible for determining the appropriateness of using and
48     distributing the Program and assumes all risks associated with its
49     exercise of rights under this Agreement, including but not limited to
50     the risks and costs of program errors, damage to or loss of data,
51     programs or equipment, and unavailability or interruption of operations.
52 
53     DISCLAIMER OF LIABILITY
54     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
55     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
57     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
59     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
60     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
61 
62     You should have received a copy of the GNU General Public License
63     along with this program; if not, write to the Free Software
64     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
65 */
66 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
67 
68 #include "linux_compat.h"	/* linux-2.6 tweaks */
69 #include <linux/module.h>
70 #include <linux/kernel.h>
71 #include <linux/init.h>
72 #include <linux/errno.h>
73 #include <linux/kdev_t.h>
74 #include <linux/blkdev.h>
75 #include <linux/delay.h>	/* for mdelay */
76 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
77 #include <linux/reboot.h>	/* notifier code */
78 #include <linux/sched.h>
79 #include <linux/workqueue.h>
80 
81 #include <scsi/scsi.h>
82 #include <scsi/scsi_cmnd.h>
83 #include <scsi/scsi_device.h>
84 #include <scsi/scsi_host.h>
85 #include <scsi/scsi_tcq.h>
86 
87 #include "mptbase.h"
88 #include "mptscsih.h"
89 
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #define my_NAME		"Fusion MPT SCSI Host driver"
92 #define my_VERSION	MPT_LINUX_VERSION_COMMON
93 #define MYNAM		"mptscsih"
94 
95 MODULE_AUTHOR(MODULEAUTHOR);
96 MODULE_DESCRIPTION(my_NAME);
97 MODULE_LICENSE("GPL");
98 
99 /* Command line args */
100 static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
101 MODULE_PARM(mpt_dv, "i");
102 MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
103 
104 static int mpt_width = MPTSCSIH_MAX_WIDTH;
105 MODULE_PARM(mpt_width, "i");
106 MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
107 
108 static int mpt_factor = MPTSCSIH_MIN_SYNC;
109 MODULE_PARM(mpt_factor, "h");
110 MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
111 
112 static int mpt_saf_te = MPTSCSIH_SAF_TE;
113 MODULE_PARM(mpt_saf_te, "i");
114 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
115 
116 static int mpt_pq_filter = 0;
117 MODULE_PARM(mpt_pq_filter, "i");
118 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
119 
120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
121 
122 typedef struct _BIG_SENSE_BUF {
123 	u8		data[MPT_SENSE_BUFFER_ALLOC];
124 } BIG_SENSE_BUF;
125 
126 #define MPT_SCANDV_GOOD			(0x00000000) /* must be 0 */
127 #define MPT_SCANDV_DID_RESET		(0x00000001)
128 #define MPT_SCANDV_SENSE		(0x00000002)
129 #define MPT_SCANDV_SOME_ERROR		(0x00000004)
130 #define MPT_SCANDV_SELECTION_TIMEOUT	(0x00000008)
131 #define MPT_SCANDV_ISSUE_SENSE		(0x00000010)
132 #define MPT_SCANDV_FALLBACK		(0x00000020)
133 
134 #define MPT_SCANDV_MAX_RETRIES		(10)
135 
136 #define MPT_ICFLAG_BUF_CAP	0x01	/* ReadBuffer Read Capacity format */
137 #define MPT_ICFLAG_ECHO		0x02	/* ReadBuffer Echo buffer format */
138 #define MPT_ICFLAG_PHYS_DISK	0x04	/* Any SCSI IO but do Phys Disk Format */
139 #define MPT_ICFLAG_TAGGED_CMD	0x08	/* Do tagged IO */
140 #define MPT_ICFLAG_DID_RESET	0x20	/* Bus Reset occurred with this command */
141 #define MPT_ICFLAG_RESERVED	0x40	/* Reserved has been issued */
142 
143 typedef struct _internal_cmd {
144 	char		*data;		/* data pointer */
145 	dma_addr_t	data_dma;	/* data dma address */
146 	int		size;		/* transfer size */
147 	u8		cmd;		/* SCSI Op Code */
148 	u8		bus;		/* bus number */
149 	u8		id;		/* SCSI ID (virtual) */
150 	u8		lun;
151 	u8		flags;		/* Bit Field - See above */
152 	u8		physDiskNum;	/* Phys disk number, -1 else */
153 	u8		rsvd2;
154 	u8		rsvd;
155 } INTERNAL_CMD;
156 
157 typedef struct _negoparms {
158 	u8 width;
159 	u8 offset;
160 	u8 factor;
161 	u8 flags;
162 } NEGOPARMS;
163 
164 typedef struct _dv_parameters {
165 	NEGOPARMS	 max;
166 	NEGOPARMS	 now;
167 	u8		 cmd;
168 	u8		 id;
169 	u16		 pad1;
170 } DVPARAMETERS;
171 
172 
173 /*
174  *  Other private/forward protos...
175  */
176 static int	mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
177 static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
178 static int	mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
179 
180 static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
181 				 SCSIIORequest_t *pReq, int req_idx);
182 static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
183 static void	copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
184 static int	mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
185 static int	mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
186 static u32	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
187 
188 static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
189 static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
190 
191 static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
192 static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
193 
194 static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
195 static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
196 static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
197 static void	mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
198 static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
199 static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
200 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
201 static int	mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
202 static void	mptscsih_timer_expired(unsigned long data);
203 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
204 static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
205 
206 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
207 static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
208 static void	mptscsih_domainValidation(void *hd);
209 static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
210 static void	mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
211 static int	mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
212 static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
213 static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
214 #endif
215 /* module entry point */
216 static int  __init   mptscsih_init  (void);
217 static void __exit   mptscsih_exit  (void);
218 
219 static int  mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
220 static void mptscsih_remove(struct pci_dev *);
221 static void mptscsih_shutdown(struct device *);
222 #ifdef CONFIG_PM
223 static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
224 static int mptscsih_resume(struct pci_dev *pdev);
225 #endif
226 
227 
228 /*
229  *	Private data...
230  */
231 
232 static int	mpt_scsi_hosts = 0;
233 
234 static int	ScsiDoneCtx = -1;
235 static int	ScsiTaskCtx = -1;
236 static int	ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
237 
238 #define SNS_LEN(scp)	sizeof((scp)->sense_buffer)
239 
240 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
241 /*
242  * Domain Validation task structure
243  */
244 static DEFINE_SPINLOCK(dvtaskQ_lock);
245 static int dvtaskQ_active = 0;
246 static int dvtaskQ_release = 0;
247 static struct work_struct	mptscsih_dvTask;
248 #endif
249 
250 /*
251  * Wait Queue setup
252  */
253 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
254 static int scandv_wait_done = 1;
255 
256 
257 /* Driver command line structure
258  */
259 static struct scsi_host_template driver_template;
260 
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
262 /**
263  *	mptscsih_add_sge - Place a simple SGE at address pAddr.
264  *	@pAddr: virtual address for SGE
265  *	@flagslength: SGE flags and data transfer length
266  *	@dma_addr: Physical address
267  *
268  *	This routine places a MPT request frame back on the MPT adapter's
269  *	FreeQ.
270  */
271 static inline void
272 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
273 {
274 	if (sizeof(dma_addr_t) == sizeof(u64)) {
275 		SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
276 		u32 tmp = dma_addr & 0xFFFFFFFF;
277 
278 		pSge->FlagsLength = cpu_to_le32(flagslength);
279 		pSge->Address.Low = cpu_to_le32(tmp);
280 		tmp = (u32) ((u64)dma_addr >> 32);
281 		pSge->Address.High = cpu_to_le32(tmp);
282 
283 	} else {
284 		SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
285 		pSge->FlagsLength = cpu_to_le32(flagslength);
286 		pSge->Address = cpu_to_le32(dma_addr);
287 	}
288 } /* mptscsih_add_sge() */
289 
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
291 /**
292  *	mptscsih_add_chain - Place a chain SGE at address pAddr.
293  *	@pAddr: virtual address for SGE
294  *	@next: nextChainOffset value (u32's)
295  *	@length: length of next SGL segment
296  *	@dma_addr: Physical address
297  *
298  *	This routine places a MPT request frame back on the MPT adapter's
299  *	FreeQ.
300  */
301 static inline void
302 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
303 {
304 	if (sizeof(dma_addr_t) == sizeof(u64)) {
305 		SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
306 		u32 tmp = dma_addr & 0xFFFFFFFF;
307 
308 		pChain->Length = cpu_to_le16(length);
309 		pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
310 
311 		pChain->NextChainOffset = next;
312 
313 		pChain->Address.Low = cpu_to_le32(tmp);
314 		tmp = (u32) ((u64)dma_addr >> 32);
315 		pChain->Address.High = cpu_to_le32(tmp);
316 	} else {
317 		SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
318 		pChain->Length = cpu_to_le16(length);
319 		pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
320 		pChain->NextChainOffset = next;
321 		pChain->Address = cpu_to_le32(dma_addr);
322 	}
323 } /* mptscsih_add_chain() */
324 
325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
326 /*
327  *	mptscsih_getFreeChainBuffer - Function to get a free chain
328  *	from the MPT_SCSI_HOST FreeChainQ.
329  *	@ioc: Pointer to MPT_ADAPTER structure
330  *	@req_idx: Index of the SCSI IO request frame. (output)
331  *
332  *	return SUCCESS or FAILED
333  */
334 static inline int
335 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
336 {
337 	MPT_FRAME_HDR *chainBuf;
338 	unsigned long flags;
339 	int rc;
340 	int chain_idx;
341 
342 	dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
343 			ioc->name));
344 	spin_lock_irqsave(&ioc->FreeQlock, flags);
345 	if (!list_empty(&ioc->FreeChainQ)) {
346 		int offset;
347 
348 		chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
349 				u.frame.linkage.list);
350 		list_del(&chainBuf->u.frame.linkage.list);
351 		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
352 		chain_idx = offset / ioc->req_sz;
353 		rc = SUCCESS;
354 		dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
355 			ioc->name, *retIndex, chainBuf));
356 	} else {
357 		rc = FAILED;
358 		chain_idx = MPT_HOST_NO_CHAIN;
359 		dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
360 			ioc->name));
361 	}
362 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
363 
364 	*retIndex = chain_idx;
365 	return rc;
366 } /* mptscsih_getFreeChainBuffer() */
367 
368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
369 /*
370  *	mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
371  *	SCSIIORequest_t Message Frame.
372  *	@ioc: Pointer to MPT_ADAPTER structure
373  *	@SCpnt: Pointer to scsi_cmnd structure
374  *	@pReq: Pointer to SCSIIORequest_t structure
375  *
376  *	Returns ...
377  */
378 static int
379 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
380 		SCSIIORequest_t *pReq, int req_idx)
381 {
382 	char 	*psge;
383 	char	*chainSge;
384 	struct scatterlist *sg;
385 	int	 frm_sz;
386 	int	 sges_left, sg_done;
387 	int	 chain_idx = MPT_HOST_NO_CHAIN;
388 	int	 sgeOffset;
389 	int	 numSgeSlots, numSgeThisFrame;
390 	u32	 sgflags, sgdir, thisxfer = 0;
391 	int	 chain_dma_off = 0;
392 	int	 newIndex;
393 	int	 ii;
394 	dma_addr_t v2;
395 	u32	RequestNB;
396 
397 	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
398 	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
399 		sgdir = MPT_TRANSFER_HOST_TO_IOC;
400 	} else {
401 		sgdir = MPT_TRANSFER_IOC_TO_HOST;
402 	}
403 
404 	psge = (char *) &pReq->SGL;
405 	frm_sz = ioc->req_sz;
406 
407 	/* Map the data portion, if any.
408 	 * sges_left  = 0 if no data transfer.
409 	 */
410 	if ( (sges_left = SCpnt->use_sg) ) {
411 		sges_left = pci_map_sg(ioc->pcidev,
412 			       (struct scatterlist *) SCpnt->request_buffer,
413  			       SCpnt->use_sg,
414 			       SCpnt->sc_data_direction);
415 		if (sges_left == 0)
416 			return FAILED;
417 	} else if (SCpnt->request_bufflen) {
418 		SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
419 				      SCpnt->request_buffer,
420 				      SCpnt->request_bufflen,
421 				      SCpnt->sc_data_direction);
422 		dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
423 				ioc->name, SCpnt, SCpnt->request_bufflen));
424 		mptscsih_add_sge((char *) &pReq->SGL,
425 			0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
426 			SCpnt->SCp.dma_handle);
427 
428 		return SUCCESS;
429 	}
430 
431 	/* Handle the SG case.
432 	 */
433 	sg = (struct scatterlist *) SCpnt->request_buffer;
434 	sg_done  = 0;
435 	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
436 	chainSge = NULL;
437 
438 	/* Prior to entering this loop - the following must be set
439 	 * current MF:  sgeOffset (bytes)
440 	 *              chainSge (Null if original MF is not a chain buffer)
441 	 *              sg_done (num SGE done for this MF)
442 	 */
443 
444 nextSGEset:
445 	numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
446 	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
447 
448 	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
449 
450 	/* Get first (num - 1) SG elements
451 	 * Skip any SG entries with a length of 0
452 	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
453 	 */
454 	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
455 		thisxfer = sg_dma_len(sg);
456 		if (thisxfer == 0) {
457 			sg ++; /* Get next SG element from the OS */
458 			sg_done++;
459 			continue;
460 		}
461 
462 		v2 = sg_dma_address(sg);
463 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
464 
465 		sg++;		/* Get next SG element from the OS */
466 		psge += (sizeof(u32) + sizeof(dma_addr_t));
467 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
468 		sg_done++;
469 	}
470 
471 	if (numSgeThisFrame == sges_left) {
472 		/* Add last element, end of buffer and end of list flags.
473 		 */
474 		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
475 				MPT_SGE_FLAGS_END_OF_BUFFER |
476 				MPT_SGE_FLAGS_END_OF_LIST;
477 
478 		/* Add last SGE and set termination flags.
479 		 * Note: Last SGE may have a length of 0 - which should be ok.
480 		 */
481 		thisxfer = sg_dma_len(sg);
482 
483 		v2 = sg_dma_address(sg);
484 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
485 		/*
486 		sg++;
487 		psge += (sizeof(u32) + sizeof(dma_addr_t));
488 		*/
489 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
490 		sg_done++;
491 
492 		if (chainSge) {
493 			/* The current buffer is a chain buffer,
494 			 * but there is not another one.
495 			 * Update the chain element
496 			 * Offset and Length fields.
497 			 */
498 			mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
499 		} else {
500 			/* The current buffer is the original MF
501 			 * and there is no Chain buffer.
502 			 */
503 			pReq->ChainOffset = 0;
504 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
505 			dsgprintk((MYIOC_s_ERR_FMT
506 			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
507 			ioc->RequestNB[req_idx] = RequestNB;
508 		}
509 	} else {
510 		/* At least one chain buffer is needed.
511 		 * Complete the first MF
512 		 *  - last SGE element, set the LastElement bit
513 		 *  - set ChainOffset (words) for orig MF
514 		 *             (OR finish previous MF chain buffer)
515 		 *  - update MFStructPtr ChainIndex
516 		 *  - Populate chain element
517 		 * Also
518 		 * Loop until done.
519 		 */
520 
521 		dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
522 				ioc->name, sg_done));
523 
524 		/* Set LAST_ELEMENT flag for last non-chain element
525 		 * in the buffer. Since psge points at the NEXT
526 		 * SGE element, go back one SGE element, update the flags
527 		 * and reset the pointer. (Note: sgflags & thisxfer are already
528 		 * set properly).
529 		 */
530 		if (sg_done) {
531 			u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
532 			sgflags = le32_to_cpu(*ptmp);
533 			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
534 			*ptmp = cpu_to_le32(sgflags);
535 		}
536 
537 		if (chainSge) {
538 			/* The current buffer is a chain buffer.
539 			 * chainSge points to the previous Chain Element.
540 			 * Update its chain element Offset and Length (must
541 			 * include chain element size) fields.
542 			 * Old chain element is now complete.
543 			 */
544 			u8 nextChain = (u8) (sgeOffset >> 2);
545 			sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
546 			mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
547 		} else {
548 			/* The original MF buffer requires a chain buffer -
549 			 * set the offset.
550 			 * Last element in this MF is a chain element.
551 			 */
552 			pReq->ChainOffset = (u8) (sgeOffset >> 2);
553 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
554 			dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
555 			ioc->RequestNB[req_idx] = RequestNB;
556 		}
557 
558 		sges_left -= sg_done;
559 
560 
561 		/* NOTE: psge points to the beginning of the chain element
562 		 * in current buffer. Get a chain buffer.
563 		 */
564 		dsgprintk((MYIOC_s_INFO_FMT
565 		    "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
566 		    ioc->name, pReq->CDB[0], SCpnt));
567 		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
568 			return FAILED;
569 
570 		/* Update the tracking arrays.
571 		 * If chainSge == NULL, update ReqToChain, else ChainToChain
572 		 */
573 		if (chainSge) {
574 			ioc->ChainToChain[chain_idx] = newIndex;
575 		} else {
576 			ioc->ReqToChain[req_idx] = newIndex;
577 		}
578 		chain_idx = newIndex;
579 		chain_dma_off = ioc->req_sz * chain_idx;
580 
581 		/* Populate the chainSGE for the current buffer.
582 		 * - Set chain buffer pointer to psge and fill
583 		 *   out the Address and Flags fields.
584 		 */
585 		chainSge = (char *) psge;
586 		dsgprintk((KERN_INFO "  Current buff @ %p (index 0x%x)",
587 				psge, req_idx));
588 
589 		/* Start the SGE for the next buffer
590 		 */
591 		psge = (char *) (ioc->ChainBuffer + chain_dma_off);
592 		sgeOffset = 0;
593 		sg_done = 0;
594 
595 		dsgprintk((KERN_INFO "  Chain buff @ %p (index 0x%x)\n",
596 				psge, chain_idx));
597 
598 		/* Start the SGE for the next buffer
599 		 */
600 
601 		goto nextSGEset;
602 	}
603 
604 	return SUCCESS;
605 } /* mptscsih_AddSGE() */
606 
607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
608 /*
609  *	mptscsih_io_done - Main SCSI IO callback routine registered to
610  *	Fusion MPT (base) driver
611  *	@ioc: Pointer to MPT_ADAPTER structure
612  *	@mf: Pointer to original MPT request frame
613  *	@r: Pointer to MPT reply frame (NULL if TurboReply)
614  *
615  *	This routine is called from mpt.c::mpt_interrupt() at the completion
616  *	of any SCSI IO request.
617  *	This routine is registered with the Fusion MPT (base) driver at driver
618  *	load/init time via the mpt_register() API call.
619  *
620  *	Returns 1 indicating alloc'd request frame ptr should be freed.
621  */
622 static int
623 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
624 {
625 	struct scsi_cmnd	*sc;
626 	MPT_SCSI_HOST	*hd;
627 	SCSIIORequest_t	*pScsiReq;
628 	SCSIIOReply_t	*pScsiReply;
629 	u16		 req_idx;
630 
631 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
632 
633 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
634 	sc = hd->ScsiLookup[req_idx];
635 	if (sc == NULL) {
636 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
637 
638 		/* Remark: writeSDP1 will use the ScsiDoneCtx
639 		 * If a SCSI I/O cmd, device disabled by OS and
640 		 * completion done. Cannot touch sc struct. Just free mem.
641 		 */
642 		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
643 			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
644 			ioc->name);
645 
646 		mptscsih_freeChainBuffers(ioc, req_idx);
647 		return 1;
648 	}
649 
650 	dmfprintk((MYIOC_s_INFO_FMT
651 		"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
652 		ioc->name, mf, mr, sc, req_idx));
653 
654 	sc->result = DID_OK << 16;		/* Set default reply as OK */
655 	pScsiReq = (SCSIIORequest_t *) mf;
656 	pScsiReply = (SCSIIOReply_t *) mr;
657 
658 	if (pScsiReply == NULL) {
659 		/* special context reply handling */
660 		;
661 	} else {
662 		u32	 xfer_cnt;
663 		u16	 status;
664 		u8	 scsi_state, scsi_status;
665 
666 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
667 		scsi_state = pScsiReply->SCSIState;
668 		scsi_status = pScsiReply->SCSIStatus;
669 		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
670 		sc->resid = sc->request_bufflen - xfer_cnt;
671 
672 		dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
673 			"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
674 			"resid=%d bufflen=%d xfer_cnt=%d\n",
675 			ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
676 			status, scsi_state, scsi_status, sc->resid,
677 			sc->request_bufflen, xfer_cnt));
678 
679 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
680 			copy_sense_data(sc, hd, mf, pScsiReply);
681 
682 		/*
683 		 *  Look for + dump FCP ResponseInfo[]!
684 		 */
685 		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
686 			printk(KERN_NOTICE "  FCP_ResponseInfo=%08xh\n",
687 			le32_to_cpu(pScsiReply->ResponseInfo));
688 		}
689 
690 		switch(status) {
691 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
692 			/* CHECKME!
693 			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
694 			 * But not: DID_BUS_BUSY lest one risk
695 			 * killing interrupt handler:-(
696 			 */
697 			sc->result = SAM_STAT_BUSY;
698 			break;
699 
700 		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
701 		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
702 			sc->result = DID_BAD_TARGET << 16;
703 			break;
704 
705 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
706 			/* Spoof to SCSI Selection Timeout! */
707 			sc->result = DID_NO_CONNECT << 16;
708 
709 			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
710 				hd->sel_timeout[pScsiReq->TargetID]++;
711 			break;
712 
713 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
714 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
715 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
716 			/* Linux handles an unsolicited DID_RESET better
717 			 * than an unsolicited DID_ABORT.
718 			 */
719 			sc->result = DID_RESET << 16;
720 
721 			/* GEM Workaround. */
722 			if (ioc->bus_type == SCSI)
723 				mptscsih_no_negotiate(hd, sc->device->id);
724 			break;
725 
726 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
727 			if ( xfer_cnt >= sc->underflow ) {
728 				/* Sufficient data transfer occurred */
729 				sc->result = (DID_OK << 16) | scsi_status;
730 			} else if ( xfer_cnt == 0 ) {
731 				/* A CRC Error causes this condition; retry */
732 				sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
733 					(CHECK_CONDITION << 1);
734 				sc->sense_buffer[0] = 0x70;
735 				sc->sense_buffer[2] = NO_SENSE;
736 				sc->sense_buffer[12] = 0;
737 				sc->sense_buffer[13] = 0;
738 			} else {
739 				sc->result = DID_SOFT_ERROR << 16;
740 			}
741 			dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
742 			break;
743 
744 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
745 			/*
746 			 *  Do upfront check for valid SenseData and give it
747 			 *  precedence!
748 			 */
749 			sc->result = (DID_OK << 16) | scsi_status;
750 			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
751 				/* Have already saved the status and sense data
752 				 */
753 				;
754 			} else {
755 				if (xfer_cnt < sc->underflow) {
756 					sc->result = DID_SOFT_ERROR << 16;
757 				}
758 				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
759 					/* What to do?
760 				 	*/
761 					sc->result = DID_SOFT_ERROR << 16;
762 				}
763 				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
764 					/*  Not real sure here either...  */
765 					sc->result = DID_RESET << 16;
766 				}
767 			}
768 
769 			dreplyprintk((KERN_NOTICE "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
770 					sc->underflow));
771 			dreplyprintk((KERN_NOTICE "  ActBytesXferd=%02xh\n", xfer_cnt));
772 			/* Report Queue Full
773 			 */
774 			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
775 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
776 
777 			break;
778 
779 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
780 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
781 			scsi_status = pScsiReply->SCSIStatus;
782 			sc->result = (DID_OK << 16) | scsi_status;
783 			if (scsi_state == 0) {
784 				;
785 			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
786 				/*
787 				 * If running against circa 200003dd 909 MPT f/w,
788 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
789 				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
790 				 * and with SenseBytes set to 0.
791 				 */
792 				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
793 					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
794 
795 			}
796 			else if (scsi_state &
797 			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
798 			   ) {
799 				/*
800 				 * What to do?
801 				 */
802 				sc->result = DID_SOFT_ERROR << 16;
803 			}
804 			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
805 				/*  Not real sure here either...  */
806 				sc->result = DID_RESET << 16;
807 			}
808 			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
809 				/* Device Inq. data indicates that it supports
810 				 * QTags, but rejects QTag messages.
811 				 * This command completed OK.
812 				 *
813 				 * Not real sure here either so do nothing...  */
814 			}
815 
816 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
817 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
818 
819 			/* Add handling of:
820 			 * Reservation Conflict, Busy,
821 			 * Command Terminated, CHECK
822 			 */
823 			break;
824 
825 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
826 			sc->result = DID_SOFT_ERROR << 16;
827 			break;
828 
829 		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
830 		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
831 		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
832 		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
833 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
834 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
835 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
836 		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
837 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
838 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
839 		default:
840 			/*
841 			 * What to do?
842 			 */
843 			sc->result = DID_SOFT_ERROR << 16;
844 			break;
845 
846 		}	/* switch(status) */
847 
848 		dreplyprintk((KERN_NOTICE "  sc->result is %08xh\n", sc->result));
849 	} /* end of address reply case */
850 
851 	/* Unmap the DMA buffers, if any. */
852 	if (sc->use_sg) {
853 		pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
854 			    sc->use_sg, sc->sc_data_direction);
855 	} else if (sc->request_bufflen) {
856 		pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
857 				sc->request_bufflen, sc->sc_data_direction);
858 	}
859 
860 	hd->ScsiLookup[req_idx] = NULL;
861 
862 	sc->scsi_done(sc);		/* Issue the command callback */
863 
864 	/* Free Chain buffers */
865 	mptscsih_freeChainBuffers(ioc, req_idx);
866 	return 1;
867 }
868 
869 
870 /*
871  *	mptscsih_flush_running_cmds - For each command found, search
872  *		Scsi_Host instance taskQ and reply to OS.
873  *		Called only if recovering from a FW reload.
874  *	@hd: Pointer to a SCSI HOST structure
875  *
876  *	Returns: None.
877  *
878  *	Must be called while new I/Os are being queued.
879  */
880 static void
881 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
882 {
883 	MPT_ADAPTER *ioc = hd->ioc;
884 	struct scsi_cmnd	*SCpnt;
885 	MPT_FRAME_HDR	*mf;
886 	int		 ii;
887 	int		 max = ioc->req_depth;
888 
889 	dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
890 	for (ii= 0; ii < max; ii++) {
891 		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
892 
893 			/* Command found.
894 			 */
895 
896 			/* Null ScsiLookup index
897 			 */
898 			hd->ScsiLookup[ii] = NULL;
899 
900 			mf = MPT_INDEX_2_MFPTR(ioc, ii);
901 			dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
902 					mf, SCpnt));
903 
904 			/* Set status, free OS resources (SG DMA buffers)
905 			 * Do OS callback
906 			 * Free driver resources (chain, msg buffers)
907 			 */
908 			if (scsi_device_online(SCpnt->device)) {
909 				if (SCpnt->use_sg) {
910 					pci_unmap_sg(ioc->pcidev,
911 						(struct scatterlist *) SCpnt->request_buffer,
912 						SCpnt->use_sg,
913 						SCpnt->sc_data_direction);
914 				} else if (SCpnt->request_bufflen) {
915 					pci_unmap_single(ioc->pcidev,
916 						SCpnt->SCp.dma_handle,
917 						SCpnt->request_bufflen,
918 						SCpnt->sc_data_direction);
919 				}
920 			}
921 			SCpnt->result = DID_RESET << 16;
922 			SCpnt->host_scribble = NULL;
923 
924 			/* Free Chain buffers */
925 			mptscsih_freeChainBuffers(ioc, ii);
926 
927 			/* Free Message frames */
928 			mpt_free_msg_frame(ioc, mf);
929 
930 			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
931 		}
932 	}
933 
934 	return;
935 }
936 
937 /*
938  *	mptscsih_search_running_cmds - Delete any commands associated
939  *		with the specified target and lun. Function called only
940  *		when a lun is disable by mid-layer.
941  *		Do NOT access the referenced scsi_cmnd structure or
942  *		members. Will cause either a paging or NULL ptr error.
943  *	@hd: Pointer to a SCSI HOST structure
944  *	@target: target id
945  *	@lun: lun
946  *
947  *	Returns: None.
948  *
949  *	Called from slave_destroy.
950  */
951 static void
952 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
953 {
954 	SCSIIORequest_t	*mf = NULL;
955 	int		 ii;
956 	int		 max = hd->ioc->req_depth;
957 
958 	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
959 			target, lun, max));
960 
961 	for (ii=0; ii < max; ii++) {
962 		if (hd->ScsiLookup[ii] != NULL) {
963 
964 			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
965 
966 			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
967 					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
968 
969 			if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
970 				continue;
971 
972 			/* Cleanup
973 			 */
974 			hd->ScsiLookup[ii] = NULL;
975 			mptscsih_freeChainBuffers(hd->ioc, ii);
976 			mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
977 		}
978 	}
979 
980 	return;
981 }
982 
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 /*
985  *  Hack! It might be nice to report if a device is returning QUEUE_FULL
986  *  but maybe not each and every time...
987  */
988 static long last_queue_full = 0;
989 
990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
991 /*
992  *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
993  *	from a SCSI target device.
994  *	@sc: Pointer to scsi_cmnd structure
995  *	@pScsiReply: Pointer to SCSIIOReply_t
996  *	@pScsiReq: Pointer to original SCSI request
997  *
998  *	This routine periodically reports QUEUE_FULL status returned from a
999  *	SCSI target device.  It reports this to the console via kernel
1000  *	printk() API call, not more than once every 10 seconds.
1001  */
1002 static void
1003 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1004 {
1005 	long time = jiffies;
1006 
1007 	if (time - last_queue_full > 10 * HZ) {
1008 		char *ioc_str = "ioc?";
1009 
1010 		if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1011 			ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1012 		dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1013 				ioc_str, 0, sc->device->id, sc->device->lun));
1014 		last_queue_full = time;
1015 	}
1016 }
1017 
1018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1019 static char *info_kbuf = NULL;
1020 
1021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1023 /*
1024  *	mptscsih_probe - Installs scsi devices per bus.
1025  *	@pdev: Pointer to pci_dev structure
1026  *
1027  *	Returns 0 for success, non-zero for failure.
1028  *
1029  */
1030 
1031 static int
1032 mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1033 {
1034 	struct Scsi_Host	*sh;
1035 	MPT_SCSI_HOST		*hd;
1036 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1037 	unsigned long		 flags;
1038 	int			 sz, ii;
1039 	int			 numSGE = 0;
1040 	int			 scale;
1041 	int			 ioc_cap;
1042 	u8			*mem;
1043 	int			error=0;
1044 
1045 
1046 	/* 20010202 -sralston
1047 	 *  Added sanity check on readiness of the MPT adapter.
1048 	 */
1049 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1050 		printk(MYIOC_s_WARN_FMT
1051 		  "Skipping because it's not operational!\n",
1052 		  ioc->name);
1053 		return -ENODEV;
1054 	}
1055 
1056 	if (!ioc->active) {
1057 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1058 		  ioc->name);
1059 		return -ENODEV;
1060 	}
1061 
1062 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
1063 	 */
1064 	ioc_cap = 0;
1065 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1066 		if (ioc->pfacts[ii].ProtocolFlags &
1067 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
1068 			ioc_cap ++;
1069 	}
1070 
1071 	if (!ioc_cap) {
1072 		printk(MYIOC_s_WARN_FMT
1073 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1074 			ioc->name, ioc);
1075 		return -ENODEV;
1076 	}
1077 
1078 	sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1079 
1080 	if (!sh) {
1081 		printk(MYIOC_s_WARN_FMT
1082 			"Unable to register controller with SCSI subsystem\n",
1083 			ioc->name);
1084                 return -1;
1085         }
1086 
1087 	spin_lock_irqsave(&ioc->FreeQlock, flags);
1088 
1089 	/* Attach the SCSI Host to the IOC structure
1090 	 */
1091 	ioc->sh = sh;
1092 
1093 	sh->io_port = 0;
1094 	sh->n_io_port = 0;
1095 	sh->irq = 0;
1096 
1097 	/* set 16 byte cdb's */
1098 	sh->max_cmd_len = 16;
1099 
1100 	/* Yikes!  This is important!
1101 	 * Otherwise, by default, linux
1102 	 * only scans target IDs 0-7!
1103 	 * pfactsN->MaxDevices unreliable
1104 	 * (not supported in early
1105 	 *	versions of the FW).
1106 	 * max_id = 1 + actual max id,
1107 	 * max_lun = 1 + actual last lun,
1108 	 *	see hosts.h :o(
1109 	 */
1110 	if (ioc->bus_type == SCSI) {
1111 		sh->max_id = MPT_MAX_SCSI_DEVICES;
1112 	} else {
1113 	/* For FC, increase the queue depth
1114 	 * from MPT_SCSI_CAN_QUEUE (31)
1115 	 * to MPT_FC_CAN_QUEUE (63).
1116 	 */
1117 		sh->can_queue = MPT_FC_CAN_QUEUE;
1118 		sh->max_id =
1119 		  MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1120 	}
1121 
1122 	sh->max_lun = MPT_LAST_LUN + 1;
1123 	sh->max_channel = 0;
1124 	sh->this_id = ioc->pfacts[0].PortSCSIID;
1125 
1126 	/* Required entry.
1127 	 */
1128 	sh->unique_id = ioc->id;
1129 
1130 	/* Verify that we won't exceed the maximum
1131 	 * number of chain buffers
1132 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
1133 	 * For 32bit SGE's:
1134 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1135 	 *               + (req_sz - 64)/sizeof(SGE)
1136 	 * A slightly different algorithm is required for
1137 	 * 64bit SGEs.
1138 	 */
1139 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1140 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1141 		numSGE = (scale - 1) *
1142 		  (ioc->facts.MaxChainDepth-1) + scale +
1143 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1144 		  sizeof(u32));
1145 	} else {
1146 		numSGE = 1 + (scale - 1) *
1147 		  (ioc->facts.MaxChainDepth-1) + scale +
1148 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1149 		  sizeof(u32));
1150 	}
1151 
1152 	if (numSGE < sh->sg_tablesize) {
1153 		/* Reset this value */
1154 		dprintk((MYIOC_s_INFO_FMT
1155 		  "Resetting sg_tablesize to %d from %d\n",
1156 		  ioc->name, numSGE, sh->sg_tablesize));
1157 		sh->sg_tablesize = numSGE;
1158 	}
1159 
1160 	/* Set the pci device pointer in Scsi_Host structure.
1161 	 */
1162 	scsi_set_device(sh, &ioc->pcidev->dev);
1163 
1164 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1165 
1166 	hd = (MPT_SCSI_HOST *) sh->hostdata;
1167 	hd->ioc = ioc;
1168 
1169 	/* SCSI needs scsi_cmnd lookup table!
1170 	 * (with size equal to req_depth*PtrSz!)
1171 	 */
1172 	sz = ioc->req_depth * sizeof(void *);
1173 	mem = kmalloc(sz, GFP_ATOMIC);
1174 	if (mem == NULL) {
1175 		error = -ENOMEM;
1176 		goto mptscsih_probe_failed;
1177 	}
1178 
1179 	memset(mem, 0, sz);
1180 	hd->ScsiLookup = (struct scsi_cmnd **) mem;
1181 
1182 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1183 		 ioc->name, hd->ScsiLookup, sz));
1184 
1185 	/* Allocate memory for the device structures.
1186 	 * A non-Null pointer at an offset
1187 	 * indicates a device exists.
1188 	 * max_id = 1 + maximum id (hosts.h)
1189 	 */
1190 	sz = sh->max_id * sizeof(void *);
1191 	mem = kmalloc(sz, GFP_ATOMIC);
1192 	if (mem == NULL) {
1193 		error = -ENOMEM;
1194 		goto mptscsih_probe_failed;
1195 	}
1196 
1197 	memset(mem, 0, sz);
1198 	hd->Targets = (VirtDevice **) mem;
1199 
1200 	dprintk((KERN_INFO
1201 	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
1202 
1203 	/* Clear the TM flags
1204 	 */
1205 	hd->tmPending = 0;
1206 	hd->tmState = TM_STATE_NONE;
1207 	hd->resetPending = 0;
1208 	hd->abortSCpnt = NULL;
1209 
1210 	/* Clear the pointer used to store
1211 	 * single-threaded commands, i.e., those
1212 	 * issued during a bus scan, dv and
1213 	 * configuration pages.
1214 	 */
1215 	hd->cmdPtr = NULL;
1216 
1217 	/* Initialize this SCSI Hosts' timers
1218 	 * To use, set the timer expires field
1219 	 * and add_timer
1220 	 */
1221 	init_timer(&hd->timer);
1222 	hd->timer.data = (unsigned long) hd;
1223 	hd->timer.function = mptscsih_timer_expired;
1224 
1225 	if (ioc->bus_type == SCSI) {
1226 		/* Update with the driver setup
1227 		 * values.
1228 		 */
1229 		if (ioc->spi_data.maxBusWidth > mpt_width)
1230 			ioc->spi_data.maxBusWidth = mpt_width;
1231 		if (ioc->spi_data.minSyncFactor < mpt_factor)
1232 			ioc->spi_data.minSyncFactor = mpt_factor;
1233 
1234 		if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1235 			ioc->spi_data.maxSyncOffset = 0;
1236 		}
1237 
1238 		ioc->spi_data.Saf_Te = mpt_saf_te;
1239 
1240 		hd->negoNvram = 0;
1241 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1242 		hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1243 #endif
1244 		ioc->spi_data.forceDv = 0;
1245 		ioc->spi_data.noQas = 0;
1246 		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1247 			ioc->spi_data.dvStatus[ii] =
1248 			  MPT_SCSICFG_NEGOTIATE;
1249 		}
1250 
1251 		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1252 			ioc->spi_data.dvStatus[ii] |=
1253 			  MPT_SCSICFG_DV_NOT_DONE;
1254 
1255 		dinitprintk((MYIOC_s_INFO_FMT
1256 			"dv %x width %x factor %x saf_te %x\n",
1257 			ioc->name, mpt_dv,
1258 			mpt_width,
1259 			mpt_factor,
1260 			mpt_saf_te));
1261 	}
1262 
1263 	mpt_scsi_hosts++;
1264 
1265 	error = scsi_add_host (sh, &ioc->pcidev->dev);
1266 	if(error) {
1267 		dprintk((KERN_ERR MYNAM
1268 		  "scsi_add_host failed\n"));
1269 		goto mptscsih_probe_failed;
1270 	}
1271 
1272 	scsi_scan_host(sh);
1273 	return 0;
1274 
1275 mptscsih_probe_failed:
1276 
1277 	mptscsih_remove(pdev);
1278 	return error;
1279 
1280 }
1281 
1282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1283 /*
1284  *	mptscsih_remove - Removed scsi devices
1285  *	@pdev: Pointer to pci_dev structure
1286  *
1287  *
1288  */
1289 static void
1290 mptscsih_remove(struct pci_dev *pdev)
1291 {
1292 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1293 	struct Scsi_Host 	*host = ioc->sh;
1294 	MPT_SCSI_HOST		*hd;
1295 	int 		 	count;
1296 	unsigned long	 	flags;
1297 
1298 	if(!host)
1299 		return;
1300 
1301 	scsi_remove_host(host);
1302 
1303 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1304 	/* Check DV thread active */
1305 	count = 10 * HZ;
1306 	spin_lock_irqsave(&dvtaskQ_lock, flags);
1307 	if (dvtaskQ_active) {
1308 		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1309 		while(dvtaskQ_active && --count) {
1310 			set_current_state(TASK_INTERRUPTIBLE);
1311 			schedule_timeout(1);
1312 		}
1313 	} else {
1314 		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1315 	}
1316 	if (!count)
1317 		printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1318 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1319 	else
1320 		printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1321 #endif
1322 #endif
1323 
1324 	hd = (MPT_SCSI_HOST *)host->hostdata;
1325 	if (hd != NULL) {
1326 		int sz1;
1327 
1328 		mptscsih_shutdown(&pdev->dev);
1329 
1330 		sz1=0;
1331 
1332 		if (hd->ScsiLookup != NULL) {
1333 			sz1 = hd->ioc->req_depth * sizeof(void *);
1334 			kfree(hd->ScsiLookup);
1335 			hd->ScsiLookup = NULL;
1336 		}
1337 
1338 		if (hd->Targets != NULL) {
1339 			/*
1340 			 * Free pointer array.
1341 			 */
1342 			kfree(hd->Targets);
1343 			hd->Targets = NULL;
1344 		}
1345 
1346 		dprintk((MYIOC_s_INFO_FMT
1347 		    "Free'd ScsiLookup (%d) memory\n",
1348 		    hd->ioc->name, sz1));
1349 
1350 		/* NULL the Scsi_Host pointer
1351 		 */
1352 		hd->ioc->sh = NULL;
1353 	}
1354 
1355 	scsi_host_put(host);
1356 	mpt_scsi_hosts--;
1357 
1358 }
1359 
1360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1361 /*
1362  *	mptscsih_shutdown - reboot notifier
1363  *
1364  */
1365 static void
1366 mptscsih_shutdown(struct device * dev)
1367 {
1368 	MPT_ADAPTER 		*ioc = pci_get_drvdata(to_pci_dev(dev));
1369 	struct Scsi_Host 	*host = ioc->sh;
1370 	MPT_SCSI_HOST		*hd;
1371 
1372 	if(!host)
1373 		return;
1374 
1375 	hd = (MPT_SCSI_HOST *)host->hostdata;
1376 
1377 	/* Flush the cache of this adapter
1378 	 */
1379 	if(hd != NULL)
1380 		mptscsih_synchronize_cache(hd, 0);
1381 
1382 }
1383 
1384 #ifdef CONFIG_PM
1385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1386 /*
1387  *	mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1388  *
1389  *
1390  */
1391 static int
1392 mptscsih_suspend(struct pci_dev *pdev, u32 state)
1393 {
1394 	mptscsih_shutdown(&pdev->dev);
1395 	return 0;
1396 }
1397 
1398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1399 /*
1400  *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1401  *
1402  *
1403  */
1404 static int
1405 mptscsih_resume(struct pci_dev *pdev)
1406 {
1407 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1408 	struct Scsi_Host 	*host = ioc->sh;
1409 	MPT_SCSI_HOST		*hd;
1410 
1411 	if(!host)
1412 		return 0;
1413 
1414 	hd = (MPT_SCSI_HOST *)host->hostdata;
1415 	if(!hd)
1416 		return 0;
1417 
1418 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1419 	{
1420 	unsigned long lflags;
1421 	spin_lock_irqsave(&dvtaskQ_lock, lflags);
1422 	if (!dvtaskQ_active) {
1423 		dvtaskQ_active = 1;
1424 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1425 		INIT_WORK(&mptscsih_dvTask,
1426 		  mptscsih_domainValidation, (void *) hd);
1427 		schedule_work(&mptscsih_dvTask);
1428 	} else {
1429 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1430 	}
1431 	}
1432 #endif
1433 	return 0;
1434 }
1435 
1436 #endif
1437 
1438 static struct mpt_pci_driver mptscsih_driver = {
1439 	.probe		= mptscsih_probe,
1440 	.remove		= mptscsih_remove,
1441 	.shutdown	= mptscsih_shutdown,
1442 #ifdef CONFIG_PM
1443 	.suspend	= mptscsih_suspend,
1444 	.resume		= mptscsih_resume,
1445 #endif
1446 };
1447 
1448 /*  SCSI host fops start here...  */
1449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1450 /**
1451  *	mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1452  *	linux scsi mid-layer.
1453  *
1454  *	Returns 0 for success, non-zero for failure.
1455  */
1456 static int __init
1457 mptscsih_init(void)
1458 {
1459 
1460 	show_mptmod_ver(my_NAME, my_VERSION);
1461 
1462 	ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1463 	ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1464 	ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1465 
1466 	if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1467 		devtprintk((KERN_INFO MYNAM
1468 		  ": Registered for IOC event notifications\n"));
1469 	}
1470 
1471 	if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1472 		dprintk((KERN_INFO MYNAM
1473 		  ": Registered for IOC reset notifications\n"));
1474 	}
1475 
1476 	if(mpt_device_driver_register(&mptscsih_driver,
1477 	  MPTSCSIH_DRIVER) != 0 ) {
1478 		dprintk((KERN_INFO MYNAM
1479 		": failed to register dd callbacks\n"));
1480 	}
1481 
1482 	return 0;
1483 
1484 }
1485 
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1488 /**
1489  *	mptscsih_exit - Unregisters MPT adapter(s)
1490  *
1491  */
1492 static void __exit
1493 mptscsih_exit(void)
1494 {
1495 	mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1496 
1497 	mpt_reset_deregister(ScsiDoneCtx);
1498 	dprintk((KERN_INFO MYNAM
1499 	  ": Deregistered for IOC reset notifications\n"));
1500 
1501 	mpt_event_deregister(ScsiDoneCtx);
1502 	dprintk((KERN_INFO MYNAM
1503 	  ": Deregistered for IOC event notifications\n"));
1504 
1505 	mpt_deregister(ScsiScanDvCtx);
1506 	mpt_deregister(ScsiTaskCtx);
1507 	mpt_deregister(ScsiDoneCtx);
1508 
1509 	if (info_kbuf != NULL)
1510 		kfree(info_kbuf);
1511 
1512 }
1513 
1514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1515 /**
1516  *	mptscsih_info - Return information about MPT adapter
1517  *	@SChost: Pointer to Scsi_Host structure
1518  *
1519  *	(linux scsi_host_template.info routine)
1520  *
1521  *	Returns pointer to buffer where information was written.
1522  */
1523 static const char *
1524 mptscsih_info(struct Scsi_Host *SChost)
1525 {
1526 	MPT_SCSI_HOST *h;
1527 	int size = 0;
1528 
1529 	if (info_kbuf == NULL)
1530 		if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1531 			return info_kbuf;
1532 
1533 	h = (MPT_SCSI_HOST *)SChost->hostdata;
1534 	info_kbuf[0] = '\0';
1535 	if (h) {
1536 		mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1537 		info_kbuf[size-1] = '\0';
1538 	}
1539 
1540 	return info_kbuf;
1541 }
1542 
1543 struct info_str {
1544 	char *buffer;
1545 	int   length;
1546 	int   offset;
1547 	int   pos;
1548 };
1549 
1550 static void copy_mem_info(struct info_str *info, char *data, int len)
1551 {
1552 	if (info->pos + len > info->length)
1553 		len = info->length - info->pos;
1554 
1555 	if (info->pos + len < info->offset) {
1556 		info->pos += len;
1557 		return;
1558 	}
1559 
1560 	if (info->pos < info->offset) {
1561 	        data += (info->offset - info->pos);
1562 	        len  -= (info->offset - info->pos);
1563 	}
1564 
1565 	if (len > 0) {
1566                 memcpy(info->buffer + info->pos, data, len);
1567                 info->pos += len;
1568 	}
1569 }
1570 
1571 static int copy_info(struct info_str *info, char *fmt, ...)
1572 {
1573 	va_list args;
1574 	char buf[81];
1575 	int len;
1576 
1577 	va_start(args, fmt);
1578 	len = vsprintf(buf, fmt, args);
1579 	va_end(args);
1580 
1581 	copy_mem_info(info, buf, len);
1582 	return len;
1583 }
1584 
1585 static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1586 {
1587 	struct info_str info;
1588 
1589 	info.buffer	= pbuf;
1590 	info.length	= len;
1591 	info.offset	= offset;
1592 	info.pos	= 0;
1593 
1594 	copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1595 	copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1596 	copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1597 	copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1598 
1599 	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1600 }
1601 
1602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1603 /**
1604  *	mptscsih_proc_info - Return information about MPT adapter
1605  *
1606  *	(linux scsi_host_template.info routine)
1607  *
1608  * 	buffer: if write, user data; if read, buffer for user
1609  * 	length: if write, return length;
1610  * 	offset: if write, 0; if read, the current offset into the buffer from
1611  * 		the previous read.
1612  * 	hostno: scsi host number
1613  *	func:   if write = 1; if read = 0
1614  */
1615 static int
1616 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1617 			int length, int func)
1618 {
1619 	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)host->hostdata;
1620 	MPT_ADAPTER	*ioc = hd->ioc;
1621 	int size = 0;
1622 
1623 	if (func) {
1624 		/*
1625 		 * write is not supported
1626 		 */
1627 	} else {
1628 		if (start)
1629 			*start = buffer;
1630 
1631 		size = mptscsih_host_info(ioc, buffer, offset, length);
1632 	}
1633 
1634 	return size;
1635 }
1636 
1637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1638 #define ADD_INDEX_LOG(req_ent)	do { } while(0)
1639 
1640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1641 /**
1642  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1643  *	@SCpnt: Pointer to scsi_cmnd structure
1644  *	@done: Pointer SCSI mid-layer IO completion function
1645  *
1646  *	(linux scsi_host_template.queuecommand routine)
1647  *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1648  *	from a linux scsi_cmnd request and send it to the IOC.
1649  *
1650  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1651  */
1652 static int
1653 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1654 {
1655 	MPT_SCSI_HOST		*hd;
1656 	MPT_FRAME_HDR		*mf;
1657 	SCSIIORequest_t		*pScsiReq;
1658 	VirtDevice		*pTarget;
1659 	int	 target;
1660 	int	 lun;
1661 	u32	 datalen;
1662 	u32	 scsictl;
1663 	u32	 scsidir;
1664 	u32	 cmd_len;
1665 	int	 my_idx;
1666 	int	 ii;
1667 
1668 	hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1669 	target = SCpnt->device->id;
1670 	lun = SCpnt->device->lun;
1671 	SCpnt->scsi_done = done;
1672 
1673 	pTarget = hd->Targets[target];
1674 
1675 	dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1676 			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1677 
1678 	if (hd->resetPending) {
1679 		dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1680 			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1681 		return SCSI_MLQUEUE_HOST_BUSY;
1682 	}
1683 
1684 	/*
1685 	 *  Put together a MPT SCSI request...
1686 	 */
1687 	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
1688 		dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1689 				hd->ioc->name));
1690 		return SCSI_MLQUEUE_HOST_BUSY;
1691 	}
1692 
1693 	pScsiReq = (SCSIIORequest_t *) mf;
1694 
1695 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1696 
1697 	ADD_INDEX_LOG(my_idx);
1698 
1699 	/*  BUG FIX!  19991030 -sralston
1700 	 *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1701 	 *    Seems we may receive a buffer (datalen>0) even when there
1702 	 *    will be no data transfer!  GRRRRR...
1703 	 */
1704 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1705 		datalen = SCpnt->request_bufflen;
1706 		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1707 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1708 		datalen = SCpnt->request_bufflen;
1709 		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1710 	} else {
1711 		datalen = 0;
1712 		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1713 	}
1714 
1715 	/* Default to untagged. Once a target structure has been allocated,
1716 	 * use the Inquiry data to determine if device supports tagged.
1717 	 */
1718 	if (   pTarget
1719 	    && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1720 	    && (SCpnt->device->tagged_supported)) {
1721 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1722 	} else {
1723 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1724 	}
1725 
1726 	/* Use the above information to set up the message frame
1727 	 */
1728 	pScsiReq->TargetID = (u8) target;
1729 	pScsiReq->Bus = (u8) SCpnt->device->channel;
1730 	pScsiReq->ChainOffset = 0;
1731 	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1732 	pScsiReq->CDBLength = SCpnt->cmd_len;
1733 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1734 	pScsiReq->Reserved = 0;
1735 	pScsiReq->MsgFlags = mpt_msg_flags();
1736 	pScsiReq->LUN[0] = 0;
1737 	pScsiReq->LUN[1] = lun;
1738 	pScsiReq->LUN[2] = 0;
1739 	pScsiReq->LUN[3] = 0;
1740 	pScsiReq->LUN[4] = 0;
1741 	pScsiReq->LUN[5] = 0;
1742 	pScsiReq->LUN[6] = 0;
1743 	pScsiReq->LUN[7] = 0;
1744 	pScsiReq->Control = cpu_to_le32(scsictl);
1745 
1746 	/*
1747 	 *  Write SCSI CDB into the message
1748 	 */
1749 	cmd_len = SCpnt->cmd_len;
1750 	for (ii=0; ii < cmd_len; ii++)
1751 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1752 
1753 	for (ii=cmd_len; ii < 16; ii++)
1754 		pScsiReq->CDB[ii] = 0;
1755 
1756 	/* DataLength */
1757 	pScsiReq->DataLength = cpu_to_le32(datalen);
1758 
1759 	/* SenseBuffer low address */
1760 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1761 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1762 
1763 	/* Now add the SG list
1764 	 * Always have a SGE even if null length.
1765 	 */
1766 	if (datalen == 0) {
1767 		/* Add a NULL SGE */
1768 		mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1769 			(dma_addr_t) -1);
1770 	} else {
1771 		/* Add a 32 or 64 bit SGE */
1772 		if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1773 			goto fail;
1774 	}
1775 
1776 	hd->ScsiLookup[my_idx] = SCpnt;
1777 	SCpnt->host_scribble = NULL;
1778 
1779 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1780 	if (hd->ioc->bus_type == SCSI) {
1781 		int dvStatus = hd->ioc->spi_data.dvStatus[target];
1782 		int issueCmd = 1;
1783 
1784 		if (dvStatus || hd->ioc->spi_data.forceDv) {
1785 
1786 			if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1787 				(hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1788 				unsigned long lflags;
1789 				/* Schedule DV if necessary */
1790 				spin_lock_irqsave(&dvtaskQ_lock, lflags);
1791 				if (!dvtaskQ_active) {
1792 					dvtaskQ_active = 1;
1793 					spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1794 					INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
1795 
1796 					schedule_work(&mptscsih_dvTask);
1797 				} else {
1798 					spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1799 				}
1800 				hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1801 			}
1802 
1803 			/* Trying to do DV to this target, extend timeout.
1804 			 * Wait to issue until flag is clear
1805 			 */
1806 			if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1807 				mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1808 				issueCmd = 0;
1809 			}
1810 
1811 			/* Set the DV flags.
1812 			 */
1813 			if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1814 				mptscsih_set_dvflags(hd, pScsiReq);
1815 
1816 			if (!issueCmd)
1817 				goto fail;
1818 		}
1819 	}
1820 #endif
1821 
1822 	mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
1823 	dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1824 			hd->ioc->name, SCpnt, mf, my_idx));
1825 	DBG_DUMP_REQUEST_FRAME(mf)
1826 	return 0;
1827 
1828  fail:
1829 	mptscsih_freeChainBuffers(hd->ioc, my_idx);
1830 	mpt_free_msg_frame(hd->ioc, mf);
1831 	return SCSI_MLQUEUE_HOST_BUSY;
1832 }
1833 
1834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1835 /*
1836  *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1837  *	with a SCSI IO request
1838  *	@hd: Pointer to the MPT_SCSI_HOST instance
1839  *	@req_idx: Index of the SCSI IO request frame.
1840  *
1841  *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1842  *	No return.
1843  */
1844 static void
1845 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1846 {
1847 	MPT_FRAME_HDR *chain;
1848 	unsigned long flags;
1849 	int chain_idx;
1850 	int next;
1851 
1852 	/* Get the first chain index and reset
1853 	 * tracker state.
1854 	 */
1855 	chain_idx = ioc->ReqToChain[req_idx];
1856 	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1857 
1858 	while (chain_idx != MPT_HOST_NO_CHAIN) {
1859 
1860 		/* Save the next chain buffer index */
1861 		next = ioc->ChainToChain[chain_idx];
1862 
1863 		/* Free this chain buffer and reset
1864 		 * tracker
1865 		 */
1866 		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1867 
1868 		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1869 					+ (chain_idx * ioc->req_sz));
1870 
1871 		spin_lock_irqsave(&ioc->FreeQlock, flags);
1872 		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1873 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1874 
1875 		dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1876 				ioc->name, chain_idx));
1877 
1878 		/* handle next */
1879 		chain_idx = next;
1880 	}
1881 	return;
1882 }
1883 
1884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1885 /*
1886  *	Reset Handling
1887  */
1888 
1889 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1890 /*
1891  *	mptscsih_TMHandler - Generic handler for SCSI Task Management.
1892  *	Fall through to mpt_HardResetHandler if: not operational, too many
1893  *	failed TM requests or handshake failure.
1894  *
1895  *	@ioc: Pointer to MPT_ADAPTER structure
1896  *	@type: Task Management type
1897  *	@target: Logical Target ID for reset (if appropriate)
1898  *	@lun: Logical Unit for reset (if appropriate)
1899  *	@ctx2abort: Context for the task to be aborted (if appropriate)
1900  *
1901  *	Remark: Currently invoked from a non-interrupt thread (_bh).
1902  *
1903  *	Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1904  *	will be active.
1905  *
1906  *	Returns 0 for SUCCESS or -1 if FAILED.
1907  */
1908 static int
1909 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1910 {
1911 	MPT_ADAPTER	*ioc;
1912 	int		 rc = -1;
1913 	int		 doTask = 1;
1914 	u32		 ioc_raw_state;
1915 	unsigned long	 flags;
1916 
1917 	/* If FW is being reloaded currently, return success to
1918 	 * the calling function.
1919 	 */
1920 	if (hd == NULL)
1921 		return 0;
1922 
1923 	ioc = hd->ioc;
1924 	if (ioc == NULL) {
1925 		printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1926 		return FAILED;
1927 	}
1928 	dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1929 
1930 	// SJR - CHECKME - Can we avoid this here?
1931 	// (mpt_HardResetHandler has this check...)
1932 	spin_lock_irqsave(&ioc->diagLock, flags);
1933 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1934 		spin_unlock_irqrestore(&ioc->diagLock, flags);
1935 		return FAILED;
1936 	}
1937 	spin_unlock_irqrestore(&ioc->diagLock, flags);
1938 
1939 	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
1940 	 *  If we time out and not bus reset, then we return a FAILED status to the caller.
1941 	 *  The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1942 	 *  successful. Otherwise, reload the FW.
1943 	 */
1944 	if (mptscsih_tm_pending_wait(hd) == FAILED) {
1945 		if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1946 			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
1947 			   "Timed out waiting for last TM (%d) to complete! \n",
1948 			   hd->ioc->name, hd->tmPending));
1949 			return FAILED;
1950 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1951 			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
1952 			   "Timed out waiting for last TM (%d) to complete! \n",
1953 			   hd->ioc->name, hd->tmPending));
1954 			return FAILED;
1955 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1956 			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
1957 			   "Timed out waiting for last TM (%d) to complete! \n",
1958 			   hd->ioc->name, hd->tmPending));
1959 			if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1960 				return FAILED;
1961 
1962 			doTask = 0;
1963 		}
1964 	} else {
1965 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1966 		hd->tmPending |=  (1 << type);
1967 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1968 	}
1969 
1970 	/* Is operational?
1971 	 */
1972 	ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1973 
1974 #ifdef MPT_DEBUG_RESET
1975 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1976 		printk(MYIOC_s_WARN_FMT
1977 			"TM Handler: IOC Not operational(0x%x)!\n",
1978 			hd->ioc->name, ioc_raw_state);
1979 	}
1980 #endif
1981 
1982 	if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1983 				&& !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1984 
1985 		/* Isse the Task Mgmt request.
1986 		 */
1987 		if (hd->hard_resets < -1)
1988 			hd->hard_resets++;
1989 		rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1990 		if (rc) {
1991 			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1992 		} else {
1993 			dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1994 		}
1995 	}
1996 
1997 	/* Only fall through to the HRH if this is a bus reset
1998 	 */
1999 	if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2000 		ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2001 		dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2002 			 hd->ioc->name));
2003 		rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2004 	}
2005 
2006 	dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2007 
2008 	return rc;
2009 }
2010 
2011 
2012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2013 /*
2014  *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
2015  *	@hd: Pointer to MPT_SCSI_HOST structure
2016  *	@type: Task Management type
2017  *	@target: Logical Target ID for reset (if appropriate)
2018  *	@lun: Logical Unit for reset (if appropriate)
2019  *	@ctx2abort: Context for the task to be aborted (if appropriate)
2020  *
2021  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2022  *	or a non-interrupt thread.  In the former, must not call schedule().
2023  *
2024  *	Not all fields are meaningfull for all task types.
2025  *
2026  *	Returns 0 for SUCCESS, -999 for "no msg frames",
2027  *	else other non-zero value returned.
2028  */
2029 static int
2030 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
2031 {
2032 	MPT_FRAME_HDR	*mf;
2033 	SCSITaskMgmt_t	*pScsiTm;
2034 	int		 ii;
2035 	int		 retval;
2036 
2037 	/* Return Fail to calling function if no message frames available.
2038 	 */
2039 	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2040 		dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
2041 				hd->ioc->name));
2042 		//return FAILED;
2043 		return -999;
2044 	}
2045 	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2046 			hd->ioc->name, mf));
2047 
2048 	/* Format the Request
2049 	 */
2050 	pScsiTm = (SCSITaskMgmt_t *) mf;
2051 	pScsiTm->TargetID = target;
2052 	pScsiTm->Bus = channel;
2053 	pScsiTm->ChainOffset = 0;
2054 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2055 
2056 	pScsiTm->Reserved = 0;
2057 	pScsiTm->TaskType = type;
2058 	pScsiTm->Reserved1 = 0;
2059 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2060                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2061 
2062 	for (ii= 0; ii < 8; ii++) {
2063 		pScsiTm->LUN[ii] = 0;
2064 	}
2065 	pScsiTm->LUN[1] = lun;
2066 
2067 	for (ii=0; ii < 7; ii++)
2068 		pScsiTm->Reserved2[ii] = 0;
2069 
2070 	pScsiTm->TaskMsgContext = ctx2abort;
2071 
2072 	dtmprintk((MYIOC_s_INFO_FMT
2073 		"IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2074 		hd->ioc->name, ctx2abort, type));
2075 
2076 	DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
2077 
2078 	if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2079 		sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
2080 		CAN_SLEEP)) != 0) {
2081 		dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2082 			" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2083 			hd->ioc, mf));
2084 		mpt_free_msg_frame(hd->ioc, mf);
2085 		return retval;
2086 	}
2087 
2088 	if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
2089 		dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
2090 			" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2091 			hd->ioc, mf));
2092 		mpt_free_msg_frame(hd->ioc, mf);
2093 		dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2094 			 hd->ioc->name));
2095 		retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2096 	}
2097 
2098 	return retval;
2099 }
2100 
2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2102 /**
2103  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2104  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2105  *
2106  *	(linux scsi_host_template.eh_abort_handler routine)
2107  *
2108  *	Returns SUCCESS or FAILED.
2109  */
2110 static int
2111 mptscsih_abort(struct scsi_cmnd * SCpnt)
2112 {
2113 	MPT_SCSI_HOST	*hd;
2114 	MPT_ADAPTER	*ioc;
2115 	MPT_FRAME_HDR	*mf;
2116 	u32		 ctx2abort;
2117 	int		 scpnt_idx;
2118 	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
2119 
2120 	/* If we can't locate our host adapter structure, return FAILED status.
2121 	 */
2122 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2123 		SCpnt->result = DID_RESET << 16;
2124 		SCpnt->scsi_done(SCpnt);
2125 		dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2126 			   "Can't locate host! (sc=%p)\n",
2127 			   SCpnt));
2128 		return FAILED;
2129 	}
2130 
2131 	ioc = hd->ioc;
2132 	if (hd->resetPending)
2133 		return FAILED;
2134 
2135 	printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2136 	       hd->ioc->name, SCpnt);
2137 
2138 	if (hd->timeouts < -1)
2139 		hd->timeouts++;
2140 
2141 	/* Find this command
2142 	 */
2143 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2144 		/* Cmd not found in ScsiLookup.
2145 		 * Do OS callback.
2146 		 */
2147 		SCpnt->result = DID_RESET << 16;
2148 		dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2149 			   "Command not in the active list! (sc=%p)\n",
2150 			   hd->ioc->name, SCpnt));
2151 		return SUCCESS;
2152 	}
2153 
2154 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
2155 	 * (the IO to be ABORT'd)
2156 	 *
2157 	 * NOTE: Since we do not byteswap MsgContext, we do not
2158 	 *	 swap it here either.  It is an opaque cookie to
2159 	 *	 the controller, so it does not matter. -DaveM
2160 	 */
2161 	mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2162 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2163 
2164 	hd->abortSCpnt = SCpnt;
2165 
2166 	spin_unlock_irq(host_lock);
2167 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2168 		SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2169 		ctx2abort, 2 /* 2 second timeout */)
2170 		< 0) {
2171 
2172 		/* The TM request failed and the subsequent FW-reload failed!
2173 		 * Fatal error case.
2174 		 */
2175 		printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2176 		       hd->ioc->name, SCpnt);
2177 
2178 		/* We must clear our pending flag before clearing our state.
2179 		 */
2180 		hd->tmPending = 0;
2181 		hd->tmState = TM_STATE_NONE;
2182 
2183 		spin_lock_irq(host_lock);
2184 
2185 		/* Unmap the DMA buffers, if any. */
2186 		if (SCpnt->use_sg) {
2187 			pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
2188 				    SCpnt->use_sg, SCpnt->sc_data_direction);
2189 		} else if (SCpnt->request_bufflen) {
2190 			pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
2191 				SCpnt->request_bufflen, SCpnt->sc_data_direction);
2192 		}
2193 		hd->ScsiLookup[scpnt_idx] = NULL;
2194 		SCpnt->result = DID_RESET << 16;
2195 		SCpnt->scsi_done(SCpnt);		/* Issue the command callback */
2196 		mptscsih_freeChainBuffers(ioc, scpnt_idx);
2197 		mpt_free_msg_frame(ioc, mf);
2198 		return FAILED;
2199 	}
2200 	spin_lock_irq(host_lock);
2201 	return SUCCESS;
2202 }
2203 
2204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2205 /**
2206  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
2207  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2208  *
2209  *	(linux scsi_host_template.eh_dev_reset_handler routine)
2210  *
2211  *	Returns SUCCESS or FAILED.
2212  */
2213 static int
2214 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2215 {
2216 	MPT_SCSI_HOST	*hd;
2217 	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
2218 
2219 	/* If we can't locate our host adapter structure, return FAILED status.
2220 	 */
2221 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2222 		dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2223 			   "Can't locate host! (sc=%p)\n",
2224 			   SCpnt));
2225 		return FAILED;
2226 	}
2227 
2228 	if (hd->resetPending)
2229 		return FAILED;
2230 
2231 	printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2232 	       hd->ioc->name, SCpnt);
2233 
2234 	spin_unlock_irq(host_lock);
2235 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2236 		SCpnt->device->channel, SCpnt->device->id,
2237 		0, 0, 5 /* 5 second timeout */)
2238 		< 0){
2239 		/* The TM request failed and the subsequent FW-reload failed!
2240 		 * Fatal error case.
2241 		 */
2242 		printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2243 		 		hd->ioc->name, SCpnt);
2244 		hd->tmPending = 0;
2245 		hd->tmState = TM_STATE_NONE;
2246 		spin_lock_irq(host_lock);
2247 		return FAILED;
2248 	}
2249 	spin_lock_irq(host_lock);
2250 	return SUCCESS;
2251 
2252 }
2253 
2254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 /**
2256  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
2257  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2258  *
2259  *	(linux scsi_host_template.eh_bus_reset_handler routine)
2260  *
2261  *	Returns SUCCESS or FAILED.
2262  */
2263 static int
2264 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2265 {
2266 	MPT_SCSI_HOST	*hd;
2267 	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
2268 
2269 	/* If we can't locate our host adapter structure, return FAILED status.
2270 	 */
2271 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2272 		dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2273 			   "Can't locate host! (sc=%p)\n",
2274 			   SCpnt ) );
2275 		return FAILED;
2276 	}
2277 
2278 	printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2279 	       hd->ioc->name, SCpnt);
2280 
2281 	if (hd->timeouts < -1)
2282 		hd->timeouts++;
2283 
2284 	/* We are now ready to execute the task management request. */
2285 	spin_unlock_irq(host_lock);
2286 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2287 		SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
2288 	    < 0){
2289 
2290 		/* The TM request failed and the subsequent FW-reload failed!
2291 		 * Fatal error case.
2292 		 */
2293 		printk(MYIOC_s_WARN_FMT
2294 		       "Error processing TaskMgmt request (sc=%p)\n",
2295 		       hd->ioc->name, SCpnt);
2296 		hd->tmPending = 0;
2297 		hd->tmState = TM_STATE_NONE;
2298 		spin_lock_irq(host_lock);
2299 		return FAILED;
2300 	}
2301 	spin_lock_irq(host_lock);
2302 	return SUCCESS;
2303 }
2304 
2305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2306 /**
2307  *	mptscsih_host_reset - Perform a SCSI host adapter RESET!
2308  *	new_eh variant
2309  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2310  *
2311  *	(linux scsi_host_template.eh_host_reset_handler routine)
2312  *
2313  *	Returns SUCCESS or FAILED.
2314  */
2315 static int
2316 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2317 {
2318 	MPT_SCSI_HOST *  hd;
2319 	int              status = SUCCESS;
2320 	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
2321 
2322 	/*  If we can't locate the host to reset, then we failed. */
2323 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2324 		dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2325 			     "Can't locate host! (sc=%p)\n",
2326 			     SCpnt ) );
2327 		return FAILED;
2328 	}
2329 
2330 	printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2331 	       hd->ioc->name, SCpnt);
2332 
2333 	/*  If our attempts to reset the host failed, then return a failed
2334 	 *  status.  The host will be taken off line by the SCSI mid-layer.
2335 	 */
2336 	spin_unlock_irq(host_lock);
2337 	if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2338 		status = FAILED;
2339 	} else {
2340 		/*  Make sure TM pending is cleared and TM state is set to
2341 		 *  NONE.
2342 		 */
2343 		hd->tmPending = 0;
2344 		hd->tmState = TM_STATE_NONE;
2345 	}
2346 	spin_lock_irq(host_lock);
2347 
2348 
2349 	dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2350 		     "Status = %s\n",
2351 		     (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2352 
2353 	return status;
2354 }
2355 
2356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2357 /**
2358  *	mptscsih_tm_pending_wait - wait for pending task management request to
2359  *		complete.
2360  *	@hd: Pointer to MPT host structure.
2361  *
2362  *	Returns {SUCCESS,FAILED}.
2363  */
2364 static int
2365 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2366 {
2367 	unsigned long  flags;
2368 	int            loop_count = 4 * 10;  /* Wait 10 seconds */
2369 	int            status = FAILED;
2370 
2371 	do {
2372 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2373 		if (hd->tmState == TM_STATE_NONE) {
2374 			hd->tmState = TM_STATE_IN_PROGRESS;
2375 			hd->tmPending = 1;
2376 			status = SUCCESS;
2377 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2378 			break;
2379 		}
2380 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2381 		msleep(250);
2382 	} while (--loop_count);
2383 
2384 	return status;
2385 }
2386 
2387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2388 /**
2389  *	mptscsih_tm_wait_for_completion - wait for completion of TM task
2390  *	@hd: Pointer to MPT host structure.
2391  *
2392  *	Returns {SUCCESS,FAILED}.
2393  */
2394 static int
2395 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2396 {
2397 	unsigned long  flags;
2398 	int            loop_count = 4 * timeout;
2399 	int            status = FAILED;
2400 
2401 	do {
2402 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2403 		if(hd->tmPending == 0) {
2404 			status = SUCCESS;
2405 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2406 			break;
2407 		}
2408 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2409 		msleep_interruptible(250);
2410 	} while (--loop_count);
2411 
2412 	return status;
2413 }
2414 
2415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2416 /**
2417  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2418  *	@ioc: Pointer to MPT_ADAPTER structure
2419  *	@mf: Pointer to SCSI task mgmt request frame
2420  *	@mr: Pointer to SCSI task mgmt reply frame
2421  *
2422  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
2423  *	of any SCSI task management request.
2424  *	This routine is registered with the MPT (base) driver at driver
2425  *	load/init time via the mpt_register() API call.
2426  *
2427  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2428  */
2429 static int
2430 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2431 {
2432 	SCSITaskMgmtReply_t	*pScsiTmReply;
2433 	SCSITaskMgmt_t		*pScsiTmReq;
2434 	MPT_SCSI_HOST		*hd;
2435 	unsigned long		 flags;
2436 	u16			 iocstatus;
2437 	u8			 tmType;
2438 
2439 	dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2440 			ioc->name, mf, mr));
2441 	if (ioc->sh) {
2442 		/* Depending on the thread, a timer is activated for
2443 		 * the TM request.  Delete this timer on completion of TM.
2444 		 * Decrement count of outstanding TM requests.
2445 		 */
2446 		hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2447 	} else {
2448 		dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2449 			ioc->name));
2450 		return 1;
2451 	}
2452 
2453 	if (mr == NULL) {
2454 		dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2455 			ioc->name, mf));
2456 		return 1;
2457 	} else {
2458 		pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2459 		pScsiTmReq = (SCSITaskMgmt_t*)mf;
2460 
2461 		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2462 		tmType = pScsiTmReq->TaskType;
2463 
2464 		dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
2465 				ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2466 		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2467 
2468 		iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2469 		dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2470 			ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2471 		/* Error?  (anything non-zero?) */
2472 		if (iocstatus) {
2473 
2474 			/* clear flags and continue.
2475 			 */
2476 			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2477 				hd->abortSCpnt = NULL;
2478 
2479 			/* If an internal command is present
2480 			 * or the TM failed - reload the FW.
2481 			 * FC FW may respond FAILED to an ABORT
2482 			 */
2483 			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2484 				if ((hd->cmdPtr) ||
2485 				    (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2486 					if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2487 						printk((KERN_WARNING
2488 							" Firmware Reload FAILED!!\n"));
2489 					}
2490 				}
2491 			}
2492 		} else {
2493 			dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2494 
2495 			hd->abortSCpnt = NULL;
2496 
2497 		}
2498 	}
2499 
2500 	spin_lock_irqsave(&ioc->FreeQlock, flags);
2501 	hd->tmPending = 0;
2502 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2503 	hd->tmState = TM_STATE_NONE;
2504 
2505 	return 1;
2506 }
2507 
2508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2509 /*
2510  *	This is anyones guess quite frankly.
2511  */
2512 static int
2513 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2514 		sector_t capacity, int geom[])
2515 {
2516 	int		heads;
2517 	int		sectors;
2518 	sector_t	cylinders;
2519 	ulong 		dummy;
2520 
2521 	heads = 64;
2522 	sectors = 32;
2523 
2524 	dummy = heads * sectors;
2525 	cylinders = capacity;
2526 	sector_div(cylinders,dummy);
2527 
2528 	/*
2529 	 * Handle extended translation size for logical drives
2530 	 * > 1Gb
2531 	 */
2532 	if ((ulong)capacity >= 0x200000) {
2533 		heads = 255;
2534 		sectors = 63;
2535 		dummy = heads * sectors;
2536 		cylinders = capacity;
2537 		sector_div(cylinders,dummy);
2538 	}
2539 
2540 	/* return result */
2541 	geom[0] = heads;
2542 	geom[1] = sectors;
2543 	geom[2] = cylinders;
2544 
2545 	dprintk((KERN_NOTICE
2546 		": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2547 		sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2548 
2549 	return 0;
2550 }
2551 
2552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2553 /*
2554  *	OS entry point to allow host driver to alloc memory
2555  *	for each scsi device. Called once per device the bus scan.
2556  *	Return non-zero if allocation fails.
2557  *	Init memory once per id (not LUN).
2558  */
2559 static int
2560 mptscsih_slave_alloc(struct scsi_device *device)
2561 {
2562 	struct Scsi_Host	*host = device->host;
2563 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
2564 	VirtDevice		*vdev;
2565 	uint			target = device->id;
2566 
2567 	if (hd == NULL)
2568 		return -ENODEV;
2569 
2570 	if ((vdev = hd->Targets[target]) != NULL)
2571 		goto out;
2572 
2573 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2574 	if (!vdev) {
2575 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2576 				hd->ioc->name, sizeof(VirtDevice));
2577 		return -ENOMEM;
2578 	}
2579 
2580 	memset(vdev, 0, sizeof(VirtDevice));
2581 	vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2582 	vdev->ioc_id = hd->ioc->id;
2583 	vdev->target_id = device->id;
2584 	vdev->bus_id = device->channel;
2585 	vdev->raidVolume = 0;
2586 	hd->Targets[device->id] = vdev;
2587 	if (hd->ioc->bus_type == SCSI) {
2588 		if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2589 			vdev->raidVolume = 1;
2590 			ddvtprintk((KERN_INFO
2591 			    "RAID Volume @ id %d\n", device->id));
2592 		}
2593 	} else {
2594 		vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2595 	}
2596 
2597  out:
2598 	vdev->num_luns++;
2599 	return 0;
2600 }
2601 
2602 static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2603 {
2604 	int i;
2605 
2606 	if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2607 		return 0;
2608 
2609 	for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2610 		if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2611 			return 1;
2612 	}
2613 
2614 	return 0;
2615 }
2616 
2617 /*
2618  *	OS entry point to allow for host driver to free allocated memory
2619  *	Called if no device present or device being unloaded
2620  */
2621 static void
2622 mptscsih_slave_destroy(struct scsi_device *device)
2623 {
2624 	struct Scsi_Host	*host = device->host;
2625 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
2626 	VirtDevice		*vdev;
2627 	uint			target = device->id;
2628 	uint			lun = device->lun;
2629 
2630 	if (hd == NULL)
2631 		return;
2632 
2633 	mptscsih_search_running_cmds(hd, target, lun);
2634 
2635 	vdev = hd->Targets[target];
2636 	vdev->luns[0] &= ~(1 << lun);
2637 	if (--vdev->num_luns)
2638 		return;
2639 
2640 	kfree(hd->Targets[target]);
2641 	hd->Targets[target] = NULL;
2642 
2643 	if (hd->ioc->bus_type == SCSI) {
2644 		if (mptscsih_is_raid_volume(hd, target)) {
2645 			hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2646 		} else {
2647 			hd->ioc->spi_data.dvStatus[target] =
2648 				MPT_SCSICFG_NEGOTIATE;
2649 
2650 			if (!hd->negoNvram) {
2651 				hd->ioc->spi_data.dvStatus[target] |=
2652 					MPT_SCSICFG_DV_NOT_DONE;
2653 			}
2654 		}
2655 	}
2656 }
2657 
2658 static void
2659 mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2660 	VirtDevice *pTarget, int qdepth)
2661 {
2662 	int	max_depth;
2663 	int	tagged;
2664 
2665 	if (hd->ioc->bus_type == SCSI) {
2666 		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2667 			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2668 				max_depth = 1;
2669 			else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2670 			         (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2671 				max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2672 			else
2673 				max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2674 		} else {
2675 			/* error case - No Inq. Data */
2676 			max_depth = 1;
2677 		}
2678 	} else
2679 		max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2680 
2681 	if (qdepth > max_depth)
2682 		qdepth = max_depth;
2683 	if (qdepth == 1)
2684 		tagged = 0;
2685 	else
2686 		tagged = MSG_SIMPLE_TAG;
2687 
2688 	scsi_adjust_queue_depth(device, tagged, qdepth);
2689 }
2690 
2691 
2692 /*
2693  *	OS entry point to adjust the queue_depths on a per-device basis.
2694  *	Called once per device the bus scan. Use it to force the queue_depth
2695  *	member to 1 if a device does not support Q tags.
2696  *	Return non-zero if fails.
2697  */
2698 static int
2699 mptscsih_slave_configure(struct scsi_device *device)
2700 {
2701 	struct Scsi_Host	*sh = device->host;
2702 	VirtDevice		*pTarget;
2703 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sh->hostdata;
2704 
2705 	if ((hd == NULL) || (hd->Targets == NULL)) {
2706 		return 0;
2707 	}
2708 
2709 	dsprintk((MYIOC_s_INFO_FMT
2710 		"device @ %p, id=%d, LUN=%d, channel=%d\n",
2711 		hd->ioc->name, device, device->id, device->lun, device->channel));
2712 	dsprintk((MYIOC_s_INFO_FMT
2713 		"sdtr %d wdtr %d ppr %d inq length=%d\n",
2714 		hd->ioc->name, device->sdtr, device->wdtr,
2715 		device->ppr, device->inquiry_len));
2716 
2717 	if (device->id > sh->max_id) {
2718 		/* error case, should never happen */
2719 		scsi_adjust_queue_depth(device, 0, 1);
2720 		goto slave_configure_exit;
2721 	}
2722 
2723 	pTarget = hd->Targets[device->id];
2724 
2725 	if (pTarget == NULL) {
2726 		/* Driver doesn't know about this device.
2727 		 * Kernel may generate a "Dummy Lun 0" which
2728 		 * may become a real Lun if a
2729 		 * "scsi add-single-device" command is executed
2730 		 * while the driver is active (hot-plug a
2731 		 * device).  LSI Raid controllers need
2732 		 * queue_depth set to DEV_HIGH for this reason.
2733 		 */
2734 		scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2735 			MPT_SCSI_CMD_PER_DEV_HIGH);
2736 		goto slave_configure_exit;
2737 	}
2738 
2739 	mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2740 		device->inquiry, device->inquiry_len );
2741 	mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2742 
2743 	dsprintk((MYIOC_s_INFO_FMT
2744 		"Queue depth=%d, tflags=%x\n",
2745 		hd->ioc->name, device->queue_depth, pTarget->tflags));
2746 
2747 	dsprintk((MYIOC_s_INFO_FMT
2748 		"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2749 		hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2750 
2751 slave_configure_exit:
2752 
2753 	dsprintk((MYIOC_s_INFO_FMT
2754 		"tagged %d, simple %d, ordered %d\n",
2755 		hd->ioc->name,device->tagged_supported, device->simple_tags,
2756 		device->ordered_tags));
2757 
2758 	return 0;
2759 }
2760 
2761 static ssize_t
2762 mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2763 {
2764 	int			 depth;
2765 	struct scsi_device	*sdev = to_scsi_device(dev);
2766 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2767 	VirtDevice		*pTarget;
2768 
2769 	depth = simple_strtoul(buf, NULL, 0);
2770 	if (depth == 0)
2771 		return -EINVAL;
2772 	pTarget = hd->Targets[sdev->id];
2773 	if (pTarget == NULL)
2774 		return -EINVAL;
2775 	mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2776 		pTarget, depth);
2777 	return count;
2778 }
2779 
2780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2781 /*
2782  *  Private routines...
2783  */
2784 
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 /* Utility function to copy sense data from the scsi_cmnd buffer
2787  * to the FC and SCSI target structures.
2788  *
2789  */
2790 static void
2791 copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2792 {
2793 	VirtDevice	*target;
2794 	SCSIIORequest_t	*pReq;
2795 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2796 	int		 index;
2797 
2798 	/* Get target structure
2799 	 */
2800 	pReq = (SCSIIORequest_t *) mf;
2801 	index = (int) pReq->TargetID;
2802 	target = hd->Targets[index];
2803 
2804 	if (sense_count) {
2805 		u8 *sense_data;
2806 		int req_index;
2807 
2808 		/* Copy the sense received into the scsi command block. */
2809 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2810 		sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2811 		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2812 
2813 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2814 		 */
2815 		if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2816 			if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2817 				int idx;
2818 				MPT_ADAPTER *ioc = hd->ioc;
2819 
2820 				idx = ioc->eventContext % ioc->eventLogSize;
2821 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2822 				ioc->events[idx].eventContext = ioc->eventContext;
2823 
2824 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2825 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2826 					(pReq->Bus << 8) || pReq->TargetID;
2827 
2828 				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2829 
2830 				ioc->eventContext++;
2831 			}
2832 		}
2833 	} else {
2834 		dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2835 				hd->ioc->name));
2836 	}
2837 }
2838 
2839 static u32
2840 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2841 {
2842 	MPT_SCSI_HOST *hd;
2843 	int i;
2844 
2845 	hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2846 
2847 	for (i = 0; i < hd->ioc->req_depth; i++) {
2848 		if (hd->ScsiLookup[i] == sc) {
2849 			return i;
2850 		}
2851 	}
2852 
2853 	return -1;
2854 }
2855 
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857 static int
2858 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2859 {
2860 	MPT_SCSI_HOST	*hd;
2861 	unsigned long	 flags;
2862 
2863 	dtmprintk((KERN_WARNING MYNAM
2864 			": IOC %s_reset routed to SCSI host driver!\n",
2865 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2866 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2867 
2868 	/* If a FW reload request arrives after base installed but
2869 	 * before all scsi hosts have been attached, then an alt_ioc
2870 	 * may have a NULL sh pointer.
2871 	 */
2872 	if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2873 		return 0;
2874 	else
2875 		hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2876 
2877 	if (reset_phase == MPT_IOC_SETUP_RESET) {
2878 		dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2879 
2880 		/* Clean Up:
2881 		 * 1. Set Hard Reset Pending Flag
2882 		 * All new commands go to doneQ
2883 		 */
2884 		hd->resetPending = 1;
2885 
2886 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
2887 		dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2888 
2889 		/* 2. Flush running commands
2890 		 *	Clean ScsiLookup (and associated memory)
2891 		 *	AND clean mytaskQ
2892 		 */
2893 
2894 		/* 2b. Reply to OS all known outstanding I/O commands.
2895 		 */
2896 		mptscsih_flush_running_cmds(hd);
2897 
2898 		/* 2c. If there was an internal command that
2899 		 * has not completed, configuration or io request,
2900 		 * free these resources.
2901 		 */
2902 		if (hd->cmdPtr) {
2903 			del_timer(&hd->timer);
2904 			mpt_free_msg_frame(ioc, hd->cmdPtr);
2905 		}
2906 
2907 		dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2908 
2909 	} else {
2910 		dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2911 
2912 		/* Once a FW reload begins, all new OS commands are
2913 		 * redirected to the doneQ w/ a reset status.
2914 		 * Init all control structures.
2915 		 */
2916 
2917 		/* ScsiLookup initialization
2918 		 */
2919 		{
2920 			int ii;
2921 			for (ii=0; ii < hd->ioc->req_depth; ii++)
2922 				hd->ScsiLookup[ii] = NULL;
2923 		}
2924 
2925 		/* 2. Chain Buffer initialization
2926 		 */
2927 
2928 		/* 4. Renegotiate to all devices, if SCSI
2929 		 */
2930 		if (ioc->bus_type == SCSI) {
2931 			dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2932 			mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2933 		}
2934 
2935 		/* 5. Enable new commands to be posted
2936 		 */
2937 		spin_lock_irqsave(&ioc->FreeQlock, flags);
2938 		hd->tmPending = 0;
2939 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2940 		hd->resetPending = 0;
2941 		hd->tmState = TM_STATE_NONE;
2942 
2943 		/* 6. If there was an internal command,
2944 		 * wake this process up.
2945 		 */
2946 		if (hd->cmdPtr) {
2947 			/*
2948 			 * Wake up the original calling thread
2949 			 */
2950 			hd->pLocal = &hd->localReply;
2951 			hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2952 			scandv_wait_done = 1;
2953 			wake_up(&scandv_waitq);
2954 			hd->cmdPtr = NULL;
2955 		}
2956 
2957 		/* 7. Set flag to force DV and re-read IOC Page 3
2958 		 */
2959 		if (ioc->bus_type == SCSI) {
2960 			ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2961 			ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2962 		}
2963 
2964 		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2965 
2966 	}
2967 
2968 	return 1;		/* currently means nothing really */
2969 }
2970 
2971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2972 static int
2973 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2974 {
2975 	MPT_SCSI_HOST *hd;
2976 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2977 
2978 	devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2979 			ioc->name, event));
2980 
2981 	switch (event) {
2982 	case MPI_EVENT_UNIT_ATTENTION:			/* 03 */
2983 		/* FIXME! */
2984 		break;
2985 	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
2986 	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
2987 		hd = NULL;
2988 		if (ioc->sh) {
2989 			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2990 			if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2991 				hd->soft_resets++;
2992 		}
2993 		break;
2994 	case MPI_EVENT_LOGOUT:				/* 09 */
2995 		/* FIXME! */
2996 		break;
2997 
2998 		/*
2999 		 *  CHECKME! Don't think we need to do
3000 		 *  anything for these, but...
3001 		 */
3002 	case MPI_EVENT_RESCAN:				/* 06 */
3003 	case MPI_EVENT_LINK_STATUS_CHANGE:		/* 07 */
3004 	case MPI_EVENT_LOOP_STATE_CHANGE:		/* 08 */
3005 		/*
3006 		 *  CHECKME!  Falling thru...
3007 		 */
3008 		break;
3009 
3010 	case MPI_EVENT_INTEGRATED_RAID:			/* 0B */
3011 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3012 		/* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3013 		 * if DV disabled. Need to check for target mode.
3014 		 */
3015 		hd = NULL;
3016 		if (ioc->sh)
3017 			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3018 
3019 		if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
3020 			ScsiCfgData	*pSpi;
3021 			Ioc3PhysDisk_t	*pPDisk;
3022 			int		 numPDisk;
3023 			u8		 reason;
3024 			u8		 physDiskNum;
3025 
3026 			reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3027 			if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3028 				/* New or replaced disk.
3029 				 * Set DV flag and schedule DV.
3030 				 */
3031 				pSpi = &ioc->spi_data;
3032 				physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3033 				ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3034 				if (pSpi->pIocPg3) {
3035 					pPDisk =  pSpi->pIocPg3->PhysDisk;
3036 					numPDisk =pSpi->pIocPg3->NumPhysDisks;
3037 
3038 					while (numPDisk) {
3039 						if (physDiskNum == pPDisk->PhysDiskNum) {
3040 							pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3041 							pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3042 							ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3043 							break;
3044 						}
3045 						pPDisk++;
3046 						numPDisk--;
3047 					}
3048 
3049 					if (numPDisk == 0) {
3050 						/* The physical disk that needs DV was not found
3051 						 * in the stored IOC Page 3. The driver must reload
3052 						 * this page. DV routine will set the NEED_DV flag for
3053 						 * all phys disks that have DV_NOT_DONE set.
3054 						 */
3055 						pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3056 						ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3057 					}
3058 				}
3059 			}
3060 		}
3061 #endif
3062 
3063 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3064 		printk("Raid Event RF: ");
3065 		{
3066 			u32 *m = (u32 *)pEvReply;
3067 			int ii;
3068 			int n = (int)pEvReply->MsgLength;
3069 			for (ii=6; ii < n; ii++)
3070 				printk(" %08x", le32_to_cpu(m[ii]));
3071 			printk("\n");
3072 		}
3073 #endif
3074 		break;
3075 
3076 	case MPI_EVENT_NONE:				/* 00 */
3077 	case MPI_EVENT_LOG_DATA:			/* 01 */
3078 	case MPI_EVENT_STATE_CHANGE:			/* 02 */
3079 	case MPI_EVENT_EVENT_CHANGE:			/* 0A */
3080 	default:
3081 		dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
3082 		break;
3083 	}
3084 
3085 	return 1;		/* currently means nothing really */
3086 }
3087 
3088 static struct device_attribute mptscsih_queue_depth_attr = {
3089 	.attr = {
3090 		.name = 	"queue_depth",
3091 		.mode =		S_IWUSR,
3092 	},
3093 	.store = mptscsih_store_queue_depth,
3094 };
3095 
3096 static struct device_attribute *mptscsih_dev_attrs[] = {
3097 	&mptscsih_queue_depth_attr,
3098 	NULL,
3099 };
3100 
3101 static struct scsi_host_template driver_template = {
3102 	.proc_name			= "mptscsih",
3103 	.proc_info			= mptscsih_proc_info,
3104 	.name				= "MPT SCSI Host",
3105 	.info				= mptscsih_info,
3106 	.queuecommand			= mptscsih_qcmd,
3107 	.slave_alloc			= mptscsih_slave_alloc,
3108 	.slave_configure		= mptscsih_slave_configure,
3109 	.slave_destroy			= mptscsih_slave_destroy,
3110 	.eh_abort_handler		= mptscsih_abort,
3111 	.eh_device_reset_handler	= mptscsih_dev_reset,
3112 	.eh_bus_reset_handler		= mptscsih_bus_reset,
3113 	.eh_host_reset_handler		= mptscsih_host_reset,
3114 	.bios_param			= mptscsih_bios_param,
3115 	.can_queue			= MPT_SCSI_CAN_QUEUE,
3116 	.this_id			= -1,
3117 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
3118 	.max_sectors			= 8192,
3119 	.cmd_per_lun			= 7,
3120 	.use_clustering			= ENABLE_CLUSTERING,
3121 	.sdev_attrs			= mptscsih_dev_attrs,
3122 };
3123 
3124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3125 /*
3126  *	mptscsih_initTarget - Target, LUN alloc/free functionality.
3127  *	@hd: Pointer to MPT_SCSI_HOST structure
3128  *	@bus_id: Bus number (?)
3129  *	@target_id: SCSI target id
3130  *	@lun: SCSI LUN id
3131  *	@data: Pointer to data
3132  *	@dlen: Number of INQUIRY bytes
3133  *
3134  *	NOTE: It's only SAFE to call this routine if data points to
3135  *	sane & valid STANDARD INQUIRY data!
3136  *
3137  *	Allocate and initialize memory for this target.
3138  *	Save inquiry data.
3139  *
3140  */
3141 static void
3142 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
3143 {
3144 	int		indexed_lun, lun_index;
3145 	VirtDevice	*vdev;
3146 	ScsiCfgData	*pSpi;
3147 	char		data_56;
3148 
3149 	dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
3150 			hd->ioc->name, bus_id, target_id, lun, hd));
3151 
3152 	/*
3153 	 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
3154 	 * (i.e. The targer is capable of supporting the specified peripheral device type
3155 	 * on this logical unit; however, the physical device is not currently connected
3156 	 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
3157 	 * capable of supporting a physical device on this logical unit). This is to work
3158 	 * around a bug in th emid-layer in some distributions in which the mid-layer will
3159 	 * continue to try to communicate to the LUN and evntually create a dummy LUN.
3160 	*/
3161 	if (mpt_pq_filter && dlen && (data[0] & 0xE0))
3162 		data[0] |= 0x40;
3163 
3164 	/* Is LUN supported? If so, upper 2 bits will be 0
3165 	* in first byte of inquiry data.
3166 	*/
3167 	if (data[0] & 0xe0)
3168 		return;
3169 
3170 	if ((vdev = hd->Targets[target_id]) == NULL) {
3171 		return;
3172 	}
3173 
3174 	lun_index = (lun >> 5);  /* 32 luns per lun_index */
3175 	indexed_lun = (lun % 32);
3176 	vdev->luns[lun_index] |= (1 << indexed_lun);
3177 
3178 	if (hd->ioc->bus_type == SCSI) {
3179 		if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
3180 			/* Treat all Processors as SAF-TE if
3181 			 * command line option is set */
3182 			vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3183 			mptscsih_writeIOCPage4(hd, target_id, bus_id);
3184 		}else if ((data[0] == TYPE_PROCESSOR) &&
3185 			!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
3186 			if ( dlen > 49 ) {
3187 				vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3188 				if ( data[44] == 'S' &&
3189 				     data[45] == 'A' &&
3190 				     data[46] == 'F' &&
3191 				     data[47] == '-' &&
3192 				     data[48] == 'T' &&
3193 				     data[49] == 'E' ) {
3194 					vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3195 					mptscsih_writeIOCPage4(hd, target_id, bus_id);
3196 				}
3197 			}
3198 		}
3199 		if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
3200 			if ( dlen > 8 ) {
3201 				memcpy (vdev->inq_data, data, 8);
3202 			} else {
3203 				memcpy (vdev->inq_data, data, dlen);
3204 			}
3205 
3206 			/* If have not done DV, set the DV flag.
3207 			 */
3208 			pSpi = &hd->ioc->spi_data;
3209 			if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
3210 				if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
3211 					pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
3212 			}
3213 
3214 			vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3215 
3216 
3217 			data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
3218 			if (dlen > 56) {
3219 				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3220 				/* Update the target capabilities
3221 				 */
3222 					data_56 = data[56];
3223 					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3224 				}
3225 			}
3226 			mptscsih_setTargetNegoParms(hd, vdev, data_56);
3227 		} else {
3228 			/* Initial Inquiry may not request enough data bytes to
3229 			 * obtain byte 57.  DV will; if target doesn't return
3230 			 * at least 57 bytes, data[56] will be zero. */
3231 			if (dlen > 56) {
3232 				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3233 				/* Update the target capabilities
3234 				 */
3235 					data_56 = data[56];
3236 					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3237 					mptscsih_setTargetNegoParms(hd, vdev, data_56);
3238 				}
3239 			}
3240 		}
3241 	}
3242 }
3243 
3244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3245 /*
3246  *  Update the target negotiation parameters based on the
3247  *  the Inquiry data, adapter capabilities, and NVRAM settings.
3248  *
3249  */
3250 static void
3251 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
3252 {
3253 	ScsiCfgData *pspi_data = &hd->ioc->spi_data;
3254 	int  id = (int) target->target_id;
3255 	int  nvram;
3256 	VirtDevice	*vdev;
3257 	int ii;
3258 	u8 width = MPT_NARROW;
3259 	u8 factor = MPT_ASYNC;
3260 	u8 offset = 0;
3261 	u8 version, nfactor;
3262 	u8 noQas = 1;
3263 
3264 	target->negoFlags = pspi_data->noQas;
3265 
3266 	/* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3267 	 * support. If available, default QAS to off and allow enabling.
3268 	 * If not available, default QAS to on, turn off for non-disks.
3269 	 */
3270 
3271 	/* Set flags based on Inquiry data
3272 	 */
3273 	version = target->inq_data[2] & 0x07;
3274 	if (version < 2) {
3275 		width = 0;
3276 		factor = MPT_ULTRA2;
3277 		offset = pspi_data->maxSyncOffset;
3278 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3279 	} else {
3280 		if (target->inq_data[7] & 0x20) {
3281 			width = 1;
3282 		}
3283 
3284 		if (target->inq_data[7] & 0x10) {
3285 			factor = pspi_data->minSyncFactor;
3286 			if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
3287 				/* bits 2 & 3 show Clocking support */
3288 				if ((byte56 & 0x0C) == 0)
3289 					factor = MPT_ULTRA2;
3290 				else {
3291 					if ((byte56 & 0x03) == 0)
3292 						factor = MPT_ULTRA160;
3293 					else {
3294 						factor = MPT_ULTRA320;
3295 						if (byte56 & 0x02)
3296 						{
3297 							ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
3298 							noQas = 0;
3299 						}
3300 						if (target->inq_data[0] == TYPE_TAPE) {
3301 							if (byte56 & 0x01)
3302 								target->negoFlags |= MPT_TAPE_NEGO_IDP;
3303 						}
3304 					}
3305 				}
3306 			} else {
3307 				ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
3308 				noQas = 0;
3309 			}
3310 
3311 			offset = pspi_data->maxSyncOffset;
3312 
3313 			/* If RAID, never disable QAS
3314 			 * else if non RAID, do not disable
3315 			 *   QAS if bit 1 is set
3316 			 * bit 1 QAS support, non-raid only
3317 			 * bit 0 IU support
3318 			 */
3319 			if (target->raidVolume == 1) {
3320 				noQas = 0;
3321 			}
3322 		} else {
3323 			factor = MPT_ASYNC;
3324 			offset = 0;
3325 		}
3326 	}
3327 
3328 	if ( (target->inq_data[7] & 0x02) == 0) {
3329 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3330 	}
3331 
3332 	/* Update tflags based on NVRAM settings. (SCSI only)
3333 	 */
3334 	if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3335 		nvram = pspi_data->nvram[id];
3336 		nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3337 
3338 		if (width)
3339 			width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3340 
3341 		if (offset > 0) {
3342 			/* Ensure factor is set to the
3343 			 * maximum of: adapter, nvram, inquiry
3344 			 */
3345 			if (nfactor) {
3346 				if (nfactor < pspi_data->minSyncFactor )
3347 					nfactor = pspi_data->minSyncFactor;
3348 
3349 				factor = max(factor, nfactor);
3350 				if (factor == MPT_ASYNC)
3351 					offset = 0;
3352 			} else {
3353 				offset = 0;
3354 				factor = MPT_ASYNC;
3355 		}
3356 		} else {
3357 			factor = MPT_ASYNC;
3358 		}
3359 	}
3360 
3361 	/* Make sure data is consistent
3362 	 */
3363 	if ((!width) && (factor < MPT_ULTRA2)) {
3364 		factor = MPT_ULTRA2;
3365 	}
3366 
3367 	/* Save the data to the target structure.
3368 	 */
3369 	target->minSyncFactor = factor;
3370 	target->maxOffset = offset;
3371 	target->maxWidth = width;
3372 
3373 	target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
3374 
3375 	/* Disable unused features.
3376 	 */
3377 	if (!width)
3378 		target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3379 
3380 	if (!offset)
3381 		target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3382 
3383 	if ( factor > MPT_ULTRA320 )
3384 		noQas = 0;
3385 
3386 	/* GEM, processor WORKAROUND
3387 	 */
3388 	if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
3389 		target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
3390 		pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
3391 	} else {
3392 		if (noQas && (pspi_data->noQas == 0)) {
3393 			pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
3394 			target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3395 
3396 			/* Disable QAS in a mixed configuration case
3397 	 		*/
3398 
3399 			ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3400 			for (ii = 0; ii < id; ii++) {
3401 				if ( (vdev = hd->Targets[ii]) ) {
3402 					vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3403 					mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
3404 				}
3405 			}
3406 		}
3407 	}
3408 
3409 	/* Write SDP1 on this I/O to this target */
3410 	if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3411 		ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3412 		mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3413 		pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3414 	} else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3415 		ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3416 		mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3417 		pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3418 	}
3419 }
3420 
3421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3422 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3423  * Else set the NEED_DV flag after Read Capacity Issued (disks)
3424  * or Mode Sense (cdroms).
3425  *
3426  * Tapes, initTarget will set this flag on completion of Inquiry command.
3427  * Called only if DV_NOT_DONE flag is set
3428  */
3429 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3430 {
3431 	u8 cmd;
3432 	ScsiCfgData *pSpi;
3433 
3434 	ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3435 		pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
3436 
3437 	if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3438 		return;
3439 
3440 	cmd = pReq->CDB[0];
3441 
3442 	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3443 		pSpi = &hd->ioc->spi_data;
3444 		if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3445 			/* Set NEED_DV for all hidden disks
3446 			 */
3447 			Ioc3PhysDisk_t *pPDisk =  pSpi->pIocPg3->PhysDisk;
3448 			int		numPDisk = pSpi->pIocPg3->NumPhysDisks;
3449 
3450 			while (numPDisk) {
3451 				pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3452 				ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3453 				pPDisk++;
3454 				numPDisk--;
3455 			}
3456 		}
3457 		pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3458 		ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3459 	}
3460 }
3461 
3462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3463 /*
3464  * If no Target, bus reset on 1st I/O. Set the flag to
3465  * prevent any future negotiations to this device.
3466  */
3467 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3468 {
3469 
3470 	if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3471 		hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3472 
3473 	return;
3474 }
3475 
3476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3477 /*
3478  *  SCSI Config Page functionality ...
3479  */
3480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3481 /*	mptscsih_setDevicePage1Flags  - add Requested and Configuration fields flags
3482  *	based on width, factor and offset parameters.
3483  *	@width: bus width
3484  *	@factor: sync factor
3485  *	@offset: sync offset
3486  *	@requestedPtr: pointer to requested values (updated)
3487  *	@configurationPtr: pointer to configuration values (updated)
3488  *	@flags: flags to block WDTR or SDTR negotiation
3489  *
3490  *	Return: None.
3491  *
3492  *	Remark: Called by writeSDP1 and _dv_params
3493  */
3494 static void
3495 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3496 {
3497 	u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3498 	u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3499 
3500 	*configurationPtr = 0;
3501 	*requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3502 	*requestedPtr |= (offset << 16) | (factor << 8);
3503 
3504 	if (width && offset && !nowide && !nosync) {
3505 		if (factor < MPT_ULTRA160) {
3506 			*requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3507 			if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3508 				*requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3509 			if (flags & MPT_TAPE_NEGO_IDP)
3510 				*requestedPtr |= 0x08000000;
3511 		} else if (factor < MPT_ULTRA2) {
3512 			*requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3513 		}
3514 	}
3515 
3516 	if (nowide)
3517 		*configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3518 
3519 	if (nosync)
3520 		*configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3521 
3522 	return;
3523 }
3524 
3525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3526 /*	mptscsih_writeSDP1  - write SCSI Device Page 1
3527  *	@hd: Pointer to a SCSI Host Strucutre
3528  *	@portnum: IOC port number
3529  *	@target_id: writeSDP1 for single ID
3530  *	@flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3531  *
3532  *	Return: -EFAULT if read of config page header fails
3533  *		or 0 if success.
3534  *
3535  *	Remark: If a target has been found, the settings from the
3536  *		target structure are used, else the device is set
3537  *		to async/narrow.
3538  *
3539  *	Remark: Called during init and after a FW reload.
3540  *	Remark: We do not wait for a return, write pages sequentially.
3541  */
3542 static int
3543 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3544 {
3545 	MPT_ADAPTER		*ioc = hd->ioc;
3546 	Config_t		*pReq;
3547 	SCSIDevicePage1_t	*pData;
3548 	VirtDevice		*pTarget;
3549 	MPT_FRAME_HDR		*mf;
3550 	dma_addr_t		 dataDma;
3551 	u16			 req_idx;
3552 	u32			 frameOffset;
3553 	u32			 requested, configuration, flagsLength;
3554 	int			 ii, nvram;
3555 	int			 id = 0, maxid = 0;
3556 	u8			 width;
3557 	u8			 factor;
3558 	u8			 offset;
3559 	u8			 bus = 0;
3560 	u8			 negoFlags;
3561 	u8			 maxwidth, maxoffset, maxfactor;
3562 
3563 	if (ioc->spi_data.sdp1length == 0)
3564 		return 0;
3565 
3566 	if (flags & MPT_SCSICFG_ALL_IDS) {
3567 		id = 0;
3568 		maxid = ioc->sh->max_id - 1;
3569 	} else if (ioc->sh) {
3570 		id = target_id;
3571 		maxid = min_t(int, id, ioc->sh->max_id - 1);
3572 	}
3573 
3574 	for (; id <= maxid; id++) {
3575 
3576 		if (id == ioc->pfacts[portnum].PortSCSIID)
3577 			continue;
3578 
3579 		/* Use NVRAM to get adapter and target maximums
3580 		 * Data over-riden by target structure information, if present
3581 		 */
3582 		maxwidth = ioc->spi_data.maxBusWidth;
3583 		maxoffset = ioc->spi_data.maxSyncOffset;
3584 		maxfactor = ioc->spi_data.minSyncFactor;
3585 		if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3586 			nvram = ioc->spi_data.nvram[id];
3587 
3588 			if (maxwidth)
3589 				maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3590 
3591 			if (maxoffset > 0) {
3592 				maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3593 				if (maxfactor == 0) {
3594 					/* Key for async */
3595 					maxfactor = MPT_ASYNC;
3596 					maxoffset = 0;
3597 				} else if (maxfactor < ioc->spi_data.minSyncFactor) {
3598 					maxfactor = ioc->spi_data.minSyncFactor;
3599 				}
3600 			} else
3601 				maxfactor = MPT_ASYNC;
3602 		}
3603 
3604 		/* Set the negotiation flags.
3605 		 */
3606 		negoFlags = ioc->spi_data.noQas;
3607 		if (!maxwidth)
3608 			negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3609 
3610 		if (!maxoffset)
3611 			negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3612 
3613 		if (flags & MPT_SCSICFG_USE_NVRAM) {
3614 			width = maxwidth;
3615 			factor = maxfactor;
3616 			offset = maxoffset;
3617 		} else {
3618 			width = 0;
3619 			factor = MPT_ASYNC;
3620 			offset = 0;
3621 			//negoFlags = 0;
3622 			//negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3623 		}
3624 
3625 		/* If id is not a raid volume, get the updated
3626 		 * transmission settings from the target structure.
3627 		 */
3628 		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3629 			width = pTarget->maxWidth;
3630 			factor = pTarget->minSyncFactor;
3631 			offset = pTarget->maxOffset;
3632 			negoFlags = pTarget->negoFlags;
3633 		}
3634 
3635 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3636 		/* Force to async and narrow if DV has not been executed
3637 		 * for this ID
3638 		 */
3639 		if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3640 			width = 0;
3641 			factor = MPT_ASYNC;
3642 			offset = 0;
3643 		}
3644 #endif
3645 
3646 		if (flags & MPT_SCSICFG_BLK_NEGO)
3647 			negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3648 
3649 		mptscsih_setDevicePage1Flags(width, factor, offset,
3650 					&requested, &configuration, negoFlags);
3651 		dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3652 			target_id, width, factor, offset, negoFlags, requested, configuration));
3653 
3654 		/* Get a MF for this command.
3655 		 */
3656 		if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3657 			dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3658 						ioc->name));
3659 			return -EAGAIN;
3660 		}
3661 
3662 		ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3663 			hd->ioc->name, mf, id, requested, configuration));
3664 
3665 
3666 		/* Set the request and the data pointers.
3667 		 * Request takes: 36 bytes (32 bit SGE)
3668 		 * SCSI Device Page 1 requires 16 bytes
3669 		 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3670 		 * and MF size >= 64 bytes.
3671 		 * Place data at end of MF.
3672 		 */
3673 		pReq = (Config_t *)mf;
3674 
3675 		req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3676 		frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3677 
3678 		pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3679 		dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3680 
3681 		/* Complete the request frame (same for all requests).
3682 		 */
3683 		pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3684 		pReq->Reserved = 0;
3685 		pReq->ChainOffset = 0;
3686 		pReq->Function = MPI_FUNCTION_CONFIG;
3687 		pReq->ExtPageLength = 0;
3688 		pReq->ExtPageType = 0;
3689 		pReq->MsgFlags = 0;
3690 		for (ii=0; ii < 8; ii++) {
3691 			pReq->Reserved2[ii] = 0;
3692 		}
3693 		pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3694 		pReq->Header.PageLength = ioc->spi_data.sdp1length;
3695 		pReq->Header.PageNumber = 1;
3696 		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3697 		pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3698 
3699 		/* Add a SGE to the config request.
3700 		 */
3701 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3702 
3703 		mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3704 
3705 		/* Set up the common data portion
3706 		 */
3707 		pData->Header.PageVersion = pReq->Header.PageVersion;
3708 		pData->Header.PageLength = pReq->Header.PageLength;
3709 		pData->Header.PageNumber = pReq->Header.PageNumber;
3710 		pData->Header.PageType = pReq->Header.PageType;
3711 		pData->RequestedParameters = cpu_to_le32(requested);
3712 		pData->Reserved = 0;
3713 		pData->Configuration = cpu_to_le32(configuration);
3714 
3715 		dprintk((MYIOC_s_INFO_FMT
3716 			"write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3717 				ioc->name, id, (id | (bus<<8)),
3718 				requested, configuration));
3719 
3720 		mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3721 	}
3722 
3723 	return 0;
3724 }
3725 
3726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3727 /*	mptscsih_writeIOCPage4  - write IOC Page 4
3728  *	@hd: Pointer to a SCSI Host Structure
3729  *	@target_id: write IOC Page4 for this ID & Bus
3730  *
3731  *	Return: -EAGAIN if unable to obtain a Message Frame
3732  *		or 0 if success.
3733  *
3734  *	Remark: We do not wait for a return, write pages sequentially.
3735  */
3736 static int
3737 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3738 {
3739 	MPT_ADAPTER		*ioc = hd->ioc;
3740 	Config_t		*pReq;
3741 	IOCPage4_t		*IOCPage4Ptr;
3742 	MPT_FRAME_HDR		*mf;
3743 	dma_addr_t		 dataDma;
3744 	u16			 req_idx;
3745 	u32			 frameOffset;
3746 	u32			 flagsLength;
3747 	int			 ii;
3748 
3749 	/* Get a MF for this command.
3750 	 */
3751 	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3752 		dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3753 					ioc->name));
3754 		return -EAGAIN;
3755 	}
3756 
3757 	/* Set the request and the data pointers.
3758 	 * Place data at end of MF.
3759 	 */
3760 	pReq = (Config_t *)mf;
3761 
3762 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3763 	frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3764 
3765 	/* Complete the request frame (same for all requests).
3766 	 */
3767 	pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3768 	pReq->Reserved = 0;
3769 	pReq->ChainOffset = 0;
3770 	pReq->Function = MPI_FUNCTION_CONFIG;
3771 	pReq->ExtPageLength = 0;
3772 	pReq->ExtPageType = 0;
3773 	pReq->MsgFlags = 0;
3774 	for (ii=0; ii < 8; ii++) {
3775 		pReq->Reserved2[ii] = 0;
3776 	}
3777 
3778        	IOCPage4Ptr = ioc->spi_data.pIocPg4;
3779        	dataDma = ioc->spi_data.IocPg4_dma;
3780        	ii = IOCPage4Ptr->ActiveSEP++;
3781        	IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3782        	IOCPage4Ptr->SEP[ii].SEPBus = bus;
3783        	pReq->Header = IOCPage4Ptr->Header;
3784 	pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3785 
3786 	/* Add a SGE to the config request.
3787 	 */
3788 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3789 		(IOCPage4Ptr->Header.PageLength + ii) * 4;
3790 
3791 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3792 
3793 	dinitprintk((MYIOC_s_INFO_FMT
3794 		"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3795 			ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3796 
3797 	mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3798 
3799 	return 0;
3800 }
3801 
3802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3803 /*
3804  *  Bus Scan and Domain Validation functionality ...
3805  */
3806 
3807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3808 /*
3809  *	mptscsih_scandv_complete - Scan and DV callback routine registered
3810  *	to Fustion MPT (base) driver.
3811  *
3812  *	@ioc: Pointer to MPT_ADAPTER structure
3813  *	@mf: Pointer to original MPT request frame
3814  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
3815  *
3816  *	This routine is called from mpt.c::mpt_interrupt() at the completion
3817  *	of any SCSI IO request.
3818  *	This routine is registered with the Fusion MPT (base) driver at driver
3819  *	load/init time via the mpt_register() API call.
3820  *
3821  *	Returns 1 indicating alloc'd request frame ptr should be freed.
3822  *
3823  *	Remark: Sets a completion code and (possibly) saves sense data
3824  *	in the IOC member localReply structure.
3825  *	Used ONLY for DV and other internal commands.
3826  */
3827 static int
3828 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3829 {
3830 	MPT_SCSI_HOST	*hd;
3831 	SCSIIORequest_t *pReq;
3832 	int		 completionCode;
3833 	u16		 req_idx;
3834 
3835 	if ((mf == NULL) ||
3836 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3837 		printk(MYIOC_s_ERR_FMT
3838 			"ScanDvComplete, %s req frame ptr! (=%p)\n",
3839 				ioc->name, mf?"BAD":"NULL", (void *) mf);
3840 		goto wakeup;
3841 	}
3842 
3843 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3844 	del_timer(&hd->timer);
3845 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3846 	hd->ScsiLookup[req_idx] = NULL;
3847 	pReq = (SCSIIORequest_t *) mf;
3848 
3849 	if (mf != hd->cmdPtr) {
3850 		printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3851 				hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3852 	}
3853 	hd->cmdPtr = NULL;
3854 
3855 	ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3856 			hd->ioc->name, mf, mr, req_idx));
3857 
3858 	hd->pLocal = &hd->localReply;
3859 	hd->pLocal->scsiStatus = 0;
3860 
3861 	/* If target struct exists, clear sense valid flag.
3862 	 */
3863 	if (mr == NULL) {
3864 		completionCode = MPT_SCANDV_GOOD;
3865 	} else {
3866 		SCSIIOReply_t	*pReply;
3867 		u16		 status;
3868 		u8		 scsi_status;
3869 
3870 		pReply = (SCSIIOReply_t *) mr;
3871 
3872 		status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3873 		scsi_status = pReply->SCSIStatus;
3874 
3875 		ddvtprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3876 			     status, pReply->SCSIState, scsi_status,
3877 			     le32_to_cpu(pReply->IOCLogInfo)));
3878 
3879 		switch(status) {
3880 
3881 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
3882 			completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3883 			break;
3884 
3885 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
3886 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
3887 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
3888 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
3889 			completionCode = MPT_SCANDV_DID_RESET;
3890 			break;
3891 
3892 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
3893 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
3894 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
3895 			if (pReply->Function == MPI_FUNCTION_CONFIG) {
3896 				ConfigReply_t *pr = (ConfigReply_t *)mr;
3897 				completionCode = MPT_SCANDV_GOOD;
3898 				hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3899 				hd->pLocal->header.PageLength = pr->Header.PageLength;
3900 				hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3901 				hd->pLocal->header.PageType = pr->Header.PageType;
3902 
3903 			} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3904 				/* If the RAID Volume request is successful,
3905 				 * return GOOD, else indicate that
3906 				 * some type of error occurred.
3907 				 */
3908 				MpiRaidActionReply_t	*pr = (MpiRaidActionReply_t *)mr;
3909 				if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3910 					completionCode = MPT_SCANDV_GOOD;
3911 				else
3912 					completionCode = MPT_SCANDV_SOME_ERROR;
3913 
3914 			} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3915 				u8		*sense_data;
3916 				int		 sz;
3917 
3918 				/* save sense data in global structure
3919 				 */
3920 				completionCode = MPT_SCANDV_SENSE;
3921 				hd->pLocal->scsiStatus = scsi_status;
3922 				sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3923 					(req_idx * MPT_SENSE_BUFFER_ALLOC));
3924 
3925 				sz = min_t(int, pReq->SenseBufferLength,
3926 							SCSI_STD_SENSE_BYTES);
3927 				memcpy(hd->pLocal->sense, sense_data, sz);
3928 
3929 				ddvprintk((KERN_NOTICE "  Check Condition, sense ptr %p\n",
3930 						sense_data));
3931 			} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3932 				if (pReq->CDB[0] == INQUIRY)
3933 					completionCode = MPT_SCANDV_ISSUE_SENSE;
3934 				else
3935 					completionCode = MPT_SCANDV_DID_RESET;
3936 			}
3937 			else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3938 				completionCode = MPT_SCANDV_DID_RESET;
3939 			else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3940 				completionCode = MPT_SCANDV_DID_RESET;
3941 			else {
3942 				completionCode = MPT_SCANDV_GOOD;
3943 				hd->pLocal->scsiStatus = scsi_status;
3944 			}
3945 			break;
3946 
3947 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
3948 			if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3949 				completionCode = MPT_SCANDV_DID_RESET;
3950 			else
3951 				completionCode = MPT_SCANDV_SOME_ERROR;
3952 			break;
3953 
3954 		default:
3955 			completionCode = MPT_SCANDV_SOME_ERROR;
3956 			break;
3957 
3958 		}	/* switch(status) */
3959 
3960 		ddvtprintk((KERN_NOTICE "  completionCode set to %08xh\n",
3961 				completionCode));
3962 	} /* end of address reply case */
3963 
3964 	hd->pLocal->completion = completionCode;
3965 
3966 	/* MF and RF are freed in mpt_interrupt
3967 	 */
3968 wakeup:
3969 	/* Free Chain buffers (will never chain) in scan or dv */
3970 	//mptscsih_freeChainBuffers(ioc, req_idx);
3971 
3972 	/*
3973 	 * Wake up the original calling thread
3974 	 */
3975 	scandv_wait_done = 1;
3976 	wake_up(&scandv_waitq);
3977 
3978 	return 1;
3979 }
3980 
3981 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3982 /*	mptscsih_timer_expired - Call back for timer process.
3983  *	Used only for dv functionality.
3984  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3985  *
3986  */
3987 static void mptscsih_timer_expired(unsigned long data)
3988 {
3989 	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3990 
3991 	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3992 
3993 	if (hd->cmdPtr) {
3994 		MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3995 
3996 		if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3997 			/* Desire to issue a task management request here.
3998 			 * TM requests MUST be single threaded.
3999 			 * If old eh code and no TM current, issue request.
4000 			 * If new eh code, do nothing. Wait for OS cmd timeout
4001 			 *	for bus reset.
4002 			 */
4003 			ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
4004 		} else {
4005 			/* Perform a FW reload */
4006 			if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
4007 				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
4008 			}
4009 		}
4010 	} else {
4011 		/* This should NEVER happen */
4012 		printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
4013 	}
4014 
4015 	/* No more processing.
4016 	 * TM call will generate an interrupt for SCSI TM Management.
4017 	 * The FW will reply to all outstanding commands, callback will finish cleanup.
4018 	 * Hard reset clean-up will free all resources.
4019 	 */
4020 	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
4021 
4022 	return;
4023 }
4024 
4025 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027 /*	mptscsih_do_raid - Format and Issue a RAID volume request message.
4028  *	@hd: Pointer to scsi host structure
4029  *	@action: What do be done.
4030  *	@id: Logical target id.
4031  *	@bus: Target locations bus.
4032  *
4033  *	Returns: < 0 on a fatal error
4034  *		0 on success
4035  *
4036  *	Remark: Wait to return until reply processed by the ISR.
4037  */
4038 static int
4039 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
4040 {
4041 	MpiRaidActionRequest_t	*pReq;
4042 	MPT_FRAME_HDR		*mf;
4043 	int			in_isr;
4044 
4045 	in_isr = in_interrupt();
4046 	if (in_isr) {
4047 		dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
4048        				hd->ioc->name));
4049 		return -EPERM;
4050 	}
4051 
4052 	/* Get and Populate a free Frame
4053 	 */
4054 	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4055 		ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
4056 					hd->ioc->name));
4057 		return -EAGAIN;
4058 	}
4059 	pReq = (MpiRaidActionRequest_t *)mf;
4060 	pReq->Action = action;
4061 	pReq->Reserved1 = 0;
4062 	pReq->ChainOffset = 0;
4063 	pReq->Function = MPI_FUNCTION_RAID_ACTION;
4064 	pReq->VolumeID = io->id;
4065 	pReq->VolumeBus = io->bus;
4066 	pReq->PhysDiskNum = io->physDiskNum;
4067 	pReq->MsgFlags = 0;
4068 	pReq->Reserved2 = 0;
4069 	pReq->ActionDataWord = 0; /* Reserved for this action */
4070 	//pReq->ActionDataSGE = 0;
4071 
4072 	mpt_add_sge((char *)&pReq->ActionDataSGE,
4073 		MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
4074 
4075 	ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
4076 			hd->ioc->name, action, io->id));
4077 
4078 	hd->pLocal = NULL;
4079 	hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
4080 	scandv_wait_done = 0;
4081 
4082 	/* Save cmd pointer, for resource free if timeout or
4083 	 * FW reload occurs
4084 	 */
4085 	hd->cmdPtr = mf;
4086 
4087 	add_timer(&hd->timer);
4088 	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4089 	wait_event(scandv_waitq, scandv_wait_done);
4090 
4091 	if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
4092 		return -1;
4093 
4094 	return 0;
4095 }
4096 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4097 
4098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4099 /**
4100  *	mptscsih_do_cmd - Do internal command.
4101  *	@hd: MPT_SCSI_HOST pointer
4102  *	@io: INTERNAL_CMD pointer.
4103  *
4104  *	Issue the specified internally generated command and do command
4105  *	specific cleanup. For bus scan / DV only.
4106  *	NOTES: If command is Inquiry and status is good,
4107  *	initialize a target structure, save the data
4108  *
4109  *	Remark: Single threaded access only.
4110  *
4111  *	Return:
4112  *		< 0 if an illegal command or no resources
4113  *
4114  *		   0 if good
4115  *
4116  *		 > 0 if command complete but some type of completion error.
4117  */
4118 static int
4119 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
4120 {
4121 	MPT_FRAME_HDR	*mf;
4122 	SCSIIORequest_t	*pScsiReq;
4123 	SCSIIORequest_t	 ReqCopy;
4124 	int		 my_idx, ii, dir;
4125 	int		 rc, cmdTimeout;
4126 	int		in_isr;
4127 	char		 cmdLen;
4128 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4129 	char		 cmd = io->cmd;
4130 
4131 	in_isr = in_interrupt();
4132 	if (in_isr) {
4133 		dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
4134        				hd->ioc->name));
4135 		return -EPERM;
4136 	}
4137 
4138 
4139 	/* Set command specific information
4140 	 */
4141 	switch (cmd) {
4142 	case INQUIRY:
4143 		cmdLen = 6;
4144 		dir = MPI_SCSIIO_CONTROL_READ;
4145 		CDB[0] = cmd;
4146 		CDB[4] = io->size;
4147 		cmdTimeout = 10;
4148 		break;
4149 
4150 	case TEST_UNIT_READY:
4151 		cmdLen = 6;
4152 		dir = MPI_SCSIIO_CONTROL_READ;
4153 		cmdTimeout = 10;
4154 		break;
4155 
4156 	case START_STOP:
4157 		cmdLen = 6;
4158 		dir = MPI_SCSIIO_CONTROL_READ;
4159 		CDB[0] = cmd;
4160 		CDB[4] = 1;	/*Spin up the disk */
4161 		cmdTimeout = 15;
4162 		break;
4163 
4164 	case REQUEST_SENSE:
4165 		cmdLen = 6;
4166 		CDB[0] = cmd;
4167 		CDB[4] = io->size;
4168 		dir = MPI_SCSIIO_CONTROL_READ;
4169 		cmdTimeout = 10;
4170 		break;
4171 
4172 	case READ_BUFFER:
4173 		cmdLen = 10;
4174 		dir = MPI_SCSIIO_CONTROL_READ;
4175 		CDB[0] = cmd;
4176 		if (io->flags & MPT_ICFLAG_ECHO) {
4177 			CDB[1] = 0x0A;
4178 		} else {
4179 			CDB[1] = 0x02;
4180 		}
4181 
4182 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
4183 			CDB[1] |= 0x01;
4184 		}
4185 		CDB[6] = (io->size >> 16) & 0xFF;
4186 		CDB[7] = (io->size >>  8) & 0xFF;
4187 		CDB[8] = io->size & 0xFF;
4188 		cmdTimeout = 10;
4189 		break;
4190 
4191 	case WRITE_BUFFER:
4192 		cmdLen = 10;
4193 		dir = MPI_SCSIIO_CONTROL_WRITE;
4194 		CDB[0] = cmd;
4195 		if (io->flags & MPT_ICFLAG_ECHO) {
4196 			CDB[1] = 0x0A;
4197 		} else {
4198 			CDB[1] = 0x02;
4199 		}
4200 		CDB[6] = (io->size >> 16) & 0xFF;
4201 		CDB[7] = (io->size >>  8) & 0xFF;
4202 		CDB[8] = io->size & 0xFF;
4203 		cmdTimeout = 10;
4204 		break;
4205 
4206 	case RESERVE:
4207 		cmdLen = 6;
4208 		dir = MPI_SCSIIO_CONTROL_READ;
4209 		CDB[0] = cmd;
4210 		cmdTimeout = 10;
4211 		break;
4212 
4213 	case RELEASE:
4214 		cmdLen = 6;
4215 		dir = MPI_SCSIIO_CONTROL_READ;
4216 		CDB[0] = cmd;
4217 		cmdTimeout = 10;
4218 		break;
4219 
4220 	case SYNCHRONIZE_CACHE:
4221 		cmdLen = 10;
4222 		dir = MPI_SCSIIO_CONTROL_READ;
4223 		CDB[0] = cmd;
4224 //		CDB[1] = 0x02;	/* set immediate bit */
4225 		cmdTimeout = 10;
4226 		break;
4227 
4228 	default:
4229 		/* Error Case */
4230 		return -EFAULT;
4231 	}
4232 
4233 	/* Get and Populate a free Frame
4234 	 */
4235 	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4236 		ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
4237 					hd->ioc->name));
4238 		return -EBUSY;
4239 	}
4240 
4241 	pScsiReq = (SCSIIORequest_t *) mf;
4242 
4243 	/* Get the request index */
4244 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4245 	ADD_INDEX_LOG(my_idx); /* for debug */
4246 
4247 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
4248 		pScsiReq->TargetID = io->physDiskNum;
4249 		pScsiReq->Bus = 0;
4250 		pScsiReq->ChainOffset = 0;
4251 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4252 	} else {
4253 		pScsiReq->TargetID = io->id;
4254 		pScsiReq->Bus = io->bus;
4255 		pScsiReq->ChainOffset = 0;
4256 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
4257 	}
4258 
4259 	pScsiReq->CDBLength = cmdLen;
4260 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
4261 
4262 	pScsiReq->Reserved = 0;
4263 
4264 	pScsiReq->MsgFlags = mpt_msg_flags();
4265 	/* MsgContext set in mpt_get_msg_fram call  */
4266 
4267 	for (ii=0; ii < 8; ii++)
4268 		pScsiReq->LUN[ii] = 0;
4269 	pScsiReq->LUN[1] = io->lun;
4270 
4271 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
4272 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
4273 	else
4274 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4275 
4276 	if (cmd == REQUEST_SENSE) {
4277 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4278 		ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
4279 			hd->ioc->name, cmd));
4280 	}
4281 
4282 	for (ii=0; ii < 16; ii++)
4283 		pScsiReq->CDB[ii] = CDB[ii];
4284 
4285 	pScsiReq->DataLength = cpu_to_le32(io->size);
4286 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
4287 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
4288 
4289 	ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
4290 			hd->ioc->name, cmd, io->bus, io->id, io->lun));
4291 
4292 	if (dir == MPI_SCSIIO_CONTROL_READ) {
4293 		mpt_add_sge((char *) &pScsiReq->SGL,
4294 			MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
4295 			io->data_dma);
4296 	} else {
4297 		mpt_add_sge((char *) &pScsiReq->SGL,
4298 			MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
4299 			io->data_dma);
4300 	}
4301 
4302 	/* The ISR will free the request frame, but we need
4303 	 * the information to initialize the target. Duplicate.
4304 	 */
4305 	memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
4306 
4307 	/* Issue this command after:
4308 	 *	finish init
4309 	 *	add timer
4310 	 * Wait until the reply has been received
4311 	 *  ScsiScanDvCtx callback function will
4312 	 *	set hd->pLocal;
4313 	 *	set scandv_wait_done and call wake_up
4314 	 */
4315 	hd->pLocal = NULL;
4316 	hd->timer.expires = jiffies + HZ*cmdTimeout;
4317 	scandv_wait_done = 0;
4318 
4319 	/* Save cmd pointer, for resource free if timeout or
4320 	 * FW reload occurs
4321 	 */
4322 	hd->cmdPtr = mf;
4323 
4324 	add_timer(&hd->timer);
4325 	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4326 	wait_event(scandv_waitq, scandv_wait_done);
4327 
4328 	if (hd->pLocal) {
4329 		rc = hd->pLocal->completion;
4330 		hd->pLocal->skip = 0;
4331 
4332 		/* Always set fatal error codes in some cases.
4333 		 */
4334 		if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
4335 			rc = -ENXIO;
4336 		else if (rc == MPT_SCANDV_SOME_ERROR)
4337 			rc =  -rc;
4338 	} else {
4339 		rc = -EFAULT;
4340 		/* This should never happen. */
4341 		ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
4342 				hd->ioc->name));
4343 	}
4344 
4345 	return rc;
4346 }
4347 
4348 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4349 /**
4350  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4351  *	@hd: Pointer to MPT_SCSI_HOST structure
4352  *	@portnum: IOC port number
4353  *
4354  *	Uses the ISR, but with special processing.
4355  *	MUST be single-threaded.
4356  *
4357  *	Return: 0 on completion
4358  */
4359 static int
4360 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4361 {
4362 	MPT_ADAPTER		*ioc= hd->ioc;
4363 	VirtDevice		*pTarget;
4364 	SCSIDevicePage1_t	*pcfg1Data = NULL;
4365 	INTERNAL_CMD		 iocmd;
4366 	CONFIGPARMS		 cfg;
4367 	dma_addr_t		 cfg1_dma_addr = -1;
4368 	ConfigPageHeader_t	 header1;
4369 	int			 bus = 0;
4370 	int			 id = 0;
4371 	int			 lun;
4372 	int			 indexed_lun, lun_index;
4373 	int			 hostId = ioc->pfacts[portnum].PortSCSIID;
4374 	int			 max_id;
4375 	int			 requested, configuration, data;
4376 	int			 doConfig = 0;
4377 	u8			 flags, factor;
4378 
4379 	max_id = ioc->sh->max_id - 1;
4380 
4381 	/* Following parameters will not change
4382 	 * in this routine.
4383 	 */
4384 	iocmd.cmd = SYNCHRONIZE_CACHE;
4385 	iocmd.flags = 0;
4386 	iocmd.physDiskNum = -1;
4387 	iocmd.data = NULL;
4388 	iocmd.data_dma = -1;
4389 	iocmd.size = 0;
4390 	iocmd.rsvd = iocmd.rsvd2 = 0;
4391 
4392 	/* No SCSI hosts
4393 	 */
4394 	if (hd->Targets == NULL)
4395 		return 0;
4396 
4397 	/* Skip the host
4398 	 */
4399 	if (id == hostId)
4400 		id++;
4401 
4402 	/* Write SDP1 for all SCSI devices
4403 	 * Alloc memory and set up config buffer
4404 	 */
4405 	if (ioc->bus_type == SCSI) {
4406 		if (ioc->spi_data.sdp1length > 0) {
4407 			pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
4408 					 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
4409 
4410 			if (pcfg1Data != NULL) {
4411 				doConfig = 1;
4412 				header1.PageVersion = ioc->spi_data.sdp1version;
4413 				header1.PageLength = ioc->spi_data.sdp1length;
4414 				header1.PageNumber = 1;
4415 				header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4416 				cfg.hdr = &header1;
4417 				cfg.physAddr = cfg1_dma_addr;
4418 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4419 				cfg.dir = 1;
4420 				cfg.timeout = 0;
4421 			}
4422 		}
4423 	}
4424 
4425 	/* loop through all devices on this port
4426 	 */
4427 	while (bus < MPT_MAX_BUS) {
4428 		iocmd.bus = bus;
4429 		iocmd.id = id;
4430 		pTarget = hd->Targets[(int)id];
4431 
4432 		if (doConfig) {
4433 
4434 			/* Set the negotiation flags */
4435 			if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4436 				flags = pTarget->negoFlags;
4437 			} else {
4438 				flags = hd->ioc->spi_data.noQas;
4439 				if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4440 					data = hd->ioc->spi_data.nvram[id];
4441 
4442 					if (data & MPT_NVRAM_WIDE_DISABLE)
4443 						flags |= MPT_TARGET_NO_NEGO_WIDE;
4444 
4445 					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4446 					if ((factor == 0) || (factor == MPT_ASYNC))
4447 						flags |= MPT_TARGET_NO_NEGO_SYNC;
4448 				}
4449 			}
4450 
4451 			/* Force to async, narrow */
4452 			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4453 					&configuration, flags);
4454 			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4455 				"offset=0 negoFlags=%x request=%x config=%x\n",
4456 				id, flags, requested, configuration));
4457 			pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4458 			pcfg1Data->Reserved = 0;
4459 			pcfg1Data->Configuration = le32_to_cpu(configuration);
4460 			cfg.pageAddr = (bus<<8) | id;
4461 			mpt_config(hd->ioc, &cfg);
4462 		}
4463 
4464 		/* If target Ptr NULL or if this target is NOT a disk, skip.
4465 		 */
4466 		if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4467 			for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4468 				/* If LUN present, issue the command
4469 				 */
4470 				lun_index = (lun >> 5);  /* 32 luns per lun_index */
4471 				indexed_lun = (lun % 32);
4472 				if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4473 					iocmd.lun = lun;
4474 					(void) mptscsih_do_cmd(hd, &iocmd);
4475 				}
4476 			}
4477 		}
4478 
4479 		/* get next relevant device */
4480 		id++;
4481 
4482 		if (id == hostId)
4483 			id++;
4484 
4485 		if (id > max_id) {
4486 			id = 0;
4487 			bus++;
4488 		}
4489 	}
4490 
4491 	if (pcfg1Data) {
4492 		pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4493 	}
4494 
4495 	return 0;
4496 }
4497 
4498 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4500 /**
4501  *	mptscsih_domainValidation - Top level handler for domain validation.
4502  *	@hd: Pointer to MPT_SCSI_HOST structure.
4503  *
4504  *	Uses the ISR, but with special processing.
4505  *	Called from schedule, should not be in interrupt mode.
4506  *	While thread alive, do dv for all devices needing dv
4507  *
4508  *	Return: None.
4509  */
4510 static void
4511 mptscsih_domainValidation(void *arg)
4512 {
4513 	MPT_SCSI_HOST		*hd;
4514 	MPT_ADAPTER		*ioc;
4515 	unsigned long		 flags;
4516 	int 			 id, maxid, dvStatus, did;
4517 	int			 ii, isPhysDisk;
4518 
4519 	spin_lock_irqsave(&dvtaskQ_lock, flags);
4520 	dvtaskQ_active = 1;
4521 	if (dvtaskQ_release) {
4522 		dvtaskQ_active = 0;
4523 		spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4524 		return;
4525 	}
4526 	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4527 
4528 	/* For this ioc, loop through all devices and do dv to each device.
4529 	 * When complete with this ioc, search through the ioc list, and
4530 	 * for each scsi ioc found, do dv for all devices. Exit when no
4531 	 * device needs dv.
4532 	 */
4533 	did = 1;
4534 	while (did) {
4535 		did = 0;
4536 		list_for_each_entry(ioc, &ioc_list, list) {
4537 			spin_lock_irqsave(&dvtaskQ_lock, flags);
4538 			if (dvtaskQ_release) {
4539 				dvtaskQ_active = 0;
4540 				spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4541 				return;
4542 			}
4543 			spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4544 
4545 			msleep(250);
4546 
4547 			/* DV only to SCSI adapters */
4548 			if (ioc->bus_type != SCSI)
4549 				continue;
4550 
4551 			/* Make sure everything looks ok */
4552 			if (ioc->sh == NULL)
4553 				continue;
4554 
4555 			hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4556 			if (hd == NULL)
4557 				continue;
4558 
4559 			if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4560 				mpt_read_ioc_pg_3(ioc);
4561 				if (ioc->spi_data.pIocPg3) {
4562 					Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4563 					int		numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4564 
4565 					while (numPDisk) {
4566 						if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4567 							ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4568 
4569 						pPDisk++;
4570 						numPDisk--;
4571 					}
4572 				}
4573 				ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4574 			}
4575 
4576 			maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4577 
4578 			for (id = 0; id < maxid; id++) {
4579 				spin_lock_irqsave(&dvtaskQ_lock, flags);
4580 				if (dvtaskQ_release) {
4581 					dvtaskQ_active = 0;
4582 					spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4583 					return;
4584 				}
4585 				spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4586 				dvStatus = hd->ioc->spi_data.dvStatus[id];
4587 
4588 				if (dvStatus & MPT_SCSICFG_NEED_DV) {
4589 					did++;
4590 					hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4591 					hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4592 
4593 					msleep(250);
4594 
4595 					/* If hidden phys disk, block IO's to all
4596 					 *	raid volumes
4597 					 * else, process normally
4598 					 */
4599 					isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4600 					if (isPhysDisk) {
4601 						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4602 							if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4603 								hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4604 							}
4605 						}
4606 					}
4607 
4608 					if (mptscsih_doDv(hd, 0, id) == 1) {
4609 						/* Untagged device was busy, try again
4610 						 */
4611 						hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4612 						hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4613 					} else {
4614 						/* DV is complete. Clear flags.
4615 						 */
4616 						hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4617 					}
4618 
4619 					if (isPhysDisk) {
4620 						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4621 							if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4622 								hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4623 							}
4624 						}
4625 					}
4626 
4627 					if (hd->ioc->spi_data.noQas)
4628 						mptscsih_qas_check(hd, id);
4629 				}
4630 			}
4631 		}
4632 	}
4633 
4634 	spin_lock_irqsave(&dvtaskQ_lock, flags);
4635 	dvtaskQ_active = 0;
4636 	spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4637 
4638 	return;
4639 }
4640 
4641 /* Search IOC page 3 to determine if this is hidden physical disk
4642  */
4643 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4644 {
4645 	if (ioc->spi_data.pIocPg3) {
4646 		Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
4647 		int		numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4648 
4649 		while (numPDisk) {
4650 			if (pPDisk->PhysDiskID == id) {
4651 				return 1;
4652 			}
4653 			pPDisk++;
4654 			numPDisk--;
4655 		}
4656 	}
4657 	return 0;
4658 }
4659 
4660 /* Write SDP1 if no QAS has been enabled
4661  */
4662 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4663 {
4664 	VirtDevice *pTarget;
4665 	int ii;
4666 
4667 	if (hd->Targets == NULL)
4668 		return;
4669 
4670 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4671 		if (ii == id)
4672 			continue;
4673 
4674 		if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4675 			continue;
4676 
4677 		pTarget = hd->Targets[ii];
4678 
4679 		if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4680 			if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4681 				pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4682 				dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4683 				mptscsih_writeSDP1(hd, 0, ii, 0);
4684 			}
4685 		} else {
4686 			if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4687 				dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4688 				mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4689 			}
4690 		}
4691 	}
4692 	return;
4693 }
4694 
4695 
4696 
4697 #define MPT_GET_NVRAM_VALS	0x01
4698 #define MPT_UPDATE_MAX		0x02
4699 #define MPT_SET_MAX		0x04
4700 #define MPT_SET_MIN		0x08
4701 #define MPT_FALLBACK		0x10
4702 #define MPT_SAVE		0x20
4703 
4704 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4705 /**
4706  *	mptscsih_doDv - Perform domain validation to a target.
4707  *	@hd: Pointer to MPT_SCSI_HOST structure.
4708  *	@portnum: IOC port number.
4709  *	@target: Physical ID of this target
4710  *
4711  *	Uses the ISR, but with special processing.
4712  *	MUST be single-threaded.
4713  *	Test will exit if target is at async & narrow.
4714  *
4715  *	Return: None.
4716  */
4717 static int
4718 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4719 {
4720 	MPT_ADAPTER		*ioc = hd->ioc;
4721 	VirtDevice		*pTarget;
4722 	SCSIDevicePage1_t	*pcfg1Data;
4723 	SCSIDevicePage0_t	*pcfg0Data;
4724 	u8			*pbuf1;
4725 	u8			*pbuf2;
4726 	u8			*pDvBuf;
4727 	dma_addr_t		 dvbuf_dma = -1;
4728 	dma_addr_t		 buf1_dma = -1;
4729 	dma_addr_t		 buf2_dma = -1;
4730 	dma_addr_t		 cfg1_dma_addr = -1;
4731 	dma_addr_t		 cfg0_dma_addr = -1;
4732 	ConfigPageHeader_t	 header1;
4733 	ConfigPageHeader_t	 header0;
4734 	DVPARAMETERS		 dv;
4735 	INTERNAL_CMD		 iocmd;
4736 	CONFIGPARMS		 cfg;
4737 	int			 dv_alloc = 0;
4738 	int			 rc, sz = 0;
4739 	int			 bufsize = 0;
4740 	int			 dataBufSize = 0;
4741 	int			 echoBufSize = 0;
4742 	int			 notDone;
4743 	int			 patt;
4744 	int			 repeat;
4745 	int			 retcode = 0;
4746 	int			 nfactor =  MPT_ULTRA320;
4747 	char			 firstPass = 1;
4748 	char			 doFallback = 0;
4749 	char			 readPage0;
4750 	char			 bus, lun;
4751 	char			 inq0 = 0;
4752 
4753 	if (ioc->spi_data.sdp1length == 0)
4754 		return 0;
4755 
4756 	if (ioc->spi_data.sdp0length == 0)
4757 		return 0;
4758 
4759 	/* If multiple buses are used, require that the initiator
4760 	 * id be the same on all buses.
4761 	 */
4762 	if (id == ioc->pfacts[0].PortSCSIID)
4763 		return 0;
4764 
4765 	lun = 0;
4766 	bus = (u8) bus_number;
4767 	ddvtprintk((MYIOC_s_NOTE_FMT
4768 			"DV started: bus=%d, id=%d dv @ %p\n",
4769 			ioc->name, bus, id, &dv));
4770 
4771 	/* Prep DV structure
4772 	 */
4773 	memset (&dv, 0, sizeof(DVPARAMETERS));
4774 	dv.id = id;
4775 
4776 	/* Populate tmax with the current maximum
4777 	 * transfer parameters for this target.
4778 	 * Exit if narrow and async.
4779 	 */
4780 	dv.cmd = MPT_GET_NVRAM_VALS;
4781 	mptscsih_dv_parms(hd, &dv, NULL);
4782 
4783 	/* Prep SCSI IO structure
4784 	 */
4785 	iocmd.id = id;
4786 	iocmd.bus = bus;
4787 	iocmd.lun = lun;
4788 	iocmd.flags = 0;
4789 	iocmd.physDiskNum = -1;
4790 	iocmd.rsvd = iocmd.rsvd2 = 0;
4791 
4792 	pTarget = hd->Targets[id];
4793 
4794 	/* Use tagged commands if possible.
4795 	 */
4796 	if (pTarget) {
4797 		if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4798 			iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4799 		else {
4800 			if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4801 				return 0;
4802 
4803 			if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4804 				(hd->ioc->facts.FWVersion.Word < 0x01010B00))
4805 				return 0;
4806 		}
4807 	}
4808 
4809 	/* Prep cfg structure
4810 	 */
4811 	cfg.pageAddr = (bus<<8) | id;
4812 	cfg.hdr = NULL;
4813 
4814 	/* Prep SDP0 header
4815 	 */
4816 	header0.PageVersion = ioc->spi_data.sdp0version;
4817 	header0.PageLength = ioc->spi_data.sdp0length;
4818 	header0.PageNumber = 0;
4819 	header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4820 
4821 	/* Prep SDP1 header
4822 	 */
4823 	header1.PageVersion = ioc->spi_data.sdp1version;
4824 	header1.PageLength = ioc->spi_data.sdp1length;
4825 	header1.PageNumber = 1;
4826 	header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4827 
4828 	if (header0.PageLength & 1)
4829 		dv_alloc = (header0.PageLength * 4) + 4;
4830 
4831 	dv_alloc +=  (2048 + (header1.PageLength * 4));
4832 
4833 	pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4834 	if (pDvBuf == NULL)
4835 		return 0;
4836 
4837 	sz = 0;
4838 	pbuf1 = (u8 *)pDvBuf;
4839 	buf1_dma = dvbuf_dma;
4840 	sz +=1024;
4841 
4842 	pbuf2 = (u8 *) (pDvBuf + sz);
4843 	buf2_dma = dvbuf_dma + sz;
4844 	sz +=1024;
4845 
4846 	pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4847 	cfg0_dma_addr = dvbuf_dma + sz;
4848 	sz += header0.PageLength * 4;
4849 
4850 	/* 8-byte alignment
4851 	 */
4852 	if (header0.PageLength & 1)
4853 		sz += 4;
4854 
4855 	pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4856 	cfg1_dma_addr = dvbuf_dma + sz;
4857 
4858 	/* Skip this ID? Set cfg.hdr to force config page write
4859 	 */
4860 	{
4861 		ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4862 		if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4863 			/* Set the factor from nvram */
4864 			nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4865 			if (nfactor < pspi_data->minSyncFactor )
4866 				nfactor = pspi_data->minSyncFactor;
4867 
4868 			if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4869 				(pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4870 
4871 				ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4872 					ioc->name, bus, id, lun));
4873 
4874 				dv.cmd = MPT_SET_MAX;
4875 				mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4876 				cfg.hdr = &header1;
4877 
4878 				/* Save the final negotiated settings to
4879 				 * SCSI device page 1.
4880 				 */
4881 				cfg.physAddr = cfg1_dma_addr;
4882 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4883 				cfg.dir = 1;
4884 				mpt_config(hd->ioc, &cfg);
4885 				goto target_done;
4886 			}
4887 		}
4888 	}
4889 
4890 	/* Finish iocmd inititialization - hidden or visible disk? */
4891 	if (ioc->spi_data.pIocPg3) {
4892 		/* Search IOC page 3 for matching id
4893 		 */
4894 		Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
4895 		int		numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4896 
4897 		while (numPDisk) {
4898 			if (pPDisk->PhysDiskID == id) {
4899 				/* match */
4900 				iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4901 				iocmd.physDiskNum = pPDisk->PhysDiskNum;
4902 
4903 				/* Quiesce the IM
4904 				 */
4905 				if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4906 					ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4907 					goto target_done;
4908 				}
4909 				break;
4910 			}
4911 			pPDisk++;
4912 			numPDisk--;
4913 		}
4914 	}
4915 
4916 	/* RAID Volume ID's may double for a physical device. If RAID but
4917 	 * not a physical ID as well, skip DV.
4918 	 */
4919 	if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4920 		goto target_done;
4921 
4922 
4923 	/* Basic Test.
4924 	 * Async & Narrow - Inquiry
4925 	 * Async & Narrow - Inquiry
4926 	 * Maximum transfer rate - Inquiry
4927 	 * Compare buffers:
4928 	 *	If compare, test complete.
4929 	 *	If miscompare and first pass, repeat
4930 	 *	If miscompare and not first pass, fall back and repeat
4931 	 */
4932 	hd->pLocal = NULL;
4933 	readPage0 = 0;
4934 	sz = SCSI_MAX_INQUIRY_BYTES;
4935 	rc = MPT_SCANDV_GOOD;
4936 	while (1) {
4937 		ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4938 		retcode = 0;
4939 		dv.cmd = MPT_SET_MIN;
4940 		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4941 
4942 		cfg.hdr = &header1;
4943 		cfg.physAddr = cfg1_dma_addr;
4944 		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4945 		cfg.dir = 1;
4946 		if (mpt_config(hd->ioc, &cfg) != 0)
4947 			goto target_done;
4948 
4949 		/* Wide - narrow - wide workaround case
4950 		 */
4951 		if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4952 			/* Send an untagged command to reset disk Qs corrupted
4953 			 * when a parity error occurs on a Request Sense.
4954 			 */
4955 			if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4956 				((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4957 				(hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4958 
4959 				iocmd.cmd = REQUEST_SENSE;
4960 				iocmd.data_dma = buf1_dma;
4961 				iocmd.data = pbuf1;
4962 				iocmd.size = 0x12;
4963 				if (mptscsih_do_cmd(hd, &iocmd) < 0)
4964 					goto target_done;
4965 				else {
4966 					if (hd->pLocal == NULL)
4967 						goto target_done;
4968 					rc = hd->pLocal->completion;
4969 					if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4970 						dv.max.width = 0;
4971 						doFallback = 0;
4972 					} else
4973 						goto target_done;
4974 				}
4975 			} else
4976 				goto target_done;
4977 		}
4978 
4979 		iocmd.cmd = INQUIRY;
4980 		iocmd.data_dma = buf1_dma;
4981 		iocmd.data = pbuf1;
4982 		iocmd.size = sz;
4983 		memset(pbuf1, 0x00, sz);
4984 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
4985 			goto target_done;
4986 		else {
4987 			if (hd->pLocal == NULL)
4988 				goto target_done;
4989 			rc = hd->pLocal->completion;
4990 			if (rc == MPT_SCANDV_GOOD) {
4991 				if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4992 					if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4993 						retcode = 1;
4994 					else
4995 						retcode = 0;
4996 
4997 					goto target_done;
4998 				}
4999 			} else if  (rc == MPT_SCANDV_SENSE) {
5000 				;
5001 			} else {
5002 				/* If first command doesn't complete
5003 				 * with a good status or with a check condition,
5004 				 * exit.
5005 				 */
5006 				goto target_done;
5007 			}
5008 		}
5009 
5010 		/* Reset the size for disks
5011 		 */
5012 		inq0 = (*pbuf1) & 0x1F;
5013 		if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
5014 			sz = 0x40;
5015 			iocmd.size = sz;
5016 		}
5017 
5018 		/* Another GEM workaround. Check peripheral device type,
5019 		 * if PROCESSOR, quit DV.
5020 		 */
5021 		if (inq0 == TYPE_PROCESSOR) {
5022 			mptscsih_initTarget(hd,
5023 				bus,
5024 				id,
5025 				lun,
5026 				pbuf1,
5027 				sz);
5028 			goto target_done;
5029 		}
5030 
5031 		if (inq0 > 0x08)
5032 			goto target_done;
5033 
5034 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5035 			goto target_done;
5036 
5037 		if (sz == 0x40) {
5038 			if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
5039 				&& (pTarget->minSyncFactor > 0x09)) {
5040 				if ((pbuf1[56] & 0x04) == 0)
5041 					;
5042 				else if ((pbuf1[56] & 0x01) == 1) {
5043 					pTarget->minSyncFactor =
5044 					    nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
5045 				} else {
5046 					pTarget->minSyncFactor =
5047 					    nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
5048 				}
5049 
5050 				dv.max.factor = pTarget->minSyncFactor;
5051 
5052 				if ((pbuf1[56] & 0x02) == 0) {
5053 					pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
5054 					hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5055 					ddvprintk((MYIOC_s_NOTE_FMT
5056 					    "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5057 					    ioc->name, id, pbuf1[56]));
5058 				}
5059 			}
5060 		}
5061 
5062 		if (doFallback)
5063 			dv.cmd = MPT_FALLBACK;
5064 		else
5065 			dv.cmd = MPT_SET_MAX;
5066 
5067 		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5068 		if (mpt_config(hd->ioc, &cfg) != 0)
5069 			goto target_done;
5070 
5071 		if ((!dv.now.width) && (!dv.now.offset))
5072 			goto target_done;
5073 
5074 		iocmd.cmd = INQUIRY;
5075 		iocmd.data_dma = buf2_dma;
5076 		iocmd.data = pbuf2;
5077 		iocmd.size = sz;
5078 		memset(pbuf2, 0x00, sz);
5079 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5080 			goto target_done;
5081 		else if (hd->pLocal == NULL)
5082 			goto target_done;
5083 		else {
5084 			/* Save the return code.
5085 			 * If this is the first pass,
5086 			 * read SCSI Device Page 0
5087 			 * and update the target max parameters.
5088 			 */
5089 			rc = hd->pLocal->completion;
5090 			doFallback = 0;
5091 			if (rc == MPT_SCANDV_GOOD) {
5092 				if (!readPage0) {
5093 					u32 sdp0_info;
5094 					u32 sdp0_nego;
5095 
5096 					cfg.hdr = &header0;
5097 					cfg.physAddr = cfg0_dma_addr;
5098 					cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5099 					cfg.dir = 0;
5100 
5101 					if (mpt_config(hd->ioc, &cfg) != 0)
5102 						goto target_done;
5103 
5104 					sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
5105 					sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
5106 
5107 					/* Quantum and Fujitsu workarounds.
5108 					 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5109 					 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5110 					 * Resetart with a request for U160.
5111 					 */
5112 					if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
5113 							doFallback = 1;
5114 					} else {
5115 						dv.cmd = MPT_UPDATE_MAX;
5116 						mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
5117 						/* Update the SCSI device page 1 area
5118 						 */
5119 						pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
5120 						readPage0 = 1;
5121 					}
5122 				}
5123 
5124 				/* Quantum workaround. Restart this test will the fallback
5125 				 * flag set.
5126 				 */
5127 				if (doFallback == 0) {
5128 					if (memcmp(pbuf1, pbuf2, sz) != 0) {
5129 						if (!firstPass)
5130 							doFallback = 1;
5131 					} else {
5132 						ddvprintk((MYIOC_s_NOTE_FMT
5133 						    "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
5134 						hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
5135 						mptscsih_initTarget(hd,
5136 							bus,
5137 							id,
5138 							lun,
5139 							pbuf1,
5140 							sz);
5141 						break;	/* test complete */
5142 					}
5143 				}
5144 
5145 
5146 			} else if (rc == MPT_SCANDV_ISSUE_SENSE)
5147 				doFallback = 1;	/* set fallback flag */
5148 			else if ((rc == MPT_SCANDV_DID_RESET) ||
5149 				 (rc == MPT_SCANDV_SENSE) ||
5150 				 (rc == MPT_SCANDV_FALLBACK))
5151 				doFallback = 1;	/* set fallback flag */
5152 			else
5153 				goto target_done;
5154 
5155 			firstPass = 0;
5156 		}
5157 	}
5158 	ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
5159 
5160 	if (mpt_dv == 0)
5161 		goto target_done;
5162 
5163 	inq0 = (*pbuf1) & 0x1F;
5164 
5165 	/* Continue only for disks
5166 	 */
5167 	if (inq0 != 0)
5168 		goto target_done;
5169 
5170 	if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
5171 		goto target_done;
5172 
5173 	/* Start the Enhanced Test.
5174 	 * 0) issue TUR to clear out check conditions
5175 	 * 1) read capacity of echo (regular) buffer
5176 	 * 2) reserve device
5177 	 * 3) do write-read-compare data pattern test
5178 	 * 4) release
5179 	 * 5) update nego parms to target struct
5180 	 */
5181 	cfg.hdr = &header1;
5182 	cfg.physAddr = cfg1_dma_addr;
5183 	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5184 	cfg.dir = 1;
5185 
5186 	iocmd.cmd = TEST_UNIT_READY;
5187 	iocmd.data_dma = -1;
5188 	iocmd.data = NULL;
5189 	iocmd.size = 0;
5190 	notDone = 1;
5191 	while (notDone) {
5192 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5193 			goto target_done;
5194 
5195 		if (hd->pLocal == NULL)
5196 			goto target_done;
5197 
5198 		rc = hd->pLocal->completion;
5199 		if (rc == MPT_SCANDV_GOOD)
5200 			notDone = 0;
5201 		else if (rc == MPT_SCANDV_SENSE) {
5202 			u8 skey = hd->pLocal->sense[2] & 0x0F;
5203 			u8 asc = hd->pLocal->sense[12];
5204 			u8 ascq = hd->pLocal->sense[13];
5205 			ddvprintk((MYIOC_s_INFO_FMT
5206 				"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5207 				ioc->name, skey, asc, ascq));
5208 
5209 			if (skey == UNIT_ATTENTION)
5210 				notDone++; /* repeat */
5211 			else if ((skey == NOT_READY) &&
5212 					(asc == 0x04)&&(ascq == 0x01)) {
5213 				/* wait then repeat */
5214 				mdelay (2000);
5215 				notDone++;
5216 			} else if ((skey == NOT_READY) && (asc == 0x3A)) {
5217 				/* no medium, try read test anyway */
5218 				notDone = 0;
5219 			} else {
5220 				/* All other errors are fatal.
5221 				 */
5222 				ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5223 						ioc->name));
5224 				goto target_done;
5225 			}
5226 		} else
5227 			goto target_done;
5228 	}
5229 
5230 	iocmd.cmd = READ_BUFFER;
5231 	iocmd.data_dma = buf1_dma;
5232 	iocmd.data = pbuf1;
5233 	iocmd.size = 4;
5234 	iocmd.flags |= MPT_ICFLAG_BUF_CAP;
5235 
5236 	dataBufSize = 0;
5237 	echoBufSize = 0;
5238 	for (patt = 0; patt < 2; patt++) {
5239 		if (patt == 0)
5240 			iocmd.flags |= MPT_ICFLAG_ECHO;
5241 		else
5242 			iocmd.flags &= ~MPT_ICFLAG_ECHO;
5243 
5244 		notDone = 1;
5245 		while (notDone) {
5246 			bufsize = 0;
5247 
5248 			/* If not ready after 8 trials,
5249 			 * give up on this device.
5250 			 */
5251 			if (notDone > 8)
5252 				goto target_done;
5253 
5254 			if (mptscsih_do_cmd(hd, &iocmd) < 0)
5255 				goto target_done;
5256 			else if (hd->pLocal == NULL)
5257 				goto target_done;
5258 			else {
5259 				rc = hd->pLocal->completion;
5260 				ddvprintk(("ReadBuffer Comp Code %d", rc));
5261 				ddvprintk(("  buff: %0x %0x %0x %0x\n",
5262 					pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
5263 
5264 				if (rc == MPT_SCANDV_GOOD) {
5265 					notDone = 0;
5266 					if (iocmd.flags & MPT_ICFLAG_ECHO) {
5267 						bufsize =  ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
5268 					} else {
5269 						bufsize =  pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
5270 					}
5271 				} else if (rc == MPT_SCANDV_SENSE) {
5272 					u8 skey = hd->pLocal->sense[2] & 0x0F;
5273 					u8 asc = hd->pLocal->sense[12];
5274 					u8 ascq = hd->pLocal->sense[13];
5275 					ddvprintk((MYIOC_s_INFO_FMT
5276 						"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5277 						ioc->name, skey, asc, ascq));
5278 					if (skey == ILLEGAL_REQUEST) {
5279 						notDone = 0;
5280 					} else if (skey == UNIT_ATTENTION) {
5281 						notDone++; /* repeat */
5282 					} else if ((skey == NOT_READY) &&
5283 						(asc == 0x04)&&(ascq == 0x01)) {
5284 						/* wait then repeat */
5285 						mdelay (2000);
5286 						notDone++;
5287 					} else {
5288 						/* All other errors are fatal.
5289 						 */
5290 						ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5291 							ioc->name));
5292 						goto target_done;
5293 					}
5294 				} else {
5295 					/* All other errors are fatal
5296 					 */
5297 					goto target_done;
5298 				}
5299 			}
5300 		}
5301 
5302 		if (iocmd.flags & MPT_ICFLAG_ECHO)
5303 			echoBufSize = bufsize;
5304 		else
5305 			dataBufSize = bufsize;
5306 	}
5307 	sz = 0;
5308 	iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
5309 
5310 	/* Use echo buffers if possible,
5311 	 * Exit if both buffers are 0.
5312 	 */
5313 	if (echoBufSize > 0) {
5314 		iocmd.flags |= MPT_ICFLAG_ECHO;
5315 		if (dataBufSize > 0)
5316 			bufsize = min(echoBufSize, dataBufSize);
5317 		else
5318 			bufsize = echoBufSize;
5319 	} else if (dataBufSize == 0)
5320 		goto target_done;
5321 
5322 	ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
5323 		(iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
5324 
5325 	/* Data buffers for write-read-compare test max 1K.
5326 	 */
5327 	sz = min(bufsize, 1024);
5328 
5329 	/* --- loop ----
5330 	 * On first pass, always issue a reserve.
5331 	 * On additional loops, only if a reset has occurred.
5332 	 * iocmd.flags indicates if echo or regular buffer
5333 	 */
5334 	for (patt = 0; patt < 4; patt++) {
5335 		ddvprintk(("Pattern %d\n", patt));
5336 		if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
5337 			iocmd.cmd = TEST_UNIT_READY;
5338 			iocmd.data_dma = -1;
5339 			iocmd.data = NULL;
5340 			iocmd.size = 0;
5341 			if (mptscsih_do_cmd(hd, &iocmd) < 0)
5342 				goto target_done;
5343 
5344 			iocmd.cmd = RELEASE;
5345 			iocmd.data_dma = -1;
5346 			iocmd.data = NULL;
5347 			iocmd.size = 0;
5348 			if (mptscsih_do_cmd(hd, &iocmd) < 0)
5349 				goto target_done;
5350 			else if (hd->pLocal == NULL)
5351 				goto target_done;
5352 			else {
5353 				rc = hd->pLocal->completion;
5354 				ddvprintk(("Release rc %d\n", rc));
5355 				if (rc == MPT_SCANDV_GOOD)
5356 					iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5357 				else
5358 					goto target_done;
5359 			}
5360 			iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5361 		}
5362 		iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
5363 
5364 		repeat = 5;
5365 		while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
5366 			iocmd.cmd = RESERVE;
5367 			iocmd.data_dma = -1;
5368 			iocmd.data = NULL;
5369 			iocmd.size = 0;
5370 			if (mptscsih_do_cmd(hd, &iocmd) < 0)
5371 				goto target_done;
5372 			else if (hd->pLocal == NULL)
5373 				goto target_done;
5374 			else {
5375 				rc = hd->pLocal->completion;
5376 				if (rc == MPT_SCANDV_GOOD) {
5377 					iocmd.flags |= MPT_ICFLAG_RESERVED;
5378 				} else if (rc == MPT_SCANDV_SENSE) {
5379 					/* Wait if coming ready
5380 					 */
5381 					u8 skey = hd->pLocal->sense[2] & 0x0F;
5382 					u8 asc = hd->pLocal->sense[12];
5383 					u8 ascq = hd->pLocal->sense[13];
5384 					ddvprintk((MYIOC_s_INFO_FMT
5385 						"DV: Reserve Failed: ", ioc->name));
5386 					ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5387 							skey, asc, ascq));
5388 
5389 					if ((skey == NOT_READY) && (asc == 0x04)&&
5390 									(ascq == 0x01)) {
5391 						/* wait then repeat */
5392 						mdelay (2000);
5393 						notDone++;
5394 					} else {
5395 						ddvprintk((MYIOC_s_INFO_FMT
5396 							"DV: Reserved Failed.", ioc->name));
5397 						goto target_done;
5398 					}
5399 				} else {
5400 					ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
5401 							 ioc->name));
5402 					goto target_done;
5403 				}
5404 			}
5405 		}
5406 
5407 		mptscsih_fillbuf(pbuf1, sz, patt, 1);
5408 		iocmd.cmd = WRITE_BUFFER;
5409 		iocmd.data_dma = buf1_dma;
5410 		iocmd.data = pbuf1;
5411 		iocmd.size = sz;
5412 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5413 			goto target_done;
5414 		else if (hd->pLocal == NULL)
5415 			goto target_done;
5416 		else {
5417 			rc = hd->pLocal->completion;
5418 			if (rc == MPT_SCANDV_GOOD)
5419 				;		/* Issue read buffer */
5420 			else if (rc == MPT_SCANDV_DID_RESET) {
5421 				/* If using echo buffers, reset to data buffers.
5422 				 * Else do Fallback and restart
5423 				 * this test (re-issue reserve
5424 				 * because of bus reset).
5425 				 */
5426 				if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
5427 					iocmd.flags &= ~MPT_ICFLAG_ECHO;
5428 				} else {
5429 					dv.cmd = MPT_FALLBACK;
5430 					mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5431 
5432 					if (mpt_config(hd->ioc, &cfg) != 0)
5433 						goto target_done;
5434 
5435 					if ((!dv.now.width) && (!dv.now.offset))
5436 						goto target_done;
5437 				}
5438 
5439 				iocmd.flags |= MPT_ICFLAG_DID_RESET;
5440 				patt = -1;
5441 				continue;
5442 			} else if (rc == MPT_SCANDV_SENSE) {
5443 				/* Restart data test if UA, else quit.
5444 				 */
5445 				u8 skey = hd->pLocal->sense[2] & 0x0F;
5446 				ddvprintk((MYIOC_s_INFO_FMT
5447 					"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5448 					hd->pLocal->sense[12], hd->pLocal->sense[13]));
5449 				if (skey == UNIT_ATTENTION) {
5450 					patt = -1;
5451 					continue;
5452 				} else if (skey == ILLEGAL_REQUEST) {
5453 					if (iocmd.flags & MPT_ICFLAG_ECHO) {
5454 						if (dataBufSize >= bufsize) {
5455 							iocmd.flags &= ~MPT_ICFLAG_ECHO;
5456 							patt = -1;
5457 							continue;
5458 						}
5459 					}
5460 					goto target_done;
5461 				}
5462 				else
5463 					goto target_done;
5464 			} else {
5465 				/* fatal error */
5466 				goto target_done;
5467 			}
5468 		}
5469 
5470 		iocmd.cmd = READ_BUFFER;
5471 		iocmd.data_dma = buf2_dma;
5472 		iocmd.data = pbuf2;
5473 		iocmd.size = sz;
5474 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5475 			goto target_done;
5476 		else if (hd->pLocal == NULL)
5477 			goto target_done;
5478 		else {
5479 			rc = hd->pLocal->completion;
5480 			if (rc == MPT_SCANDV_GOOD) {
5481 				 /* If buffers compare,
5482 				  * go to next pattern,
5483 				  * else, do a fallback and restart
5484 				  * data transfer test.
5485 				  */
5486 				if (memcmp (pbuf1, pbuf2, sz) == 0) {
5487 					; /* goto next pattern */
5488 				} else {
5489 					/* Miscompare with Echo buffer, go to data buffer,
5490 					 * if that buffer exists.
5491 					 * Miscompare with Data buffer, check first 4 bytes,
5492 					 * some devices return capacity. Exit in this case.
5493 					 */
5494 					if (iocmd.flags & MPT_ICFLAG_ECHO) {
5495 						if (dataBufSize >= bufsize)
5496 							iocmd.flags &= ~MPT_ICFLAG_ECHO;
5497 						else
5498 							goto target_done;
5499 					} else {
5500 						if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5501 							/* Argh. Device returning wrong data.
5502 							 * Quit DV for this device.
5503 							 */
5504 							goto target_done;
5505 						}
5506 
5507 						/* Had an actual miscompare. Slow down.*/
5508 						dv.cmd = MPT_FALLBACK;
5509 						mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5510 
5511 						if (mpt_config(hd->ioc, &cfg) != 0)
5512 							goto target_done;
5513 
5514 						if ((!dv.now.width) && (!dv.now.offset))
5515 							goto target_done;
5516 					}
5517 
5518 					patt = -1;
5519 					continue;
5520 				}
5521 			} else if (rc == MPT_SCANDV_DID_RESET) {
5522 				/* Do Fallback and restart
5523 				 * this test (re-issue reserve
5524 				 * because of bus reset).
5525 				 */
5526 				dv.cmd = MPT_FALLBACK;
5527 				mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5528 
5529 				if (mpt_config(hd->ioc, &cfg) != 0)
5530 					 goto target_done;
5531 
5532 				if ((!dv.now.width) && (!dv.now.offset))
5533 					goto target_done;
5534 
5535 				iocmd.flags |= MPT_ICFLAG_DID_RESET;
5536 				patt = -1;
5537 				continue;
5538 			} else if (rc == MPT_SCANDV_SENSE) {
5539 				/* Restart data test if UA, else quit.
5540 				 */
5541 				u8 skey = hd->pLocal->sense[2] & 0x0F;
5542 				ddvprintk((MYIOC_s_INFO_FMT
5543 					"SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5544 					hd->pLocal->sense[12], hd->pLocal->sense[13]));
5545 				if (skey == UNIT_ATTENTION) {
5546 					patt = -1;
5547 					continue;
5548 				}
5549 				else
5550 					goto target_done;
5551 			} else {
5552 				/* fatal error */
5553 				goto target_done;
5554 			}
5555 		}
5556 
5557 	} /* --- end of patt loop ---- */
5558 
5559 target_done:
5560 	if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5561 		iocmd.cmd = RELEASE;
5562 		iocmd.data_dma = -1;
5563 		iocmd.data = NULL;
5564 		iocmd.size = 0;
5565 		if (mptscsih_do_cmd(hd, &iocmd) < 0)
5566 			printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5567 					ioc->name, id);
5568 		else if (hd->pLocal) {
5569 			if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5570 				iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5571 		} else {
5572 			printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5573 						ioc->name, id);
5574 		}
5575 	}
5576 
5577 
5578 	/* Set if cfg1_dma_addr contents is valid
5579 	 */
5580 	if ((cfg.hdr != NULL) && (retcode == 0)){
5581 		/* If disk, not U320, disable QAS
5582 		 */
5583 		if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5584 			hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5585 			ddvprintk((MYIOC_s_NOTE_FMT
5586 			    "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5587 		}
5588 
5589 		dv.cmd = MPT_SAVE;
5590 		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5591 
5592 		/* Double writes to SDP1 can cause problems,
5593 		 * skip save of the final negotiated settings to
5594 		 * SCSI device page 1.
5595 		 *
5596 		cfg.hdr = &header1;
5597 		cfg.physAddr = cfg1_dma_addr;
5598 		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5599 		cfg.dir = 1;
5600 		mpt_config(hd->ioc, &cfg);
5601 		 */
5602 	}
5603 
5604 	/* If this is a RAID Passthrough, enable internal IOs
5605 	 */
5606 	if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5607 		if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5608 			ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5609 	}
5610 
5611 	/* Done with the DV scan of the current target
5612 	 */
5613 	if (pDvBuf)
5614 		pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5615 
5616 	ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5617 			ioc->name, id));
5618 
5619 	return retcode;
5620 }
5621 
5622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5623 /*	mptscsih_dv_parms - perform a variety of operations on the
5624  *	parameters used for negotiation.
5625  *	@hd: Pointer to a SCSI host.
5626  *	@dv: Pointer to a structure that contains the maximum and current
5627  *		negotiated parameters.
5628  */
5629 static void
5630 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5631 {
5632 	VirtDevice		*pTarget;
5633 	SCSIDevicePage0_t	*pPage0;
5634 	SCSIDevicePage1_t	*pPage1;
5635 	int			val = 0, data, configuration;
5636 	u8			width = 0;
5637 	u8			offset = 0;
5638 	u8			factor = 0;
5639 	u8			negoFlags = 0;
5640 	u8			cmd = dv->cmd;
5641 	u8			id = dv->id;
5642 
5643 	switch (cmd) {
5644 	case MPT_GET_NVRAM_VALS:
5645 		ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5646 							 hd->ioc->name));
5647 		/* Get the NVRAM values and save in tmax
5648 		 * If not an LVD bus, the adapter minSyncFactor has been
5649 		 * already throttled back.
5650 		 */
5651 		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5652 			width = pTarget->maxWidth;
5653 			offset = pTarget->maxOffset;
5654 			factor = pTarget->minSyncFactor;
5655 			negoFlags = pTarget->negoFlags;
5656 		} else {
5657 			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5658 				data = hd->ioc->spi_data.nvram[id];
5659 				width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5660 				if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5661 					factor = MPT_ASYNC;
5662 				else {
5663 					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5664 					if ((factor == 0) || (factor == MPT_ASYNC)){
5665 						factor = MPT_ASYNC;
5666 						offset = 0;
5667 					}
5668 				}
5669 			} else {
5670 				width = MPT_NARROW;
5671 				offset = 0;
5672 				factor = MPT_ASYNC;
5673 			}
5674 
5675 			/* Set the negotiation flags */
5676 			negoFlags = hd->ioc->spi_data.noQas;
5677 			if (!width)
5678 				negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5679 
5680 			if (!offset)
5681 				negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5682 		}
5683 
5684 		/* limit by adapter capabilities */
5685 		width = min(width, hd->ioc->spi_data.maxBusWidth);
5686 		offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5687 		factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5688 
5689 		/* Check Consistency */
5690 		if (offset && (factor < MPT_ULTRA2) && !width)
5691 			factor = MPT_ULTRA2;
5692 
5693 		dv->max.width = width;
5694 		dv->max.offset = offset;
5695 		dv->max.factor = factor;
5696 		dv->max.flags = negoFlags;
5697 		ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5698 				id, width, factor, offset, negoFlags));
5699 		break;
5700 
5701 	case MPT_UPDATE_MAX:
5702 		ddvprintk((MYIOC_s_NOTE_FMT
5703 			"Updating with SDP0 Data: ", hd->ioc->name));
5704 		/* Update tmax values with those from Device Page 0.*/
5705 		pPage0 = (SCSIDevicePage0_t *) pPage;
5706 		if (pPage0) {
5707 			val = cpu_to_le32(pPage0->NegotiatedParameters);
5708 			dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5709 			dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5710 			dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5711 		}
5712 
5713 		dv->now.width = dv->max.width;
5714 		dv->now.offset = dv->max.offset;
5715 		dv->now.factor = dv->max.factor;
5716 		ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5717 				id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5718 		break;
5719 
5720 	case MPT_SET_MAX:
5721 		ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5722 								hd->ioc->name));
5723 		/* Set current to the max values. Update the config page.*/
5724 		dv->now.width = dv->max.width;
5725 		dv->now.offset = dv->max.offset;
5726 		dv->now.factor = dv->max.factor;
5727 		dv->now.flags = dv->max.flags;
5728 
5729 		pPage1 = (SCSIDevicePage1_t *)pPage;
5730 		if (pPage1) {
5731 			mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5732 				dv->now.offset, &val, &configuration, dv->now.flags);
5733 			dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5734 				id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5735 			pPage1->RequestedParameters = le32_to_cpu(val);
5736 			pPage1->Reserved = 0;
5737 			pPage1->Configuration = le32_to_cpu(configuration);
5738 		}
5739 
5740 		ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5741 				id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5742 		break;
5743 
5744 	case MPT_SET_MIN:
5745 		ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5746 								hd->ioc->name));
5747 		/* Set page to asynchronous and narrow
5748 		 * Do not update now, breaks fallback routine. */
5749 		width = MPT_NARROW;
5750 		offset = 0;
5751 		factor = MPT_ASYNC;
5752 		negoFlags = dv->max.flags;
5753 
5754 		pPage1 = (SCSIDevicePage1_t *)pPage;
5755 		if (pPage1) {
5756 			mptscsih_setDevicePage1Flags (width, factor,
5757 				offset, &val, &configuration, negoFlags);
5758 			dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5759 				id, width, factor, offset, negoFlags, val, configuration));
5760 			pPage1->RequestedParameters = le32_to_cpu(val);
5761 			pPage1->Reserved = 0;
5762 			pPage1->Configuration = le32_to_cpu(configuration);
5763 		}
5764 		ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5765 				id, width, factor, offset, val, configuration, negoFlags));
5766 		break;
5767 
5768 	case MPT_FALLBACK:
5769 		ddvprintk((MYIOC_s_NOTE_FMT
5770 			"Fallback: Start: offset %d, factor %x, width %d \n",
5771 				hd->ioc->name, dv->now.offset,
5772 				dv->now.factor, dv->now.width));
5773 		width = dv->now.width;
5774 		offset = dv->now.offset;
5775 		factor = dv->now.factor;
5776 		if ((offset) && (dv->max.width)) {
5777 			if (factor < MPT_ULTRA160)
5778 				factor = MPT_ULTRA160;
5779 			else if (factor < MPT_ULTRA2) {
5780 				factor = MPT_ULTRA2;
5781 				width = MPT_WIDE;
5782 			} else if ((factor == MPT_ULTRA2) && width) {
5783 				factor = MPT_ULTRA2;
5784 				width = MPT_NARROW;
5785 			} else if (factor < MPT_ULTRA) {
5786 				factor = MPT_ULTRA;
5787 				width = MPT_WIDE;
5788 			} else if ((factor == MPT_ULTRA) && width) {
5789 				width = MPT_NARROW;
5790 			} else if (factor < MPT_FAST) {
5791 				factor = MPT_FAST;
5792 				width = MPT_WIDE;
5793 			} else if ((factor == MPT_FAST) && width) {
5794 				factor = MPT_FAST;
5795 				width = MPT_NARROW;
5796 			} else if (factor < MPT_SCSI) {
5797 				factor = MPT_SCSI;
5798 				width = MPT_WIDE;
5799 			} else if ((factor == MPT_SCSI) && width) {
5800 				factor = MPT_SCSI;
5801 				width = MPT_NARROW;
5802 			} else {
5803 				factor = MPT_ASYNC;
5804 				offset = 0;
5805 			}
5806 
5807 		} else if (offset) {
5808 			width = MPT_NARROW;
5809 			if (factor < MPT_ULTRA)
5810 				factor = MPT_ULTRA;
5811 			else if (factor < MPT_FAST)
5812 				factor = MPT_FAST;
5813 			else if (factor < MPT_SCSI)
5814 				factor = MPT_SCSI;
5815 			else {
5816 				factor = MPT_ASYNC;
5817 				offset = 0;
5818 			}
5819 
5820 		} else {
5821 			width = MPT_NARROW;
5822 			factor = MPT_ASYNC;
5823 		}
5824 		dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5825 		dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5826 
5827 		dv->now.width = width;
5828 		dv->now.offset = offset;
5829 		dv->now.factor = factor;
5830 		dv->now.flags = dv->max.flags;
5831 
5832 		pPage1 = (SCSIDevicePage1_t *)pPage;
5833 		if (pPage1) {
5834 			mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5835 						&configuration, dv->now.flags);
5836 			dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5837 			     id, width, offset, factor, dv->now.flags, val, configuration));
5838 
5839 			pPage1->RequestedParameters = le32_to_cpu(val);
5840 			pPage1->Reserved = 0;
5841 			pPage1->Configuration = le32_to_cpu(configuration);
5842 		}
5843 
5844 		ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5845 			     id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5846 		break;
5847 
5848 	case MPT_SAVE:
5849 		ddvprintk((MYIOC_s_NOTE_FMT
5850 			"Saving to Target structure: ", hd->ioc->name));
5851 		ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5852 			     id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5853 
5854 		/* Save these values to target structures
5855 		 * or overwrite nvram (phys disks only).
5856 		 */
5857 
5858 		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5859 			pTarget->maxWidth = dv->now.width;
5860 			pTarget->maxOffset = dv->now.offset;
5861 			pTarget->minSyncFactor = dv->now.factor;
5862 			pTarget->negoFlags = dv->now.flags;
5863 		} else {
5864 			/* Preserv all flags, use
5865 			 * read-modify-write algorithm
5866 			 */
5867 			if (hd->ioc->spi_data.nvram) {
5868 				data = hd->ioc->spi_data.nvram[id];
5869 
5870 				if (dv->now.width)
5871 					data &= ~MPT_NVRAM_WIDE_DISABLE;
5872 				else
5873 					data |= MPT_NVRAM_WIDE_DISABLE;
5874 
5875 				if (!dv->now.offset)
5876 					factor = MPT_ASYNC;
5877 
5878 				data &= ~MPT_NVRAM_SYNC_MASK;
5879 				data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5880 
5881 				hd->ioc->spi_data.nvram[id] = data;
5882 			}
5883 		}
5884 		break;
5885 	}
5886 }
5887 
5888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5889 /*	mptscsih_fillbuf - fill a buffer with a special data pattern
5890  *		cleanup. For bus scan only.
5891  *
5892  *	@buffer: Pointer to data buffer to be filled.
5893  *	@size: Number of bytes to fill
5894  *	@index: Pattern index
5895  *	@width: bus width, 0 (8 bits) or 1 (16 bits)
5896  */
5897 static void
5898 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5899 {
5900 	char *ptr = buffer;
5901 	int ii;
5902 	char byte;
5903 	short val;
5904 
5905 	switch (index) {
5906 	case 0:
5907 
5908 		if (width) {
5909 			/* Pattern:  0000 FFFF 0000 FFFF
5910 			 */
5911 			for (ii=0; ii < size; ii++, ptr++) {
5912 				if (ii & 0x02)
5913 					*ptr = 0xFF;
5914 				else
5915 					*ptr = 0x00;
5916 			}
5917 		} else {
5918 			/* Pattern:  00 FF 00 FF
5919 			 */
5920 			for (ii=0; ii < size; ii++, ptr++) {
5921 				if (ii & 0x01)
5922 					*ptr = 0xFF;
5923 				else
5924 					*ptr = 0x00;
5925 			}
5926 		}
5927 		break;
5928 
5929 	case 1:
5930 		if (width) {
5931 			/* Pattern:  5555 AAAA 5555 AAAA 5555
5932 			 */
5933 			for (ii=0; ii < size; ii++, ptr++) {
5934 				if (ii & 0x02)
5935 					*ptr = 0xAA;
5936 				else
5937 					*ptr = 0x55;
5938 			}
5939 		} else {
5940 			/* Pattern:  55 AA 55 AA 55
5941 			 */
5942 			for (ii=0; ii < size; ii++, ptr++) {
5943 				if (ii & 0x01)
5944 					*ptr = 0xAA;
5945 				else
5946 					*ptr = 0x55;
5947 			}
5948 		}
5949 		break;
5950 
5951 	case 2:
5952 		/* Pattern:  00 01 02 03 04 05
5953 		 * ... FE FF 00 01..
5954 		 */
5955 		for (ii=0; ii < size; ii++, ptr++)
5956 			*ptr = (char) ii;
5957 		break;
5958 
5959 	case 3:
5960 		if (width) {
5961 			/* Wide Pattern:  FFFE 0001 FFFD 0002
5962 			 * ...  4000 DFFF 8000 EFFF
5963 			 */
5964 			byte = 0;
5965 			for (ii=0; ii < size/2; ii++) {
5966 				/* Create the base pattern
5967 				 */
5968 				val = (1 << byte);
5969 				/* every 64 (0x40) bytes flip the pattern
5970 				 * since we fill 2 bytes / iteration,
5971 				 * test for ii = 0x20
5972 				 */
5973 				if (ii & 0x20)
5974 					val = ~(val);
5975 
5976 				if (ii & 0x01) {
5977 					*ptr = (char)( (val & 0xFF00) >> 8);
5978 					ptr++;
5979 					*ptr = (char)(val & 0xFF);
5980 					byte++;
5981 					byte &= 0x0F;
5982 				} else {
5983 					val = ~val;
5984 					*ptr = (char)( (val & 0xFF00) >> 8);
5985 					ptr++;
5986 					*ptr = (char)(val & 0xFF);
5987 				}
5988 
5989 				ptr++;
5990 			}
5991 		} else {
5992 			/* Narrow Pattern:  FE 01 FD 02 FB 04
5993 			 * .. 7F 80 01 FE 02 FD ...  80 7F
5994 			 */
5995 			byte = 0;
5996 			for (ii=0; ii < size; ii++, ptr++) {
5997 				/* Base pattern - first 32 bytes
5998 				 */
5999 				if (ii & 0x01) {
6000 					*ptr = (1 << byte);
6001 					byte++;
6002 					byte &= 0x07;
6003 				} else {
6004 					*ptr = (char) (~(1 << byte));
6005 				}
6006 
6007 				/* Flip the pattern every 32 bytes
6008 				 */
6009 				if (ii & 0x20)
6010 					*ptr = ~(*ptr);
6011 			}
6012 		}
6013 		break;
6014 	}
6015 }
6016 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6017 
6018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6019 
6020 module_init(mptscsih_init);
6021 module_exit(mptscsih_exit);
6022