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