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