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