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