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