xref: /linux/drivers/message/fusion/mptscsih.c (revision de2fe5e07d58424bc286fff3fd3c1b0bf933cd58)
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 /*
118  *  Other private/forward protos...
119  */
120 int		mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
121 static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
122 int		mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
123 
124 static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
125 				 SCSIIORequest_t *pReq, int req_idx);
126 static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
127 static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
128 static int	mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
129 static int	mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
130 static u32	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
131 
132 static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
133 
134 int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
135 int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
136 
137 static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
138 static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
139 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
140 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
141 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
142 static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
143 
144 void 		mptscsih_remove(struct pci_dev *);
145 void 		mptscsih_shutdown(struct pci_dev *);
146 #ifdef CONFIG_PM
147 int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
148 int 		mptscsih_resume(struct pci_dev *pdev);
149 #endif
150 
151 #define SNS_LEN(scp)	sizeof((scp)->sense_buffer)
152 
153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
154 /**
155  *	mptscsih_add_sge - Place a simple SGE at address pAddr.
156  *	@pAddr: virtual address for SGE
157  *	@flagslength: SGE flags and data transfer length
158  *	@dma_addr: Physical address
159  *
160  *	This routine places a MPT request frame back on the MPT adapter's
161  *	FreeQ.
162  */
163 static inline void
164 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
165 {
166 	if (sizeof(dma_addr_t) == sizeof(u64)) {
167 		SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
168 		u32 tmp = dma_addr & 0xFFFFFFFF;
169 
170 		pSge->FlagsLength = cpu_to_le32(flagslength);
171 		pSge->Address.Low = cpu_to_le32(tmp);
172 		tmp = (u32) ((u64)dma_addr >> 32);
173 		pSge->Address.High = cpu_to_le32(tmp);
174 
175 	} else {
176 		SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
177 		pSge->FlagsLength = cpu_to_le32(flagslength);
178 		pSge->Address = cpu_to_le32(dma_addr);
179 	}
180 } /* mptscsih_add_sge() */
181 
182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
183 /**
184  *	mptscsih_add_chain - Place a chain SGE at address pAddr.
185  *	@pAddr: virtual address for SGE
186  *	@next: nextChainOffset value (u32's)
187  *	@length: length of next SGL segment
188  *	@dma_addr: Physical address
189  *
190  *	This routine places a MPT request frame back on the MPT adapter's
191  *	FreeQ.
192  */
193 static inline void
194 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
195 {
196 	if (sizeof(dma_addr_t) == sizeof(u64)) {
197 		SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
198 		u32 tmp = dma_addr & 0xFFFFFFFF;
199 
200 		pChain->Length = cpu_to_le16(length);
201 		pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
202 
203 		pChain->NextChainOffset = next;
204 
205 		pChain->Address.Low = cpu_to_le32(tmp);
206 		tmp = (u32) ((u64)dma_addr >> 32);
207 		pChain->Address.High = cpu_to_le32(tmp);
208 	} else {
209 		SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
210 		pChain->Length = cpu_to_le16(length);
211 		pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
212 		pChain->NextChainOffset = next;
213 		pChain->Address = cpu_to_le32(dma_addr);
214 	}
215 } /* mptscsih_add_chain() */
216 
217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
218 /*
219  *	mptscsih_getFreeChainBuffer - Function to get a free chain
220  *	from the MPT_SCSI_HOST FreeChainQ.
221  *	@ioc: Pointer to MPT_ADAPTER structure
222  *	@req_idx: Index of the SCSI IO request frame. (output)
223  *
224  *	return SUCCESS or FAILED
225  */
226 static inline int
227 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
228 {
229 	MPT_FRAME_HDR *chainBuf;
230 	unsigned long flags;
231 	int rc;
232 	int chain_idx;
233 
234 	dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
235 			ioc->name));
236 	spin_lock_irqsave(&ioc->FreeQlock, flags);
237 	if (!list_empty(&ioc->FreeChainQ)) {
238 		int offset;
239 
240 		chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
241 				u.frame.linkage.list);
242 		list_del(&chainBuf->u.frame.linkage.list);
243 		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
244 		chain_idx = offset / ioc->req_sz;
245 		rc = SUCCESS;
246 		dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
247 			ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
248 	} else {
249 		rc = FAILED;
250 		chain_idx = MPT_HOST_NO_CHAIN;
251 		dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
252 			ioc->name));
253 	}
254 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
255 
256 	*retIndex = chain_idx;
257 	return rc;
258 } /* mptscsih_getFreeChainBuffer() */
259 
260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
261 /*
262  *	mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
263  *	SCSIIORequest_t Message Frame.
264  *	@ioc: Pointer to MPT_ADAPTER structure
265  *	@SCpnt: Pointer to scsi_cmnd structure
266  *	@pReq: Pointer to SCSIIORequest_t structure
267  *
268  *	Returns ...
269  */
270 static int
271 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
272 		SCSIIORequest_t *pReq, int req_idx)
273 {
274 	char 	*psge;
275 	char	*chainSge;
276 	struct scatterlist *sg;
277 	int	 frm_sz;
278 	int	 sges_left, sg_done;
279 	int	 chain_idx = MPT_HOST_NO_CHAIN;
280 	int	 sgeOffset;
281 	int	 numSgeSlots, numSgeThisFrame;
282 	u32	 sgflags, sgdir, thisxfer = 0;
283 	int	 chain_dma_off = 0;
284 	int	 newIndex;
285 	int	 ii;
286 	dma_addr_t v2;
287 	u32	RequestNB;
288 
289 	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
290 	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
291 		sgdir = MPT_TRANSFER_HOST_TO_IOC;
292 	} else {
293 		sgdir = MPT_TRANSFER_IOC_TO_HOST;
294 	}
295 
296 	psge = (char *) &pReq->SGL;
297 	frm_sz = ioc->req_sz;
298 
299 	/* Map the data portion, if any.
300 	 * sges_left  = 0 if no data transfer.
301 	 */
302 	if ( (sges_left = SCpnt->use_sg) ) {
303 		sges_left = pci_map_sg(ioc->pcidev,
304 			       (struct scatterlist *) SCpnt->request_buffer,
305  			       SCpnt->use_sg,
306 			       SCpnt->sc_data_direction);
307 		if (sges_left == 0)
308 			return FAILED;
309 	} else if (SCpnt->request_bufflen) {
310 		SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
311 				      SCpnt->request_buffer,
312 				      SCpnt->request_bufflen,
313 				      SCpnt->sc_data_direction);
314 		dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
315 				ioc->name, SCpnt, SCpnt->request_bufflen));
316 		mptscsih_add_sge((char *) &pReq->SGL,
317 			0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
318 			SCpnt->SCp.dma_handle);
319 
320 		return SUCCESS;
321 	}
322 
323 	/* Handle the SG case.
324 	 */
325 	sg = (struct scatterlist *) SCpnt->request_buffer;
326 	sg_done  = 0;
327 	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
328 	chainSge = NULL;
329 
330 	/* Prior to entering this loop - the following must be set
331 	 * current MF:  sgeOffset (bytes)
332 	 *              chainSge (Null if original MF is not a chain buffer)
333 	 *              sg_done (num SGE done for this MF)
334 	 */
335 
336 nextSGEset:
337 	numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
338 	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
339 
340 	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
341 
342 	/* Get first (num - 1) SG elements
343 	 * Skip any SG entries with a length of 0
344 	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
345 	 */
346 	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
347 		thisxfer = sg_dma_len(sg);
348 		if (thisxfer == 0) {
349 			sg ++; /* Get next SG element from the OS */
350 			sg_done++;
351 			continue;
352 		}
353 
354 		v2 = sg_dma_address(sg);
355 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
356 
357 		sg++;		/* Get next SG element from the OS */
358 		psge += (sizeof(u32) + sizeof(dma_addr_t));
359 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
360 		sg_done++;
361 	}
362 
363 	if (numSgeThisFrame == sges_left) {
364 		/* Add last element, end of buffer and end of list flags.
365 		 */
366 		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
367 				MPT_SGE_FLAGS_END_OF_BUFFER |
368 				MPT_SGE_FLAGS_END_OF_LIST;
369 
370 		/* Add last SGE and set termination flags.
371 		 * Note: Last SGE may have a length of 0 - which should be ok.
372 		 */
373 		thisxfer = sg_dma_len(sg);
374 
375 		v2 = sg_dma_address(sg);
376 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
377 		/*
378 		sg++;
379 		psge += (sizeof(u32) + sizeof(dma_addr_t));
380 		*/
381 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
382 		sg_done++;
383 
384 		if (chainSge) {
385 			/* The current buffer is a chain buffer,
386 			 * but there is not another one.
387 			 * Update the chain element
388 			 * Offset and Length fields.
389 			 */
390 			mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
391 		} else {
392 			/* The current buffer is the original MF
393 			 * and there is no Chain buffer.
394 			 */
395 			pReq->ChainOffset = 0;
396 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
397 			dsgprintk((MYIOC_s_INFO_FMT
398 			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
399 			ioc->RequestNB[req_idx] = RequestNB;
400 		}
401 	} else {
402 		/* At least one chain buffer is needed.
403 		 * Complete the first MF
404 		 *  - last SGE element, set the LastElement bit
405 		 *  - set ChainOffset (words) for orig MF
406 		 *             (OR finish previous MF chain buffer)
407 		 *  - update MFStructPtr ChainIndex
408 		 *  - Populate chain element
409 		 * Also
410 		 * Loop until done.
411 		 */
412 
413 		dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
414 				ioc->name, sg_done));
415 
416 		/* Set LAST_ELEMENT flag for last non-chain element
417 		 * in the buffer. Since psge points at the NEXT
418 		 * SGE element, go back one SGE element, update the flags
419 		 * and reset the pointer. (Note: sgflags & thisxfer are already
420 		 * set properly).
421 		 */
422 		if (sg_done) {
423 			u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
424 			sgflags = le32_to_cpu(*ptmp);
425 			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
426 			*ptmp = cpu_to_le32(sgflags);
427 		}
428 
429 		if (chainSge) {
430 			/* The current buffer is a chain buffer.
431 			 * chainSge points to the previous Chain Element.
432 			 * Update its chain element Offset and Length (must
433 			 * include chain element size) fields.
434 			 * Old chain element is now complete.
435 			 */
436 			u8 nextChain = (u8) (sgeOffset >> 2);
437 			sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
438 			mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
439 		} else {
440 			/* The original MF buffer requires a chain buffer -
441 			 * set the offset.
442 			 * Last element in this MF is a chain element.
443 			 */
444 			pReq->ChainOffset = (u8) (sgeOffset >> 2);
445 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
446 			dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
447 			ioc->RequestNB[req_idx] = RequestNB;
448 		}
449 
450 		sges_left -= sg_done;
451 
452 
453 		/* NOTE: psge points to the beginning of the chain element
454 		 * in current buffer. Get a chain buffer.
455 		 */
456 		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
457 			dfailprintk((MYIOC_s_INFO_FMT
458 			    "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
459  			    ioc->name, pReq->CDB[0], SCpnt));
460 			return FAILED;
461 		}
462 
463 		/* Update the tracking arrays.
464 		 * If chainSge == NULL, update ReqToChain, else ChainToChain
465 		 */
466 		if (chainSge) {
467 			ioc->ChainToChain[chain_idx] = newIndex;
468 		} else {
469 			ioc->ReqToChain[req_idx] = newIndex;
470 		}
471 		chain_idx = newIndex;
472 		chain_dma_off = ioc->req_sz * chain_idx;
473 
474 		/* Populate the chainSGE for the current buffer.
475 		 * - Set chain buffer pointer to psge and fill
476 		 *   out the Address and Flags fields.
477 		 */
478 		chainSge = (char *) psge;
479 		dsgprintk((KERN_INFO "  Current buff @ %p (index 0x%x)",
480 				psge, req_idx));
481 
482 		/* Start the SGE for the next buffer
483 		 */
484 		psge = (char *) (ioc->ChainBuffer + chain_dma_off);
485 		sgeOffset = 0;
486 		sg_done = 0;
487 
488 		dsgprintk((KERN_INFO "  Chain buff @ %p (index 0x%x)\n",
489 				psge, chain_idx));
490 
491 		/* Start the SGE for the next buffer
492 		 */
493 
494 		goto nextSGEset;
495 	}
496 
497 	return SUCCESS;
498 } /* mptscsih_AddSGE() */
499 
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
501 /*
502  *	mptscsih_io_done - Main SCSI IO callback routine registered to
503  *	Fusion MPT (base) driver
504  *	@ioc: Pointer to MPT_ADAPTER structure
505  *	@mf: Pointer to original MPT request frame
506  *	@r: Pointer to MPT reply frame (NULL if TurboReply)
507  *
508  *	This routine is called from mpt.c::mpt_interrupt() at the completion
509  *	of any SCSI IO request.
510  *	This routine is registered with the Fusion MPT (base) driver at driver
511  *	load/init time via the mpt_register() API call.
512  *
513  *	Returns 1 indicating alloc'd request frame ptr should be freed.
514  */
515 int
516 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
517 {
518 	struct scsi_cmnd	*sc;
519 	MPT_SCSI_HOST	*hd;
520 	SCSIIORequest_t	*pScsiReq;
521 	SCSIIOReply_t	*pScsiReply;
522 	u16		 req_idx, req_idx_MR;
523 
524 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
525 
526 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
527 	req_idx_MR = (mr != NULL) ?
528 	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
529 	if ((req_idx != req_idx_MR) ||
530 	    (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
531 		printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
532 		    ioc->name);
533 		printk (MYIOC_s_ERR_FMT
534 		    "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
535 		    ioc->name, req_idx, req_idx_MR, mf, mr,
536 		    hd->ScsiLookup[req_idx_MR]);
537 		return 0;
538 	}
539 
540 	sc = hd->ScsiLookup[req_idx];
541 	if (sc == NULL) {
542 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
543 
544 		/* Remark: writeSDP1 will use the ScsiDoneCtx
545 		 * If a SCSI I/O cmd, device disabled by OS and
546 		 * completion done. Cannot touch sc struct. Just free mem.
547 		 */
548 		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
549 			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
550 			ioc->name);
551 
552 		mptscsih_freeChainBuffers(ioc, req_idx);
553 		return 1;
554 	}
555 
556 	sc->result = DID_OK << 16;		/* Set default reply as OK */
557 	pScsiReq = (SCSIIORequest_t *) mf;
558 	pScsiReply = (SCSIIOReply_t *) mr;
559 
560 	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
561 		dmfprintk((MYIOC_s_INFO_FMT
562 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
563 			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
564 	}else{
565 		dmfprintk((MYIOC_s_INFO_FMT
566 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
567 			ioc->name, mf, mr, sc, req_idx));
568 	}
569 
570 	if (pScsiReply == NULL) {
571 		/* special context reply handling */
572 		;
573 	} else {
574 		u32	 xfer_cnt;
575 		u16	 status;
576 		u8	 scsi_state, scsi_status;
577 
578 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
579 		scsi_state = pScsiReply->SCSIState;
580 		scsi_status = pScsiReply->SCSIStatus;
581 		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
582 		sc->resid = sc->request_bufflen - xfer_cnt;
583 
584 		/*
585 		 *  if we get a data underrun indication, yet no data was
586 		 *  transferred and the SCSI status indicates that the
587 		 *  command was never started, change the data underrun
588 		 *  to success
589 		 */
590 		if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
591 		    (scsi_status == MPI_SCSI_STATUS_BUSY ||
592 		     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
593 		     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
594 			status = MPI_IOCSTATUS_SUCCESS;
595 		}
596 
597 		dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
598 			"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
599 			"resid=%d bufflen=%d xfer_cnt=%d\n",
600 			ioc->id, sc->device->id, sc->device->lun,
601 			status, scsi_state, scsi_status, sc->resid,
602 			sc->request_bufflen, xfer_cnt));
603 
604 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
605 			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
606 
607 		/*
608 		 *  Look for + dump FCP ResponseInfo[]!
609 		 */
610 		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
611 		    pScsiReply->ResponseInfo) {
612 			printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
613 			"FCP_ResponseInfo=%08xh\n",
614 			ioc->id, sc->device->id, sc->device->lun,
615 			le32_to_cpu(pScsiReply->ResponseInfo));
616 		}
617 
618 		switch(status) {
619 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
620 			/* CHECKME!
621 			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
622 			 * But not: DID_BUS_BUSY lest one risk
623 			 * killing interrupt handler:-(
624 			 */
625 			sc->result = SAM_STAT_BUSY;
626 			break;
627 
628 		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
629 		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
630 			sc->result = DID_BAD_TARGET << 16;
631 			break;
632 
633 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
634 			/* Spoof to SCSI Selection Timeout! */
635 			sc->result = DID_NO_CONNECT << 16;
636 
637 			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
638 				hd->sel_timeout[pScsiReq->TargetID]++;
639 			break;
640 
641 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
642 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
643 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
644 			/* Linux handles an unsolicited DID_RESET better
645 			 * than an unsolicited DID_ABORT.
646 			 */
647 			sc->result = DID_RESET << 16;
648 
649 			break;
650 
651 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
652 			sc->resid = sc->request_bufflen - xfer_cnt;
653 			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
654 				sc->result=DID_SOFT_ERROR << 16;
655 			else /* Sufficient data transfer occurred */
656 				sc->result = (DID_OK << 16) | scsi_status;
657 			dreplyprintk((KERN_NOTICE
658 			    "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
659 			break;
660 
661 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
662 			/*
663 			 *  Do upfront check for valid SenseData and give it
664 			 *  precedence!
665 			 */
666 			sc->result = (DID_OK << 16) | scsi_status;
667 			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
668 				/* Have already saved the status and sense data
669 				 */
670 				;
671 			} else {
672 				if (xfer_cnt < sc->underflow) {
673 					if (scsi_status == SAM_STAT_BUSY)
674 						sc->result = SAM_STAT_BUSY;
675 					else
676 						sc->result = DID_SOFT_ERROR << 16;
677 				}
678 				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
679 					/* What to do?
680 				 	*/
681 					sc->result = DID_SOFT_ERROR << 16;
682 				}
683 				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
684 					/*  Not real sure here either...  */
685 					sc->result = DID_RESET << 16;
686 				}
687 			}
688 
689 			dreplyprintk((KERN_NOTICE "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
690 					sc->underflow));
691 			dreplyprintk((KERN_NOTICE "  ActBytesXferd=%02xh\n", xfer_cnt));
692 			/* Report Queue Full
693 			 */
694 			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
695 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
696 
697 			break;
698 
699 		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
700 			sc->resid=0;
701 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
702 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
703 			if (scsi_status == MPI_SCSI_STATUS_BUSY)
704 				sc->result = (DID_BUS_BUSY << 16) | scsi_status;
705 			else
706 				sc->result = (DID_OK << 16) | scsi_status;
707 			if (scsi_state == 0) {
708 				;
709 			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
710 				/*
711 				 * If running against circa 200003dd 909 MPT f/w,
712 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
713 				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
714 				 * and with SenseBytes set to 0.
715 				 */
716 				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
717 					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
718 
719 			}
720 			else if (scsi_state &
721 			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
722 			   ) {
723 				/*
724 				 * What to do?
725 				 */
726 				sc->result = DID_SOFT_ERROR << 16;
727 			}
728 			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
729 				/*  Not real sure here either...  */
730 				sc->result = DID_RESET << 16;
731 			}
732 			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
733 				/* Device Inq. data indicates that it supports
734 				 * QTags, but rejects QTag messages.
735 				 * This command completed OK.
736 				 *
737 				 * Not real sure here either so do nothing...  */
738 			}
739 
740 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
741 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
742 
743 			/* Add handling of:
744 			 * Reservation Conflict, Busy,
745 			 * Command Terminated, CHECK
746 			 */
747 			break;
748 
749 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
750 			sc->result = DID_SOFT_ERROR << 16;
751 			break;
752 
753 		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
754 		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
755 		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
756 		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
757 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
758 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
759 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
760 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
761 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
762 		default:
763 			/*
764 			 * What to do?
765 			 */
766 			sc->result = DID_SOFT_ERROR << 16;
767 			break;
768 
769 		}	/* switch(status) */
770 
771 		dreplyprintk((KERN_NOTICE "  sc->result is %08xh\n", sc->result));
772 	} /* end of address reply case */
773 
774 	/* Unmap the DMA buffers, if any. */
775 	if (sc->use_sg) {
776 		pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
777 			    sc->use_sg, sc->sc_data_direction);
778 	} else if (sc->request_bufflen) {
779 		pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
780 				sc->request_bufflen, sc->sc_data_direction);
781 	}
782 
783 	hd->ScsiLookup[req_idx] = NULL;
784 
785 	sc->scsi_done(sc);		/* Issue the command callback */
786 
787 	/* Free Chain buffers */
788 	mptscsih_freeChainBuffers(ioc, req_idx);
789 	return 1;
790 }
791 
792 /*
793  *	mptscsih_flush_running_cmds - For each command found, search
794  *		Scsi_Host instance taskQ and reply to OS.
795  *		Called only if recovering from a FW reload.
796  *	@hd: Pointer to a SCSI HOST structure
797  *
798  *	Returns: None.
799  *
800  *	Must be called while new I/Os are being queued.
801  */
802 static void
803 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
804 {
805 	MPT_ADAPTER *ioc = hd->ioc;
806 	struct scsi_cmnd	*SCpnt;
807 	MPT_FRAME_HDR	*mf;
808 	int		 ii;
809 	int		 max = ioc->req_depth;
810 
811 	dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
812 	for (ii= 0; ii < max; ii++) {
813 		if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
814 
815 			/* Command found.
816 			 */
817 
818 			/* Null ScsiLookup index
819 			 */
820 			hd->ScsiLookup[ii] = NULL;
821 
822 			mf = MPT_INDEX_2_MFPTR(ioc, ii);
823 			dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
824 					mf, SCpnt));
825 
826 			/* Set status, free OS resources (SG DMA buffers)
827 			 * Do OS callback
828 			 * Free driver resources (chain, msg buffers)
829 			 */
830 			if (SCpnt->use_sg) {
831 				pci_unmap_sg(ioc->pcidev,
832 					(struct scatterlist *) SCpnt->request_buffer,
833 					SCpnt->use_sg,
834 					SCpnt->sc_data_direction);
835 			} else if (SCpnt->request_bufflen) {
836 				pci_unmap_single(ioc->pcidev,
837 					SCpnt->SCp.dma_handle,
838 					SCpnt->request_bufflen,
839 					SCpnt->sc_data_direction);
840 			}
841 			SCpnt->result = DID_RESET << 16;
842 			SCpnt->host_scribble = NULL;
843 
844 			/* Free Chain buffers */
845 			mptscsih_freeChainBuffers(ioc, ii);
846 
847 			/* Free Message frames */
848 			mpt_free_msg_frame(ioc, mf);
849 
850 			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
851 		}
852 	}
853 
854 	return;
855 }
856 
857 /*
858  *	mptscsih_search_running_cmds - Delete any commands associated
859  *		with the specified target and lun. Function called only
860  *		when a lun is disable by mid-layer.
861  *		Do NOT access the referenced scsi_cmnd structure or
862  *		members. Will cause either a paging or NULL ptr error.
863  *		(BUT, BUT, BUT, the code does reference it! - mdr)
864  *      @hd: Pointer to a SCSI HOST structure
865  *	@vdevice: per device private data
866  *
867  *	Returns: None.
868  *
869  *	Called from slave_destroy.
870  */
871 static void
872 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
873 {
874 	SCSIIORequest_t	*mf = NULL;
875 	int		 ii;
876 	int		 max = hd->ioc->req_depth;
877 	struct scsi_cmnd *sc;
878 
879 	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
880 			vdevice->target_id, vdevice->lun, max));
881 
882 	for (ii=0; ii < max; ii++) {
883 		if ((sc = hd->ScsiLookup[ii]) != NULL) {
884 
885 			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
886 
887 			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
888 					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
889 
890 			if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
891 				continue;
892 
893 			/* Cleanup
894 			 */
895 			hd->ScsiLookup[ii] = NULL;
896 			mptscsih_freeChainBuffers(hd->ioc, ii);
897 			mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
898 			if (sc->use_sg) {
899 				pci_unmap_sg(hd->ioc->pcidev,
900 				(struct scatterlist *) sc->request_buffer,
901 					sc->use_sg,
902 					sc->sc_data_direction);
903 			} else if (sc->request_bufflen) {
904 				pci_unmap_single(hd->ioc->pcidev,
905 					sc->SCp.dma_handle,
906 					sc->request_bufflen,
907 					sc->sc_data_direction);
908 			}
909 			sc->host_scribble = NULL;
910 			sc->result = DID_NO_CONNECT << 16;
911 			sc->scsi_done(sc);
912 		}
913 	}
914 	return;
915 }
916 
917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
918 
919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
920 /*
921  *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
922  *	from a SCSI target device.
923  *	@sc: Pointer to scsi_cmnd structure
924  *	@pScsiReply: Pointer to SCSIIOReply_t
925  *	@pScsiReq: Pointer to original SCSI request
926  *
927  *	This routine periodically reports QUEUE_FULL status returned from a
928  *	SCSI target device.  It reports this to the console via kernel
929  *	printk() API call, not more than once every 10 seconds.
930  */
931 static void
932 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
933 {
934 	long time = jiffies;
935 	MPT_SCSI_HOST		*hd;
936 
937 	if (sc->device == NULL)
938 		return;
939 	if (sc->device->host == NULL)
940 		return;
941 	if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
942 		return;
943 
944 	if (time - hd->last_queue_full > 10 * HZ) {
945 		dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
946 				hd->ioc->name, 0, sc->device->id, sc->device->lun));
947 		hd->last_queue_full = time;
948 	}
949 }
950 
951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 /*
953  *	mptscsih_remove - Removed scsi devices
954  *	@pdev: Pointer to pci_dev structure
955  *
956  *
957  */
958 void
959 mptscsih_remove(struct pci_dev *pdev)
960 {
961 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
962 	struct Scsi_Host 	*host = ioc->sh;
963 	MPT_SCSI_HOST		*hd;
964 	int sz1;
965 
966 	if(!host) {
967 		mpt_detach(pdev);
968 		return;
969 	}
970 
971 	scsi_remove_host(host);
972 
973 	if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
974 		return;
975 
976 	mptscsih_shutdown(pdev);
977 
978 	sz1=0;
979 
980 	if (hd->ScsiLookup != NULL) {
981 		sz1 = hd->ioc->req_depth * sizeof(void *);
982 		kfree(hd->ScsiLookup);
983 		hd->ScsiLookup = NULL;
984 	}
985 
986 	/*
987 	 * Free pointer array.
988 	 */
989 	kfree(hd->Targets);
990 	hd->Targets = NULL;
991 
992 	dprintk((MYIOC_s_INFO_FMT
993 	    "Free'd ScsiLookup (%d) memory\n",
994 	    hd->ioc->name, sz1));
995 
996 	kfree(hd->info_kbuf);
997 
998 	/* NULL the Scsi_Host pointer
999 	 */
1000 	hd->ioc->sh = NULL;
1001 
1002 	scsi_host_put(host);
1003 
1004 	mpt_detach(pdev);
1005 
1006 }
1007 
1008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1009 /*
1010  *	mptscsih_shutdown - reboot notifier
1011  *
1012  */
1013 void
1014 mptscsih_shutdown(struct pci_dev *pdev)
1015 {
1016 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1017 	struct Scsi_Host 	*host = ioc->sh;
1018 	MPT_SCSI_HOST		*hd;
1019 
1020 	if(!host)
1021 		return;
1022 
1023 	hd = (MPT_SCSI_HOST *)host->hostdata;
1024 
1025 }
1026 
1027 #ifdef CONFIG_PM
1028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1029 /*
1030  *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1031  *
1032  *
1033  */
1034 int
1035 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1036 {
1037 	mptscsih_shutdown(pdev);
1038 	return mpt_suspend(pdev,state);
1039 }
1040 
1041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1042 /*
1043  *	mptscsih_resume - Fusion MPT scsi driver resume routine.
1044  *
1045  *
1046  */
1047 int
1048 mptscsih_resume(struct pci_dev *pdev)
1049 {
1050 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
1051 	struct Scsi_Host 	*host = ioc->sh;
1052 	MPT_SCSI_HOST		*hd;
1053 
1054 	mpt_resume(pdev);
1055 
1056 	if(!host)
1057 		return 0;
1058 
1059 	hd = (MPT_SCSI_HOST *)host->hostdata;
1060 	if(!hd)
1061 		return 0;
1062 
1063 	return 0;
1064 }
1065 
1066 #endif
1067 
1068 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1069 /**
1070  *	mptscsih_info - Return information about MPT adapter
1071  *	@SChost: Pointer to Scsi_Host structure
1072  *
1073  *	(linux scsi_host_template.info routine)
1074  *
1075  *	Returns pointer to buffer where information was written.
1076  */
1077 const char *
1078 mptscsih_info(struct Scsi_Host *SChost)
1079 {
1080 	MPT_SCSI_HOST *h;
1081 	int size = 0;
1082 
1083 	h = (MPT_SCSI_HOST *)SChost->hostdata;
1084 
1085 	if (h) {
1086 		if (h->info_kbuf == NULL)
1087 			if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1088 				return h->info_kbuf;
1089 		h->info_kbuf[0] = '\0';
1090 
1091 		mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1092 		h->info_kbuf[size-1] = '\0';
1093 	}
1094 
1095 	return h->info_kbuf;
1096 }
1097 
1098 struct info_str {
1099 	char *buffer;
1100 	int   length;
1101 	int   offset;
1102 	int   pos;
1103 };
1104 
1105 static void
1106 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1107 {
1108 	if (info->pos + len > info->length)
1109 		len = info->length - info->pos;
1110 
1111 	if (info->pos + len < info->offset) {
1112 		info->pos += len;
1113 		return;
1114 	}
1115 
1116 	if (info->pos < info->offset) {
1117 	        data += (info->offset - info->pos);
1118 	        len  -= (info->offset - info->pos);
1119 	}
1120 
1121 	if (len > 0) {
1122                 memcpy(info->buffer + info->pos, data, len);
1123                 info->pos += len;
1124 	}
1125 }
1126 
1127 static int
1128 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1129 {
1130 	va_list args;
1131 	char buf[81];
1132 	int len;
1133 
1134 	va_start(args, fmt);
1135 	len = vsprintf(buf, fmt, args);
1136 	va_end(args);
1137 
1138 	mptscsih_copy_mem_info(info, buf, len);
1139 	return len;
1140 }
1141 
1142 static int
1143 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1144 {
1145 	struct info_str info;
1146 
1147 	info.buffer	= pbuf;
1148 	info.length	= len;
1149 	info.offset	= offset;
1150 	info.pos	= 0;
1151 
1152 	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1153 	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1154 	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1155 	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1156 
1157 	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1158 }
1159 
1160 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1161 /**
1162  *	mptscsih_proc_info - Return information about MPT adapter
1163  *
1164  *	(linux scsi_host_template.info routine)
1165  *
1166  * 	buffer: if write, user data; if read, buffer for user
1167  * 	length: if write, return length;
1168  * 	offset: if write, 0; if read, the current offset into the buffer from
1169  * 		the previous read.
1170  * 	hostno: scsi host number
1171  *	func:   if write = 1; if read = 0
1172  */
1173 int
1174 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1175 			int length, int func)
1176 {
1177 	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)host->hostdata;
1178 	MPT_ADAPTER	*ioc = hd->ioc;
1179 	int size = 0;
1180 
1181 	if (func) {
1182 		/*
1183 		 * write is not supported
1184 		 */
1185 	} else {
1186 		if (start)
1187 			*start = buffer;
1188 
1189 		size = mptscsih_host_info(ioc, buffer, offset, length);
1190 	}
1191 
1192 	return size;
1193 }
1194 
1195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1196 #define ADD_INDEX_LOG(req_ent)	do { } while(0)
1197 
1198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1199 /**
1200  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1201  *	@SCpnt: Pointer to scsi_cmnd structure
1202  *	@done: Pointer SCSI mid-layer IO completion function
1203  *
1204  *	(linux scsi_host_template.queuecommand routine)
1205  *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1206  *	from a linux scsi_cmnd request and send it to the IOC.
1207  *
1208  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
1209  */
1210 int
1211 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1212 {
1213 	MPT_SCSI_HOST		*hd;
1214 	MPT_FRAME_HDR		*mf;
1215 	SCSIIORequest_t		*pScsiReq;
1216 	VirtDevice		*vdev = SCpnt->device->hostdata;
1217 	int	 lun;
1218 	u32	 datalen;
1219 	u32	 scsictl;
1220 	u32	 scsidir;
1221 	u32	 cmd_len;
1222 	int	 my_idx;
1223 	int	 ii;
1224 
1225 	hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1226 	lun = SCpnt->device->lun;
1227 	SCpnt->scsi_done = done;
1228 
1229 	dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1230 			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1231 
1232 	if (hd->resetPending) {
1233 		dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1234 			(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1235 		return SCSI_MLQUEUE_HOST_BUSY;
1236 	}
1237 
1238 	if ((hd->ioc->bus_type == SPI) &&
1239 	    vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1240 	    mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1241 		SCpnt->result = DID_NO_CONNECT << 16;
1242 		done(SCpnt);
1243 		return 0;
1244 	}
1245 
1246 	/*
1247 	 *  Put together a MPT SCSI request...
1248 	 */
1249 	if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
1250 		dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1251 				hd->ioc->name));
1252 		return SCSI_MLQUEUE_HOST_BUSY;
1253 	}
1254 
1255 	pScsiReq = (SCSIIORequest_t *) mf;
1256 
1257 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1258 
1259 	ADD_INDEX_LOG(my_idx);
1260 
1261 	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1262 	 *    Seems we may receive a buffer (datalen>0) even when there
1263 	 *    will be no data transfer!  GRRRRR...
1264 	 */
1265 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1266 		datalen = SCpnt->request_bufflen;
1267 		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
1268 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1269 		datalen = SCpnt->request_bufflen;
1270 		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
1271 	} else {
1272 		datalen = 0;
1273 		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1274 	}
1275 
1276 	/* Default to untagged. Once a target structure has been allocated,
1277 	 * use the Inquiry data to determine if device supports tagged.
1278 	 */
1279 	if (vdev
1280 	    && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1281 	    && (SCpnt->device->tagged_supported)) {
1282 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1283 	} else {
1284 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1285 	}
1286 
1287 	/* Use the above information to set up the message frame
1288 	 */
1289 	pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
1290 	pScsiReq->Bus = vdev->vtarget->bus_id;
1291 	pScsiReq->ChainOffset = 0;
1292 	if (vdev->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1293 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1294 	else
1295 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1296 	pScsiReq->CDBLength = SCpnt->cmd_len;
1297 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1298 	pScsiReq->Reserved = 0;
1299 	pScsiReq->MsgFlags = mpt_msg_flags();
1300 	pScsiReq->LUN[0] = 0;
1301 	pScsiReq->LUN[1] = lun;
1302 	pScsiReq->LUN[2] = 0;
1303 	pScsiReq->LUN[3] = 0;
1304 	pScsiReq->LUN[4] = 0;
1305 	pScsiReq->LUN[5] = 0;
1306 	pScsiReq->LUN[6] = 0;
1307 	pScsiReq->LUN[7] = 0;
1308 	pScsiReq->Control = cpu_to_le32(scsictl);
1309 
1310 	/*
1311 	 *  Write SCSI CDB into the message
1312 	 */
1313 	cmd_len = SCpnt->cmd_len;
1314 	for (ii=0; ii < cmd_len; ii++)
1315 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1316 
1317 	for (ii=cmd_len; ii < 16; ii++)
1318 		pScsiReq->CDB[ii] = 0;
1319 
1320 	/* DataLength */
1321 	pScsiReq->DataLength = cpu_to_le32(datalen);
1322 
1323 	/* SenseBuffer low address */
1324 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1325 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1326 
1327 	/* Now add the SG list
1328 	 * Always have a SGE even if null length.
1329 	 */
1330 	if (datalen == 0) {
1331 		/* Add a NULL SGE */
1332 		mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1333 			(dma_addr_t) -1);
1334 	} else {
1335 		/* Add a 32 or 64 bit SGE */
1336 		if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1337 			goto fail;
1338 	}
1339 
1340 	hd->ScsiLookup[my_idx] = SCpnt;
1341 	SCpnt->host_scribble = NULL;
1342 
1343 	mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
1344 	dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1345 			hd->ioc->name, SCpnt, mf, my_idx));
1346 	DBG_DUMP_REQUEST_FRAME(mf)
1347 	return 0;
1348 
1349  fail:
1350 	hd->ScsiLookup[my_idx] = NULL;
1351 	mptscsih_freeChainBuffers(hd->ioc, my_idx);
1352 	mpt_free_msg_frame(hd->ioc, mf);
1353 	return SCSI_MLQUEUE_HOST_BUSY;
1354 }
1355 
1356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1357 /*
1358  *	mptscsih_freeChainBuffers - Function to free chain buffers associated
1359  *	with a SCSI IO request
1360  *	@hd: Pointer to the MPT_SCSI_HOST instance
1361  *	@req_idx: Index of the SCSI IO request frame.
1362  *
1363  *	Called if SG chain buffer allocation fails and mptscsih callbacks.
1364  *	No return.
1365  */
1366 static void
1367 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1368 {
1369 	MPT_FRAME_HDR *chain;
1370 	unsigned long flags;
1371 	int chain_idx;
1372 	int next;
1373 
1374 	/* Get the first chain index and reset
1375 	 * tracker state.
1376 	 */
1377 	chain_idx = ioc->ReqToChain[req_idx];
1378 	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1379 
1380 	while (chain_idx != MPT_HOST_NO_CHAIN) {
1381 
1382 		/* Save the next chain buffer index */
1383 		next = ioc->ChainToChain[chain_idx];
1384 
1385 		/* Free this chain buffer and reset
1386 		 * tracker
1387 		 */
1388 		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1389 
1390 		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1391 					+ (chain_idx * ioc->req_sz));
1392 
1393 		spin_lock_irqsave(&ioc->FreeQlock, flags);
1394 		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1395 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1396 
1397 		dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1398 				ioc->name, chain_idx));
1399 
1400 		/* handle next */
1401 		chain_idx = next;
1402 	}
1403 	return;
1404 }
1405 
1406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1407 /*
1408  *	Reset Handling
1409  */
1410 
1411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1412 /*
1413  *	mptscsih_TMHandler - Generic handler for SCSI Task Management.
1414  *	Fall through to mpt_HardResetHandler if: not operational, too many
1415  *	failed TM requests or handshake failure.
1416  *
1417  *	@ioc: Pointer to MPT_ADAPTER structure
1418  *	@type: Task Management type
1419  *	@target: Logical Target ID for reset (if appropriate)
1420  *	@lun: Logical Unit for reset (if appropriate)
1421  *	@ctx2abort: Context for the task to be aborted (if appropriate)
1422  *
1423  *	Remark: Currently invoked from a non-interrupt thread (_bh).
1424  *
1425  *	Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1426  *	will be active.
1427  *
1428  *	Returns 0 for SUCCESS or -1 if FAILED.
1429  */
1430 int
1431 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1432 {
1433 	MPT_ADAPTER	*ioc;
1434 	int		 rc = -1;
1435 	int		 doTask = 1;
1436 	u32		 ioc_raw_state;
1437 	unsigned long	 flags;
1438 
1439 	/* If FW is being reloaded currently, return success to
1440 	 * the calling function.
1441 	 */
1442 	if (hd == NULL)
1443 		return 0;
1444 
1445 	ioc = hd->ioc;
1446 	if (ioc == NULL) {
1447 		printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1448 		return FAILED;
1449 	}
1450 	dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1451 
1452 	// SJR - CHECKME - Can we avoid this here?
1453 	// (mpt_HardResetHandler has this check...)
1454 	spin_lock_irqsave(&ioc->diagLock, flags);
1455 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1456 		spin_unlock_irqrestore(&ioc->diagLock, flags);
1457 		return FAILED;
1458 	}
1459 	spin_unlock_irqrestore(&ioc->diagLock, flags);
1460 
1461 	/*  Wait a fixed amount of time for the TM pending flag to be cleared.
1462 	 *  If we time out and not bus reset, then we return a FAILED status to the caller.
1463 	 *  The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1464 	 *  successful. Otherwise, reload the FW.
1465 	 */
1466 	if (mptscsih_tm_pending_wait(hd) == FAILED) {
1467 		if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1468 			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
1469 			   "Timed out waiting for last TM (%d) to complete! \n",
1470 			   hd->ioc->name, hd->tmPending));
1471 			return FAILED;
1472 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1473 			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
1474 			   "Timed out waiting for last TM (%d) to complete! \n",
1475 			   hd->ioc->name, hd->tmPending));
1476 			return FAILED;
1477 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1478 			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1479 			   "Timed out waiting for last TM (%d) to complete! \n",
1480 			   hd->ioc->name, hd->tmPending));
1481 			if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1482 				return FAILED;
1483 
1484 			doTask = 0;
1485 		}
1486 	} else {
1487 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1488 		hd->tmPending |=  (1 << type);
1489 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1490 	}
1491 
1492 	/* Is operational?
1493 	 */
1494 	ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1495 
1496 #ifdef MPT_DEBUG_RESET
1497 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1498 		printk(MYIOC_s_WARN_FMT
1499 			"TM Handler: IOC Not operational(0x%x)!\n",
1500 			hd->ioc->name, ioc_raw_state);
1501 	}
1502 #endif
1503 
1504 	if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1505 				&& !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1506 
1507 		/* Isse the Task Mgmt request.
1508 		 */
1509 		if (hd->hard_resets < -1)
1510 			hd->hard_resets++;
1511 		rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1512 		if (rc) {
1513 			printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1514 		} else {
1515 			dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1516 		}
1517 	}
1518 
1519 	/* Only fall through to the HRH if this is a bus reset
1520 	 */
1521 	if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
1522 		ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
1523 		dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1524 			 hd->ioc->name));
1525 		rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1526 	}
1527 
1528 	dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1529 
1530 	return rc;
1531 }
1532 
1533 
1534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1535 /*
1536  *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
1537  *	@hd: Pointer to MPT_SCSI_HOST structure
1538  *	@type: Task Management type
1539  *	@target: Logical Target ID for reset (if appropriate)
1540  *	@lun: Logical Unit for reset (if appropriate)
1541  *	@ctx2abort: Context for the task to be aborted (if appropriate)
1542  *
1543  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1544  *	or a non-interrupt thread.  In the former, must not call schedule().
1545  *
1546  *	Not all fields are meaningfull for all task types.
1547  *
1548  *	Returns 0 for SUCCESS, -999 for "no msg frames",
1549  *	else other non-zero value returned.
1550  */
1551 static int
1552 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1553 {
1554 	MPT_FRAME_HDR	*mf;
1555 	SCSITaskMgmt_t	*pScsiTm;
1556 	int		 ii;
1557 	int		 retval;
1558 
1559 	/* Return Fail to calling function if no message frames available.
1560 	 */
1561 	if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
1562 		dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1563 				hd->ioc->name));
1564 		return FAILED;
1565 	}
1566 	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
1567 			hd->ioc->name, mf));
1568 
1569 	/* Format the Request
1570 	 */
1571 	pScsiTm = (SCSITaskMgmt_t *) mf;
1572 	pScsiTm->TargetID = target;
1573 	pScsiTm->Bus = channel;
1574 	pScsiTm->ChainOffset = 0;
1575 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1576 
1577 	pScsiTm->Reserved = 0;
1578 	pScsiTm->TaskType = type;
1579 	pScsiTm->Reserved1 = 0;
1580 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1581                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1582 
1583 	for (ii= 0; ii < 8; ii++) {
1584 		pScsiTm->LUN[ii] = 0;
1585 	}
1586 	pScsiTm->LUN[1] = lun;
1587 
1588 	for (ii=0; ii < 7; ii++)
1589 		pScsiTm->Reserved2[ii] = 0;
1590 
1591 	pScsiTm->TaskMsgContext = ctx2abort;
1592 
1593 	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
1594 			hd->ioc->name, ctx2abort, type));
1595 
1596 	DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1597 
1598 	if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1599 		sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
1600 		CAN_SLEEP)) != 0) {
1601 		dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
1602 			" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1603 			hd->ioc, mf));
1604 		mpt_free_msg_frame(hd->ioc, mf);
1605 		return retval;
1606 	}
1607 
1608 	if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1609 		dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
1610 			" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1611 			hd->ioc, mf));
1612 		mpt_free_msg_frame(hd->ioc, mf);
1613 		dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1614 			 hd->ioc->name));
1615 		retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1616 	}
1617 
1618 	return retval;
1619 }
1620 
1621 static int
1622 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1623 {
1624 	switch (ioc->bus_type) {
1625 	case FC:
1626 		return 40;
1627 	case SAS:
1628 		return 10;
1629 	case SPI:
1630 	default:
1631 		return 2;
1632 	}
1633 }
1634 
1635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1636 /**
1637  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1638  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1639  *
1640  *	(linux scsi_host_template.eh_abort_handler routine)
1641  *
1642  *	Returns SUCCESS or FAILED.
1643  */
1644 int
1645 mptscsih_abort(struct scsi_cmnd * SCpnt)
1646 {
1647 	MPT_SCSI_HOST	*hd;
1648 	MPT_ADAPTER	*ioc;
1649 	MPT_FRAME_HDR	*mf;
1650 	u32		 ctx2abort;
1651 	int		 scpnt_idx;
1652 	int		 retval;
1653 	VirtDevice	 *vdev;
1654 
1655 	/* If we can't locate our host adapter structure, return FAILED status.
1656 	 */
1657 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1658 		SCpnt->result = DID_RESET << 16;
1659 		SCpnt->scsi_done(SCpnt);
1660 		dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1661 			   "Can't locate host! (sc=%p)\n",
1662 			   SCpnt));
1663 		return FAILED;
1664 	}
1665 
1666 	ioc = hd->ioc;
1667 	if (hd->resetPending) {
1668 		return FAILED;
1669 	}
1670 
1671 	if (hd->timeouts < -1)
1672 		hd->timeouts++;
1673 
1674 	/* Find this command
1675 	 */
1676 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1677 		/* Cmd not found in ScsiLookup.
1678 		 * Do OS callback.
1679 		 */
1680 		SCpnt->result = DID_RESET << 16;
1681 		dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1682 			   "Command not in the active list! (sc=%p)\n",
1683 			   hd->ioc->name, SCpnt));
1684 		return SUCCESS;
1685 	}
1686 
1687 	printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1688 	       hd->ioc->name, SCpnt);
1689 	scsi_print_command(SCpnt);
1690 
1691 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
1692 	 * (the IO to be ABORT'd)
1693 	 *
1694 	 * NOTE: Since we do not byteswap MsgContext, we do not
1695 	 *	 swap it here either.  It is an opaque cookie to
1696 	 *	 the controller, so it does not matter. -DaveM
1697 	 */
1698 	mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
1699 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1700 
1701 	hd->abortSCpnt = SCpnt;
1702 
1703 	vdev = SCpnt->device->hostdata;
1704 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1705 		vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1706 		ctx2abort, mptscsih_get_tm_timeout(ioc));
1707 
1708 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1709 		hd->ioc->name,
1710 		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1711 
1712 	if (retval == 0)
1713 		return SUCCESS;
1714 
1715 	if(retval != FAILED ) {
1716 		hd->tmPending = 0;
1717 		hd->tmState = TM_STATE_NONE;
1718 	}
1719 	return FAILED;
1720 }
1721 
1722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1723 /**
1724  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
1725  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1726  *
1727  *	(linux scsi_host_template.eh_dev_reset_handler routine)
1728  *
1729  *	Returns SUCCESS or FAILED.
1730  */
1731 int
1732 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1733 {
1734 	MPT_SCSI_HOST	*hd;
1735 	int		 retval;
1736 	VirtDevice	 *vdev;
1737 
1738 	/* If we can't locate our host adapter structure, return FAILED status.
1739 	 */
1740 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1741 		dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1742 			   "Can't locate host! (sc=%p)\n",
1743 			   SCpnt));
1744 		return FAILED;
1745 	}
1746 
1747 	if (hd->resetPending)
1748 		return FAILED;
1749 
1750 	printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1751 	       hd->ioc->name, SCpnt);
1752 	scsi_print_command(SCpnt);
1753 
1754 	vdev = SCpnt->device->hostdata;
1755 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1756 		vdev->vtarget->bus_id, vdev->vtarget->target_id,
1757 		0, 0, mptscsih_get_tm_timeout(hd->ioc));
1758 
1759 	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1760 		hd->ioc->name,
1761 		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1762 
1763 	if (retval == 0)
1764 		return SUCCESS;
1765 
1766 	if(retval != FAILED ) {
1767 		hd->tmPending = 0;
1768 		hd->tmState = TM_STATE_NONE;
1769 	}
1770 	return FAILED;
1771 }
1772 
1773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1774 /**
1775  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
1776  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1777  *
1778  *	(linux scsi_host_template.eh_bus_reset_handler routine)
1779  *
1780  *	Returns SUCCESS or FAILED.
1781  */
1782 int
1783 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1784 {
1785 	MPT_SCSI_HOST	*hd;
1786 	int		 retval;
1787 	VirtDevice	 *vdev;
1788 
1789 	/* If we can't locate our host adapter structure, return FAILED status.
1790 	 */
1791 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1792 		dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1793 			   "Can't locate host! (sc=%p)\n",
1794 			   SCpnt ) );
1795 		return FAILED;
1796 	}
1797 
1798 	printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1799 	       hd->ioc->name, SCpnt);
1800 	scsi_print_command(SCpnt);
1801 
1802 	if (hd->timeouts < -1)
1803 		hd->timeouts++;
1804 
1805 	vdev = SCpnt->device->hostdata;
1806 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1807 		vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1808 
1809 	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1810 		hd->ioc->name,
1811 		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1812 
1813 	if (retval == 0)
1814 		return SUCCESS;
1815 
1816 	if(retval != FAILED ) {
1817 		hd->tmPending = 0;
1818 		hd->tmState = TM_STATE_NONE;
1819 	}
1820 	return FAILED;
1821 }
1822 
1823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1824 /**
1825  *	mptscsih_host_reset - Perform a SCSI host adapter RESET!
1826  *	new_eh variant
1827  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1828  *
1829  *	(linux scsi_host_template.eh_host_reset_handler routine)
1830  *
1831  *	Returns SUCCESS or FAILED.
1832  */
1833 int
1834 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1835 {
1836 	MPT_SCSI_HOST *  hd;
1837 	int              status = SUCCESS;
1838 
1839 	/*  If we can't locate the host to reset, then we failed. */
1840 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1841 		dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1842 			     "Can't locate host! (sc=%p)\n",
1843 			     SCpnt ) );
1844 		return FAILED;
1845 	}
1846 
1847 	printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
1848 	       hd->ioc->name, SCpnt);
1849 
1850 	/*  If our attempts to reset the host failed, then return a failed
1851 	 *  status.  The host will be taken off line by the SCSI mid-layer.
1852 	 */
1853 	if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1854 		status = FAILED;
1855 	} else {
1856 		/*  Make sure TM pending is cleared and TM state is set to
1857 		 *  NONE.
1858 		 */
1859 		hd->tmPending = 0;
1860 		hd->tmState = TM_STATE_NONE;
1861 	}
1862 
1863 	dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
1864 		     "Status = %s\n",
1865 		     (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1866 
1867 	return status;
1868 }
1869 
1870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1871 /**
1872  *	mptscsih_tm_pending_wait - wait for pending task management request to
1873  *		complete.
1874  *	@hd: Pointer to MPT host structure.
1875  *
1876  *	Returns {SUCCESS,FAILED}.
1877  */
1878 static int
1879 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1880 {
1881 	unsigned long  flags;
1882 	int            loop_count = 4 * 10;  /* Wait 10 seconds */
1883 	int            status = FAILED;
1884 
1885 	do {
1886 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1887 		if (hd->tmState == TM_STATE_NONE) {
1888 			hd->tmState = TM_STATE_IN_PROGRESS;
1889 			hd->tmPending = 1;
1890 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1891 			status = SUCCESS;
1892 			break;
1893 		}
1894 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1895 		msleep(250);
1896 	} while (--loop_count);
1897 
1898 	return status;
1899 }
1900 
1901 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1902 /**
1903  *	mptscsih_tm_wait_for_completion - wait for completion of TM task
1904  *	@hd: Pointer to MPT host structure.
1905  *
1906  *	Returns {SUCCESS,FAILED}.
1907  */
1908 static int
1909 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1910 {
1911 	unsigned long  flags;
1912 	int            loop_count = 4 * timeout;
1913 	int            status = FAILED;
1914 
1915 	do {
1916 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1917 		if(hd->tmPending == 0) {
1918 			status = SUCCESS;
1919  			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1920 			break;
1921 		}
1922 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1923 		msleep_interruptible(250);
1924 	} while (--loop_count);
1925 
1926 	return status;
1927 }
1928 
1929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1930 static void
1931 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
1932 {
1933 	char *desc;
1934 
1935 	switch (response_code) {
1936 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
1937 		desc = "The task completed.";
1938 		break;
1939 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
1940 		desc = "The IOC received an invalid frame status.";
1941 		break;
1942 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
1943 		desc = "The task type is not supported.";
1944 		break;
1945 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
1946 		desc = "The requested task failed.";
1947 		break;
1948 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
1949 		desc = "The task completed successfully.";
1950 		break;
1951 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
1952 		desc = "The LUN request is invalid.";
1953 		break;
1954 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
1955 		desc = "The task is in the IOC queue and has not been sent to target.";
1956 		break;
1957 	default:
1958 		desc = "unknown";
1959 		break;
1960 	}
1961 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
1962 		ioc->name, response_code, desc);
1963 }
1964 
1965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1966 /**
1967  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
1968  *	@ioc: Pointer to MPT_ADAPTER structure
1969  *	@mf: Pointer to SCSI task mgmt request frame
1970  *	@mr: Pointer to SCSI task mgmt reply frame
1971  *
1972  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
1973  *	of any SCSI task management request.
1974  *	This routine is registered with the MPT (base) driver at driver
1975  *	load/init time via the mpt_register() API call.
1976  *
1977  *	Returns 1 indicating alloc'd request frame ptr should be freed.
1978  */
1979 int
1980 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1981 {
1982 	SCSITaskMgmtReply_t	*pScsiTmReply;
1983 	SCSITaskMgmt_t		*pScsiTmReq;
1984 	MPT_SCSI_HOST		*hd;
1985 	unsigned long		 flags;
1986 	u16			 iocstatus;
1987 	u8			 tmType;
1988 
1989 	dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
1990 			ioc->name, mf, mr));
1991 	if (ioc->sh) {
1992 		/* Depending on the thread, a timer is activated for
1993 		 * the TM request.  Delete this timer on completion of TM.
1994 		 * Decrement count of outstanding TM requests.
1995 		 */
1996 		hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
1997 	} else {
1998 		dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
1999 			ioc->name));
2000 		return 1;
2001 	}
2002 
2003 	if (mr == NULL) {
2004 		dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2005 			ioc->name, mf));
2006 		return 1;
2007 	} else {
2008 		pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2009 		pScsiTmReq = (SCSITaskMgmt_t*)mf;
2010 
2011 		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2012 		tmType = pScsiTmReq->TaskType;
2013 
2014 		if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2015 		    pScsiTmReply->ResponseCode)
2016 			mptscsih_taskmgmt_response_code(ioc,
2017 			    pScsiTmReply->ResponseCode);
2018 
2019 		dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
2020 				ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2021 		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2022 
2023 		iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2024 		dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2025 			ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2026 		/* Error?  (anything non-zero?) */
2027 		if (iocstatus) {
2028 
2029 			/* clear flags and continue.
2030 			 */
2031 			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2032 				hd->abortSCpnt = NULL;
2033 
2034 			/* If an internal command is present
2035 			 * or the TM failed - reload the FW.
2036 			 * FC FW may respond FAILED to an ABORT
2037 			 */
2038 			if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2039 				if ((hd->cmdPtr) ||
2040 				    (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2041 					if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2042 						printk((KERN_WARNING
2043 							" Firmware Reload FAILED!!\n"));
2044 					}
2045 				}
2046 			}
2047 		} else {
2048 			dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2049 
2050 			hd->abortSCpnt = NULL;
2051 
2052 		}
2053 	}
2054 
2055 	spin_lock_irqsave(&ioc->FreeQlock, flags);
2056 	hd->tmPending = 0;
2057 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2058 	hd->tmState = TM_STATE_NONE;
2059 
2060 	return 1;
2061 }
2062 
2063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2064 /*
2065  *	This is anyones guess quite frankly.
2066  */
2067 int
2068 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2069 		sector_t capacity, int geom[])
2070 {
2071 	int		heads;
2072 	int		sectors;
2073 	sector_t	cylinders;
2074 	ulong 		dummy;
2075 
2076 	heads = 64;
2077 	sectors = 32;
2078 
2079 	dummy = heads * sectors;
2080 	cylinders = capacity;
2081 	sector_div(cylinders,dummy);
2082 
2083 	/*
2084 	 * Handle extended translation size for logical drives
2085 	 * > 1Gb
2086 	 */
2087 	if ((ulong)capacity >= 0x200000) {
2088 		heads = 255;
2089 		sectors = 63;
2090 		dummy = heads * sectors;
2091 		cylinders = capacity;
2092 		sector_div(cylinders,dummy);
2093 	}
2094 
2095 	/* return result */
2096 	geom[0] = heads;
2097 	geom[1] = sectors;
2098 	geom[2] = cylinders;
2099 
2100 	dprintk((KERN_NOTICE
2101 		": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2102 		sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2103 
2104 	return 0;
2105 }
2106 
2107 /* Search IOC page 3 to determine if this is hidden physical disk
2108  *
2109  */
2110 int
2111 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
2112 {
2113 	int i;
2114 
2115 	if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
2116 		return 0;
2117 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2118                 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2119                         return 1;
2120         }
2121         return 0;
2122 }
2123 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2124 
2125 int
2126 mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2127 {
2128 	int i;
2129 
2130 	if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2131 		return -ENXIO;
2132 
2133 	for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2134 		if (physdiskid ==
2135 		    hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2136 			return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2137 	}
2138 
2139 	return -ENXIO;
2140 }
2141 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2142 
2143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2144 /*
2145  *	OS entry point to allow host driver to alloc memory
2146  *	for each scsi target. Called once per device the bus scan.
2147  *	Return non-zero if allocation fails.
2148  */
2149 int
2150 mptscsih_target_alloc(struct scsi_target *starget)
2151 {
2152 	VirtTarget		*vtarget;
2153 
2154 	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2155 	if (!vtarget)
2156 		return -ENOMEM;
2157 	starget->hostdata = vtarget;
2158 	vtarget->starget = starget;
2159 	return 0;
2160 }
2161 
2162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2163 /*
2164  *	OS entry point to allow host driver to alloc memory
2165  *	for each scsi device. Called once per device the bus scan.
2166  *	Return non-zero if allocation fails.
2167  */
2168 int
2169 mptscsih_slave_alloc(struct scsi_device *sdev)
2170 {
2171 	struct Scsi_Host	*host = sdev->host;
2172 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
2173 	VirtTarget		*vtarget;
2174 	VirtDevice		*vdev;
2175 	struct scsi_target 	*starget;
2176 
2177 	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2178 	if (!vdev) {
2179 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2180 				hd->ioc->name, sizeof(VirtDevice));
2181 		return -ENOMEM;
2182 	}
2183 
2184 	vdev->lun = sdev->lun;
2185 	sdev->hostdata = vdev;
2186 
2187 	starget = scsi_target(sdev);
2188 	vtarget = starget->hostdata;
2189 
2190 	vdev->vtarget = vtarget;
2191 
2192 	if (vtarget->num_luns == 0) {
2193 		hd->Targets[sdev->id] = vtarget;
2194 		vtarget->ioc_id = hd->ioc->id;
2195 		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
2196 		vtarget->target_id = sdev->id;
2197 		vtarget->bus_id = sdev->channel;
2198 		if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2199 		    hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2200 			vtarget->raidVolume = 1;
2201 			ddvtprintk((KERN_INFO
2202 				    "RAID Volume @ id %d\n", sdev->id));
2203 		}
2204 	}
2205 	vtarget->num_luns++;
2206 	return 0;
2207 }
2208 
2209 /*
2210  *	OS entry point to allow for host driver to free allocated memory
2211  *	Called if no device present or device being unloaded
2212  */
2213 void
2214 mptscsih_target_destroy(struct scsi_target *starget)
2215 {
2216 	if (starget->hostdata)
2217 		kfree(starget->hostdata);
2218 	starget->hostdata = NULL;
2219 }
2220 
2221 /*
2222  *	OS entry point to allow for host driver to free allocated memory
2223  *	Called if no device present or device being unloaded
2224  */
2225 void
2226 mptscsih_slave_destroy(struct scsi_device *sdev)
2227 {
2228 	struct Scsi_Host	*host = sdev->host;
2229 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
2230 	VirtTarget		*vtarget;
2231 	VirtDevice		*vdevice;
2232 	struct scsi_target 	*starget;
2233 
2234 	starget = scsi_target(sdev);
2235 	vtarget = starget->hostdata;
2236 	vdevice = sdev->hostdata;
2237 
2238 	mptscsih_search_running_cmds(hd, vdevice);
2239 	vtarget->luns[0] &= ~(1 << vdevice->lun);
2240 	vtarget->num_luns--;
2241 	if (vtarget->num_luns == 0) {
2242 		hd->Targets[sdev->id] = NULL;
2243 	}
2244 	mptscsih_synchronize_cache(hd, vdevice);
2245 	kfree(vdevice);
2246 	sdev->hostdata = NULL;
2247 }
2248 
2249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2250 /*
2251  *	mptscsih_change_queue_depth - This function will set a devices queue depth
2252  *	@sdev: per scsi_device pointer
2253  *	@qdepth: requested queue depth
2254  *
2255  *	Adding support for new 'change_queue_depth' api.
2256 */
2257 int
2258 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2259 {
2260 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
2261 	VirtTarget 		*vtarget;
2262 	struct scsi_target 	*starget;
2263 	int			max_depth;
2264 	int			tagged;
2265 
2266 	starget = scsi_target(sdev);
2267 	vtarget = starget->hostdata;
2268 
2269 	if (hd->ioc->bus_type == SPI) {
2270 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2271 			max_depth = 1;
2272 		else if (sdev->type == TYPE_DISK &&
2273 			 vtarget->minSyncFactor <= MPT_ULTRA160)
2274 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2275 		else
2276 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2277 	} else
2278 		max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2279 
2280 	if (qdepth > max_depth)
2281 		qdepth = max_depth;
2282 	if (qdepth == 1)
2283 		tagged = 0;
2284 	else
2285 		tagged = MSG_SIMPLE_TAG;
2286 
2287 	scsi_adjust_queue_depth(sdev, tagged, qdepth);
2288 	return sdev->queue_depth;
2289 }
2290 
2291 /*
2292  *	OS entry point to adjust the queue_depths on a per-device basis.
2293  *	Called once per device the bus scan. Use it to force the queue_depth
2294  *	member to 1 if a device does not support Q tags.
2295  *	Return non-zero if fails.
2296  */
2297 int
2298 mptscsih_slave_configure(struct scsi_device *sdev)
2299 {
2300 	struct Scsi_Host	*sh = sdev->host;
2301 	VirtTarget		*vtarget;
2302 	VirtDevice		*vdevice;
2303 	struct scsi_target 	*starget;
2304 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sh->hostdata;
2305 	int			indexed_lun, lun_index;
2306 
2307 	starget = scsi_target(sdev);
2308 	vtarget = starget->hostdata;
2309 	vdevice = sdev->hostdata;
2310 
2311 	dsprintk((MYIOC_s_INFO_FMT
2312 		"device @ %p, id=%d, LUN=%d, channel=%d\n",
2313 		hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
2314 	if (hd->ioc->bus_type == SPI)
2315 		dsprintk((MYIOC_s_INFO_FMT
2316 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
2317 		    hd->ioc->name, sdev->sdtr, sdev->wdtr,
2318 		    sdev->ppr, sdev->inquiry_len));
2319 
2320 	if (sdev->id > sh->max_id) {
2321 		/* error case, should never happen */
2322 		scsi_adjust_queue_depth(sdev, 0, 1);
2323 		goto slave_configure_exit;
2324 	}
2325 
2326 	vdevice->configured_lun=1;
2327 	lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
2328 	indexed_lun = (vdevice->lun % 32);
2329 	vtarget->luns[lun_index] |= (1 << indexed_lun);
2330 	mptscsih_initTarget(hd, vtarget, sdev);
2331 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2332 
2333 	dsprintk((MYIOC_s_INFO_FMT
2334 		"Queue depth=%d, tflags=%x\n",
2335 		hd->ioc->name, sdev->queue_depth, vtarget->tflags));
2336 
2337 	if (hd->ioc->bus_type == SPI)
2338 		dsprintk((MYIOC_s_INFO_FMT
2339 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2340 		    hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2341 		    vtarget->minSyncFactor));
2342 
2343 slave_configure_exit:
2344 
2345 	dsprintk((MYIOC_s_INFO_FMT
2346 		"tagged %d, simple %d, ordered %d\n",
2347 		hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
2348 		sdev->ordered_tags));
2349 
2350 	return 0;
2351 }
2352 
2353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2354 /*
2355  *  Private routines...
2356  */
2357 
2358 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2359 /* Utility function to copy sense data from the scsi_cmnd buffer
2360  * to the FC and SCSI target structures.
2361  *
2362  */
2363 static void
2364 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2365 {
2366 	VirtDevice	*vdev;
2367 	SCSIIORequest_t	*pReq;
2368 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2369 
2370 	/* Get target structure
2371 	 */
2372 	pReq = (SCSIIORequest_t *) mf;
2373 	vdev = sc->device->hostdata;
2374 
2375 	if (sense_count) {
2376 		u8 *sense_data;
2377 		int req_index;
2378 
2379 		/* Copy the sense received into the scsi command block. */
2380 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2381 		sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2382 		memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2383 
2384 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
2385 		 */
2386 		if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2387 			if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
2388 				int idx;
2389 				MPT_ADAPTER *ioc = hd->ioc;
2390 
2391 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2392 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2393 				ioc->events[idx].eventContext = ioc->eventContext;
2394 
2395 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2396 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2397 					(sc->device->channel << 8) || sc->device->id;
2398 
2399 				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2400 
2401 				ioc->eventContext++;
2402 			}
2403 		}
2404 	} else {
2405 		dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2406 				hd->ioc->name));
2407 	}
2408 }
2409 
2410 static u32
2411 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2412 {
2413 	MPT_SCSI_HOST *hd;
2414 	int i;
2415 
2416 	hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2417 
2418 	for (i = 0; i < hd->ioc->req_depth; i++) {
2419 		if (hd->ScsiLookup[i] == sc) {
2420 			return i;
2421 		}
2422 	}
2423 
2424 	return -1;
2425 }
2426 
2427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2428 int
2429 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2430 {
2431 	MPT_SCSI_HOST	*hd;
2432 	unsigned long	 flags;
2433 	int 		ii;
2434 
2435 	dtmprintk((KERN_WARNING MYNAM
2436 			": IOC %s_reset routed to SCSI host driver!\n",
2437 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2438 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2439 
2440 	/* If a FW reload request arrives after base installed but
2441 	 * before all scsi hosts have been attached, then an alt_ioc
2442 	 * may have a NULL sh pointer.
2443 	 */
2444 	if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2445 		return 0;
2446 	else
2447 		hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2448 
2449 	if (reset_phase == MPT_IOC_SETUP_RESET) {
2450 		dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2451 
2452 		/* Clean Up:
2453 		 * 1. Set Hard Reset Pending Flag
2454 		 * All new commands go to doneQ
2455 		 */
2456 		hd->resetPending = 1;
2457 
2458 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
2459 		dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2460 
2461 		/* 2. Flush running commands
2462 		 *	Clean ScsiLookup (and associated memory)
2463 		 *	AND clean mytaskQ
2464 		 */
2465 
2466 		/* 2b. Reply to OS all known outstanding I/O commands.
2467 		 */
2468 		mptscsih_flush_running_cmds(hd);
2469 
2470 		/* 2c. If there was an internal command that
2471 		 * has not completed, configuration or io request,
2472 		 * free these resources.
2473 		 */
2474 		if (hd->cmdPtr) {
2475 			del_timer(&hd->timer);
2476 			mpt_free_msg_frame(ioc, hd->cmdPtr);
2477 		}
2478 
2479 		dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2480 
2481 	} else {
2482 		dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2483 
2484 		/* Once a FW reload begins, all new OS commands are
2485 		 * redirected to the doneQ w/ a reset status.
2486 		 * Init all control structures.
2487 		 */
2488 
2489 		/* ScsiLookup initialization
2490 		 */
2491 		for (ii=0; ii < hd->ioc->req_depth; ii++)
2492 			hd->ScsiLookup[ii] = NULL;
2493 
2494 		/* 2. Chain Buffer initialization
2495 		 */
2496 
2497 		/* 4. Renegotiate to all devices, if SPI
2498 		 */
2499 
2500 		/* 5. Enable new commands to be posted
2501 		 */
2502 		spin_lock_irqsave(&ioc->FreeQlock, flags);
2503 		hd->tmPending = 0;
2504 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2505 		hd->resetPending = 0;
2506 		hd->tmState = TM_STATE_NONE;
2507 
2508 		/* 6. If there was an internal command,
2509 		 * wake this process up.
2510 		 */
2511 		if (hd->cmdPtr) {
2512 			/*
2513 			 * Wake up the original calling thread
2514 			 */
2515 			hd->pLocal = &hd->localReply;
2516 			hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2517 			hd->scandv_wait_done = 1;
2518 			wake_up(&hd->scandv_waitq);
2519 			hd->cmdPtr = NULL;
2520 		}
2521 
2522 		/* 7. FC: Rescan for blocked rports which might have returned.
2523 		 */
2524 		else if (ioc->bus_type == FC) {
2525 			int work_count;
2526 			unsigned long flags;
2527 
2528 			spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2529 			work_count = ++ioc->fc_rescan_work_count;
2530 			spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2531 			if (work_count == 1)
2532 				schedule_work(&ioc->fc_rescan_work);
2533 		}
2534 		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2535 
2536 	}
2537 
2538 	return 1;		/* currently means nothing really */
2539 }
2540 
2541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2542 int
2543 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2544 {
2545 	MPT_SCSI_HOST *hd;
2546 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2547 	int work_count;
2548 	unsigned long flags;
2549 
2550 	devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2551 			ioc->name, event));
2552 
2553 	if (ioc->sh == NULL ||
2554 		((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2555 		return 1;
2556 
2557 	switch (event) {
2558 	case MPI_EVENT_UNIT_ATTENTION:			/* 03 */
2559 		/* FIXME! */
2560 		break;
2561 	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
2562 	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
2563 		if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2564 			hd->soft_resets++;
2565 		break;
2566 	case MPI_EVENT_LOGOUT:				/* 09 */
2567 		/* FIXME! */
2568 		break;
2569 
2570 	case MPI_EVENT_RESCAN:				/* 06 */
2571 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2572 		work_count = ++ioc->fc_rescan_work_count;
2573 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2574 		if (work_count == 1)
2575 			schedule_work(&ioc->fc_rescan_work);
2576 		break;
2577 
2578 		/*
2579 		 *  CHECKME! Don't think we need to do
2580 		 *  anything for these, but...
2581 		 */
2582 	case MPI_EVENT_LINK_STATUS_CHANGE:		/* 07 */
2583 	case MPI_EVENT_LOOP_STATE_CHANGE:		/* 08 */
2584 		/*
2585 		 *  CHECKME!  Falling thru...
2586 		 */
2587 		break;
2588 
2589 	case MPI_EVENT_INTEGRATED_RAID:			/* 0B */
2590 		break;
2591 
2592 	case MPI_EVENT_NONE:				/* 00 */
2593 	case MPI_EVENT_LOG_DATA:			/* 01 */
2594 	case MPI_EVENT_STATE_CHANGE:			/* 02 */
2595 	case MPI_EVENT_EVENT_CHANGE:			/* 0A */
2596 	default:
2597 		dprintk((KERN_INFO "  Ignoring event (=%02Xh)\n", event));
2598 		break;
2599 	}
2600 
2601 	return 1;		/* currently means nothing really */
2602 }
2603 
2604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2605 /*
2606  *	mptscsih_initTarget - Target, LUN alloc/free functionality.
2607  *	@hd: Pointer to MPT_SCSI_HOST structure
2608  *	@vtarget: per target private data
2609  *	@sdev: SCSI device
2610  *
2611  *	NOTE: It's only SAFE to call this routine if data points to
2612  *	sane & valid STANDARD INQUIRY data!
2613  *
2614  *	Allocate and initialize memory for this target.
2615  *	Save inquiry data.
2616  *
2617  */
2618 static void
2619 mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2620 		    struct scsi_device *sdev)
2621 {
2622 	dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2623 		hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
2624 
2625 	/* Is LUN supported? If so, upper 2 bits will be 0
2626 	* in first byte of inquiry data.
2627 	*/
2628 	if (sdev->inq_periph_qual != 0)
2629 		return;
2630 
2631 	if (vtarget == NULL)
2632 		return;
2633 
2634 	vtarget->type = sdev->type;
2635 
2636 	if (hd->ioc->bus_type != SPI)
2637 		return;
2638 
2639 	if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2640 		/* Treat all Processors as SAF-TE if
2641 		 * command line option is set */
2642 		vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2643 		mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2644 	}else if ((sdev->type == TYPE_PROCESSOR) &&
2645 		!(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2646 		if (sdev->inquiry_len > 49 ) {
2647 			if (sdev->inquiry[44] == 'S' &&
2648 			    sdev->inquiry[45] == 'A' &&
2649 			    sdev->inquiry[46] == 'F' &&
2650 			    sdev->inquiry[47] == '-' &&
2651 			    sdev->inquiry[48] == 'T' &&
2652 			    sdev->inquiry[49] == 'E' ) {
2653 				vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2654 				mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2655 			}
2656 		}
2657 	}
2658 	mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2659 }
2660 
2661 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2662 /*
2663  *  Update the target negotiation parameters based on the
2664  *  the Inquiry data, adapter capabilities, and NVRAM settings.
2665  *
2666  */
2667 static void
2668 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2669 			    struct scsi_device *sdev)
2670 {
2671 	SpiCfgData *pspi_data = &hd->ioc->spi_data;
2672 	int  id = (int) target->target_id;
2673 	int  nvram;
2674 	u8 width = MPT_NARROW;
2675 	u8 factor = MPT_ASYNC;
2676 	u8 offset = 0;
2677 	u8 nfactor;
2678 	u8 noQas = 1;
2679 
2680 	target->negoFlags = pspi_data->noQas;
2681 
2682 	/* noQas == 0 => device supports QAS. */
2683 
2684 	if (sdev->scsi_level < SCSI_2) {
2685 		width = 0;
2686 		factor = MPT_ULTRA2;
2687 		offset = pspi_data->maxSyncOffset;
2688 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2689 	} else {
2690 		if (scsi_device_wide(sdev)) {
2691 			width = 1;
2692 		}
2693 
2694 		if (scsi_device_sync(sdev)) {
2695 			factor = pspi_data->minSyncFactor;
2696 			if (!scsi_device_dt(sdev))
2697 					factor = MPT_ULTRA2;
2698 			else {
2699 				if (!scsi_device_ius(sdev) &&
2700 				    !scsi_device_qas(sdev))
2701 					factor = MPT_ULTRA160;
2702 				else {
2703 					factor = MPT_ULTRA320;
2704 					if (scsi_device_qas(sdev)) {
2705 						ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2706 						noQas = 0;
2707 					}
2708 					if (sdev->type == TYPE_TAPE &&
2709 					    scsi_device_ius(sdev))
2710 						target->negoFlags |= MPT_TAPE_NEGO_IDP;
2711 				}
2712 			}
2713 			offset = pspi_data->maxSyncOffset;
2714 
2715 			/* If RAID, never disable QAS
2716 			 * else if non RAID, do not disable
2717 			 *   QAS if bit 1 is set
2718 			 * bit 1 QAS support, non-raid only
2719 			 * bit 0 IU support
2720 			 */
2721 			if (target->raidVolume == 1) {
2722 				noQas = 0;
2723 			}
2724 		} else {
2725 			factor = MPT_ASYNC;
2726 			offset = 0;
2727 		}
2728 	}
2729 
2730 	if (!sdev->tagged_supported) {
2731 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2732 	}
2733 
2734 	/* Update tflags based on NVRAM settings. (SCSI only)
2735 	 */
2736 	if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2737 		nvram = pspi_data->nvram[id];
2738 		nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2739 
2740 		if (width)
2741 			width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2742 
2743 		if (offset > 0) {
2744 			/* Ensure factor is set to the
2745 			 * maximum of: adapter, nvram, inquiry
2746 			 */
2747 			if (nfactor) {
2748 				if (nfactor < pspi_data->minSyncFactor )
2749 					nfactor = pspi_data->minSyncFactor;
2750 
2751 				factor = max(factor, nfactor);
2752 				if (factor == MPT_ASYNC)
2753 					offset = 0;
2754 			} else {
2755 				offset = 0;
2756 				factor = MPT_ASYNC;
2757 		}
2758 		} else {
2759 			factor = MPT_ASYNC;
2760 		}
2761 	}
2762 
2763 	/* Make sure data is consistent
2764 	 */
2765 	if ((!width) && (factor < MPT_ULTRA2)) {
2766 		factor = MPT_ULTRA2;
2767 	}
2768 
2769 	/* Save the data to the target structure.
2770 	 */
2771 	target->minSyncFactor = factor;
2772 	target->maxOffset = offset;
2773 	target->maxWidth = width;
2774 
2775 	target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2776 
2777 	/* Disable unused features.
2778 	 */
2779 	if (!width)
2780 		target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2781 
2782 	if (!offset)
2783 		target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2784 
2785 	if ( factor > MPT_ULTRA320 )
2786 		noQas = 0;
2787 
2788 	if (noQas && (pspi_data->noQas == 0)) {
2789 		pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2790 		target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2791 
2792 		/* Disable QAS in a mixed configuration case
2793 		 */
2794 
2795 		ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2796 	}
2797 }
2798 
2799 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2800 
2801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2802 /*
2803  *  SCSI Config Page functionality ...
2804  */
2805 
2806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2807 /*	mptscsih_writeIOCPage4  - write IOC Page 4
2808  *	@hd: Pointer to a SCSI Host Structure
2809  *	@target_id: write IOC Page4 for this ID & Bus
2810  *
2811  *	Return: -EAGAIN if unable to obtain a Message Frame
2812  *		or 0 if success.
2813  *
2814  *	Remark: We do not wait for a return, write pages sequentially.
2815  */
2816 static int
2817 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2818 {
2819 	MPT_ADAPTER		*ioc = hd->ioc;
2820 	Config_t		*pReq;
2821 	IOCPage4_t		*IOCPage4Ptr;
2822 	MPT_FRAME_HDR		*mf;
2823 	dma_addr_t		 dataDma;
2824 	u16			 req_idx;
2825 	u32			 frameOffset;
2826 	u32			 flagsLength;
2827 	int			 ii;
2828 
2829 	/* Get a MF for this command.
2830 	 */
2831 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2832 		dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2833 					ioc->name));
2834 		return -EAGAIN;
2835 	}
2836 
2837 	/* Set the request and the data pointers.
2838 	 * Place data at end of MF.
2839 	 */
2840 	pReq = (Config_t *)mf;
2841 
2842 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2843 	frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2844 
2845 	/* Complete the request frame (same for all requests).
2846 	 */
2847 	pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2848 	pReq->Reserved = 0;
2849 	pReq->ChainOffset = 0;
2850 	pReq->Function = MPI_FUNCTION_CONFIG;
2851 	pReq->ExtPageLength = 0;
2852 	pReq->ExtPageType = 0;
2853 	pReq->MsgFlags = 0;
2854 	for (ii=0; ii < 8; ii++) {
2855 		pReq->Reserved2[ii] = 0;
2856 	}
2857 
2858        	IOCPage4Ptr = ioc->spi_data.pIocPg4;
2859        	dataDma = ioc->spi_data.IocPg4_dma;
2860        	ii = IOCPage4Ptr->ActiveSEP++;
2861        	IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2862        	IOCPage4Ptr->SEP[ii].SEPBus = bus;
2863        	pReq->Header = IOCPage4Ptr->Header;
2864 	pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2865 
2866 	/* Add a SGE to the config request.
2867 	 */
2868 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2869 		(IOCPage4Ptr->Header.PageLength + ii) * 4;
2870 
2871 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2872 
2873 	dinitprintk((MYIOC_s_INFO_FMT
2874 		"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2875 			ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2876 
2877 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2878 
2879 	return 0;
2880 }
2881 
2882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2883 /*
2884  *  Bus Scan and Domain Validation functionality ...
2885  */
2886 
2887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2888 /*
2889  *	mptscsih_scandv_complete - Scan and DV callback routine registered
2890  *	to Fustion MPT (base) driver.
2891  *
2892  *	@ioc: Pointer to MPT_ADAPTER structure
2893  *	@mf: Pointer to original MPT request frame
2894  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
2895  *
2896  *	This routine is called from mpt.c::mpt_interrupt() at the completion
2897  *	of any SCSI IO request.
2898  *	This routine is registered with the Fusion MPT (base) driver at driver
2899  *	load/init time via the mpt_register() API call.
2900  *
2901  *	Returns 1 indicating alloc'd request frame ptr should be freed.
2902  *
2903  *	Remark: Sets a completion code and (possibly) saves sense data
2904  *	in the IOC member localReply structure.
2905  *	Used ONLY for DV and other internal commands.
2906  */
2907 int
2908 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2909 {
2910 	MPT_SCSI_HOST	*hd;
2911 	SCSIIORequest_t *pReq;
2912 	int		 completionCode;
2913 	u16		 req_idx;
2914 
2915 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2916 
2917 	if ((mf == NULL) ||
2918 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2919 		printk(MYIOC_s_ERR_FMT
2920 			"ScanDvComplete, %s req frame ptr! (=%p)\n",
2921 				ioc->name, mf?"BAD":"NULL", (void *) mf);
2922 		goto wakeup;
2923 	}
2924 
2925 	del_timer(&hd->timer);
2926 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2927 	hd->ScsiLookup[req_idx] = NULL;
2928 	pReq = (SCSIIORequest_t *) mf;
2929 
2930 	if (mf != hd->cmdPtr) {
2931 		printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2932 				hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2933 	}
2934 	hd->cmdPtr = NULL;
2935 
2936 	ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2937 			hd->ioc->name, mf, mr, req_idx));
2938 
2939 	hd->pLocal = &hd->localReply;
2940 	hd->pLocal->scsiStatus = 0;
2941 
2942 	/* If target struct exists, clear sense valid flag.
2943 	 */
2944 	if (mr == NULL) {
2945 		completionCode = MPT_SCANDV_GOOD;
2946 	} else {
2947 		SCSIIOReply_t	*pReply;
2948 		u16		 status;
2949 		u8		 scsi_status;
2950 
2951 		pReply = (SCSIIOReply_t *) mr;
2952 
2953 		status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2954 		scsi_status = pReply->SCSIStatus;
2955 
2956 		ddvtprintk((KERN_NOTICE "  IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
2957 			     status, pReply->SCSIState, scsi_status,
2958 			     le32_to_cpu(pReply->IOCLogInfo)));
2959 
2960 		switch(status) {
2961 
2962 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
2963 			completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2964 			break;
2965 
2966 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
2967 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
2968 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
2969 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
2970 			completionCode = MPT_SCANDV_DID_RESET;
2971 			break;
2972 
2973 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
2974 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
2975 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
2976 			if (pReply->Function == MPI_FUNCTION_CONFIG) {
2977 				ConfigReply_t *pr = (ConfigReply_t *)mr;
2978 				completionCode = MPT_SCANDV_GOOD;
2979 				hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2980 				hd->pLocal->header.PageLength = pr->Header.PageLength;
2981 				hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2982 				hd->pLocal->header.PageType = pr->Header.PageType;
2983 
2984 			} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2985 				/* If the RAID Volume request is successful,
2986 				 * return GOOD, else indicate that
2987 				 * some type of error occurred.
2988 				 */
2989 				MpiRaidActionReply_t	*pr = (MpiRaidActionReply_t *)mr;
2990 				if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2991 					completionCode = MPT_SCANDV_GOOD;
2992 				else
2993 					completionCode = MPT_SCANDV_SOME_ERROR;
2994 				memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2995 
2996 			} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2997 				u8		*sense_data;
2998 				int		 sz;
2999 
3000 				/* save sense data in global structure
3001 				 */
3002 				completionCode = MPT_SCANDV_SENSE;
3003 				hd->pLocal->scsiStatus = scsi_status;
3004 				sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3005 					(req_idx * MPT_SENSE_BUFFER_ALLOC));
3006 
3007 				sz = min_t(int, pReq->SenseBufferLength,
3008 							SCSI_STD_SENSE_BYTES);
3009 				memcpy(hd->pLocal->sense, sense_data, sz);
3010 
3011 				ddvprintk((KERN_NOTICE "  Check Condition, sense ptr %p\n",
3012 						sense_data));
3013 			} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3014 				if (pReq->CDB[0] == INQUIRY)
3015 					completionCode = MPT_SCANDV_ISSUE_SENSE;
3016 				else
3017 					completionCode = MPT_SCANDV_DID_RESET;
3018 			}
3019 			else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3020 				completionCode = MPT_SCANDV_DID_RESET;
3021 			else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3022 				completionCode = MPT_SCANDV_DID_RESET;
3023 			else {
3024 				completionCode = MPT_SCANDV_GOOD;
3025 				hd->pLocal->scsiStatus = scsi_status;
3026 			}
3027 			break;
3028 
3029 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
3030 			if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3031 				completionCode = MPT_SCANDV_DID_RESET;
3032 			else
3033 				completionCode = MPT_SCANDV_SOME_ERROR;
3034 			break;
3035 
3036 		default:
3037 			completionCode = MPT_SCANDV_SOME_ERROR;
3038 			break;
3039 
3040 		}	/* switch(status) */
3041 
3042 		ddvtprintk((KERN_NOTICE "  completionCode set to %08xh\n",
3043 				completionCode));
3044 	} /* end of address reply case */
3045 
3046 	hd->pLocal->completion = completionCode;
3047 
3048 	/* MF and RF are freed in mpt_interrupt
3049 	 */
3050 wakeup:
3051 	/* Free Chain buffers (will never chain) in scan or dv */
3052 	//mptscsih_freeChainBuffers(ioc, req_idx);
3053 
3054 	/*
3055 	 * Wake up the original calling thread
3056 	 */
3057 	hd->scandv_wait_done = 1;
3058 	wake_up(&hd->scandv_waitq);
3059 
3060 	return 1;
3061 }
3062 
3063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3064 /*	mptscsih_timer_expired - Call back for timer process.
3065  *	Used only for dv functionality.
3066  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3067  *
3068  */
3069 void
3070 mptscsih_timer_expired(unsigned long data)
3071 {
3072 	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3073 
3074 	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3075 
3076 	if (hd->cmdPtr) {
3077 		MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3078 
3079 		if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3080 			/* Desire to issue a task management request here.
3081 			 * TM requests MUST be single threaded.
3082 			 * If old eh code and no TM current, issue request.
3083 			 * If new eh code, do nothing. Wait for OS cmd timeout
3084 			 *	for bus reset.
3085 			 */
3086 			ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3087 		} else {
3088 			/* Perform a FW reload */
3089 			if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3090 				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3091 			}
3092 		}
3093 	} else {
3094 		/* This should NEVER happen */
3095 		printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3096 	}
3097 
3098 	/* No more processing.
3099 	 * TM call will generate an interrupt for SCSI TM Management.
3100 	 * The FW will reply to all outstanding commands, callback will finish cleanup.
3101 	 * Hard reset clean-up will free all resources.
3102 	 */
3103 	ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3104 
3105 	return;
3106 }
3107 
3108 
3109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3110 /**
3111  *	mptscsih_do_cmd - Do internal command.
3112  *	@hd: MPT_SCSI_HOST pointer
3113  *	@io: INTERNAL_CMD pointer.
3114  *
3115  *	Issue the specified internally generated command and do command
3116  *	specific cleanup. For bus scan / DV only.
3117  *	NOTES: If command is Inquiry and status is good,
3118  *	initialize a target structure, save the data
3119  *
3120  *	Remark: Single threaded access only.
3121  *
3122  *	Return:
3123  *		< 0 if an illegal command or no resources
3124  *
3125  *		   0 if good
3126  *
3127  *		 > 0 if command complete but some type of completion error.
3128  */
3129 static int
3130 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3131 {
3132 	MPT_FRAME_HDR	*mf;
3133 	SCSIIORequest_t	*pScsiReq;
3134 	SCSIIORequest_t	 ReqCopy;
3135 	int		 my_idx, ii, dir;
3136 	int		 rc, cmdTimeout;
3137 	int		in_isr;
3138 	char		 cmdLen;
3139 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3140 	char		 cmd = io->cmd;
3141 
3142 	in_isr = in_interrupt();
3143 	if (in_isr) {
3144 		dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3145        				hd->ioc->name));
3146 		return -EPERM;
3147 	}
3148 
3149 
3150 	/* Set command specific information
3151 	 */
3152 	switch (cmd) {
3153 	case INQUIRY:
3154 		cmdLen = 6;
3155 		dir = MPI_SCSIIO_CONTROL_READ;
3156 		CDB[0] = cmd;
3157 		CDB[4] = io->size;
3158 		cmdTimeout = 10;
3159 		break;
3160 
3161 	case TEST_UNIT_READY:
3162 		cmdLen = 6;
3163 		dir = MPI_SCSIIO_CONTROL_READ;
3164 		cmdTimeout = 10;
3165 		break;
3166 
3167 	case START_STOP:
3168 		cmdLen = 6;
3169 		dir = MPI_SCSIIO_CONTROL_READ;
3170 		CDB[0] = cmd;
3171 		CDB[4] = 1;	/*Spin up the disk */
3172 		cmdTimeout = 15;
3173 		break;
3174 
3175 	case REQUEST_SENSE:
3176 		cmdLen = 6;
3177 		CDB[0] = cmd;
3178 		CDB[4] = io->size;
3179 		dir = MPI_SCSIIO_CONTROL_READ;
3180 		cmdTimeout = 10;
3181 		break;
3182 
3183 	case READ_BUFFER:
3184 		cmdLen = 10;
3185 		dir = MPI_SCSIIO_CONTROL_READ;
3186 		CDB[0] = cmd;
3187 		if (io->flags & MPT_ICFLAG_ECHO) {
3188 			CDB[1] = 0x0A;
3189 		} else {
3190 			CDB[1] = 0x02;
3191 		}
3192 
3193 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
3194 			CDB[1] |= 0x01;
3195 		}
3196 		CDB[6] = (io->size >> 16) & 0xFF;
3197 		CDB[7] = (io->size >>  8) & 0xFF;
3198 		CDB[8] = io->size & 0xFF;
3199 		cmdTimeout = 10;
3200 		break;
3201 
3202 	case WRITE_BUFFER:
3203 		cmdLen = 10;
3204 		dir = MPI_SCSIIO_CONTROL_WRITE;
3205 		CDB[0] = cmd;
3206 		if (io->flags & MPT_ICFLAG_ECHO) {
3207 			CDB[1] = 0x0A;
3208 		} else {
3209 			CDB[1] = 0x02;
3210 		}
3211 		CDB[6] = (io->size >> 16) & 0xFF;
3212 		CDB[7] = (io->size >>  8) & 0xFF;
3213 		CDB[8] = io->size & 0xFF;
3214 		cmdTimeout = 10;
3215 		break;
3216 
3217 	case RESERVE:
3218 		cmdLen = 6;
3219 		dir = MPI_SCSIIO_CONTROL_READ;
3220 		CDB[0] = cmd;
3221 		cmdTimeout = 10;
3222 		break;
3223 
3224 	case RELEASE:
3225 		cmdLen = 6;
3226 		dir = MPI_SCSIIO_CONTROL_READ;
3227 		CDB[0] = cmd;
3228 		cmdTimeout = 10;
3229 		break;
3230 
3231 	case SYNCHRONIZE_CACHE:
3232 		cmdLen = 10;
3233 		dir = MPI_SCSIIO_CONTROL_READ;
3234 		CDB[0] = cmd;
3235 //		CDB[1] = 0x02;	/* set immediate bit */
3236 		cmdTimeout = 10;
3237 		break;
3238 
3239 	default:
3240 		/* Error Case */
3241 		return -EFAULT;
3242 	}
3243 
3244 	/* Get and Populate a free Frame
3245 	 */
3246 	if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3247 		ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3248 					hd->ioc->name));
3249 		return -EBUSY;
3250 	}
3251 
3252 	pScsiReq = (SCSIIORequest_t *) mf;
3253 
3254 	/* Get the request index */
3255 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3256 	ADD_INDEX_LOG(my_idx); /* for debug */
3257 
3258 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3259 		pScsiReq->TargetID = io->physDiskNum;
3260 		pScsiReq->Bus = 0;
3261 		pScsiReq->ChainOffset = 0;
3262 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3263 	} else {
3264 		pScsiReq->TargetID = io->id;
3265 		pScsiReq->Bus = io->bus;
3266 		pScsiReq->ChainOffset = 0;
3267 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3268 	}
3269 
3270 	pScsiReq->CDBLength = cmdLen;
3271 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3272 
3273 	pScsiReq->Reserved = 0;
3274 
3275 	pScsiReq->MsgFlags = mpt_msg_flags();
3276 	/* MsgContext set in mpt_get_msg_fram call  */
3277 
3278 	for (ii=0; ii < 8; ii++)
3279 		pScsiReq->LUN[ii] = 0;
3280 	pScsiReq->LUN[1] = io->lun;
3281 
3282 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3283 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3284 	else
3285 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3286 
3287 	if (cmd == REQUEST_SENSE) {
3288 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3289 		ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3290 			hd->ioc->name, cmd));
3291 	}
3292 
3293 	for (ii=0; ii < 16; ii++)
3294 		pScsiReq->CDB[ii] = CDB[ii];
3295 
3296 	pScsiReq->DataLength = cpu_to_le32(io->size);
3297 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3298 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3299 
3300 	ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3301 			hd->ioc->name, cmd, io->bus, io->id, io->lun));
3302 
3303 	if (dir == MPI_SCSIIO_CONTROL_READ) {
3304 		mpt_add_sge((char *) &pScsiReq->SGL,
3305 			MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3306 			io->data_dma);
3307 	} else {
3308 		mpt_add_sge((char *) &pScsiReq->SGL,
3309 			MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3310 			io->data_dma);
3311 	}
3312 
3313 	/* The ISR will free the request frame, but we need
3314 	 * the information to initialize the target. Duplicate.
3315 	 */
3316 	memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3317 
3318 	/* Issue this command after:
3319 	 *	finish init
3320 	 *	add timer
3321 	 * Wait until the reply has been received
3322 	 *  ScsiScanDvCtx callback function will
3323 	 *	set hd->pLocal;
3324 	 *	set scandv_wait_done and call wake_up
3325 	 */
3326 	hd->pLocal = NULL;
3327 	hd->timer.expires = jiffies + HZ*cmdTimeout;
3328 	hd->scandv_wait_done = 0;
3329 
3330 	/* Save cmd pointer, for resource free if timeout or
3331 	 * FW reload occurs
3332 	 */
3333 	hd->cmdPtr = mf;
3334 
3335 	add_timer(&hd->timer);
3336 	mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3337 	wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3338 
3339 	if (hd->pLocal) {
3340 		rc = hd->pLocal->completion;
3341 		hd->pLocal->skip = 0;
3342 
3343 		/* Always set fatal error codes in some cases.
3344 		 */
3345 		if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3346 			rc = -ENXIO;
3347 		else if (rc == MPT_SCANDV_SOME_ERROR)
3348 			rc =  -rc;
3349 	} else {
3350 		rc = -EFAULT;
3351 		/* This should never happen. */
3352 		ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3353 				hd->ioc->name));
3354 	}
3355 
3356 	return rc;
3357 }
3358 
3359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3360 /**
3361  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3362  *	@hd: Pointer to a SCSI HOST structure
3363  *	@vtarget: per device private data
3364  *	@lun: lun
3365  *
3366  *	Uses the ISR, but with special processing.
3367  *	MUST be single-threaded.
3368  *
3369  */
3370 static void
3371 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3372 {
3373 	INTERNAL_CMD		 iocmd;
3374 
3375 	/* Following parameters will not change
3376 	 * in this routine.
3377 	 */
3378 	iocmd.cmd = SYNCHRONIZE_CACHE;
3379 	iocmd.flags = 0;
3380 	iocmd.physDiskNum = -1;
3381 	iocmd.data = NULL;
3382 	iocmd.data_dma = -1;
3383 	iocmd.size = 0;
3384 	iocmd.rsvd = iocmd.rsvd2 = 0;
3385 	iocmd.bus = vdevice->vtarget->bus_id;
3386 	iocmd.id = vdevice->vtarget->target_id;
3387 	iocmd.lun = (u8)vdevice->lun;
3388 
3389 	if ((vdevice->vtarget->type == TYPE_DISK) &&
3390 	    (vdevice->configured_lun))
3391 		mptscsih_do_cmd(hd, &iocmd);
3392 }
3393 
3394 EXPORT_SYMBOL(mptscsih_remove);
3395 EXPORT_SYMBOL(mptscsih_shutdown);
3396 #ifdef CONFIG_PM
3397 EXPORT_SYMBOL(mptscsih_suspend);
3398 EXPORT_SYMBOL(mptscsih_resume);
3399 #endif
3400 EXPORT_SYMBOL(mptscsih_proc_info);
3401 EXPORT_SYMBOL(mptscsih_info);
3402 EXPORT_SYMBOL(mptscsih_qcmd);
3403 EXPORT_SYMBOL(mptscsih_target_alloc);
3404 EXPORT_SYMBOL(mptscsih_slave_alloc);
3405 EXPORT_SYMBOL(mptscsih_target_destroy);
3406 EXPORT_SYMBOL(mptscsih_slave_destroy);
3407 EXPORT_SYMBOL(mptscsih_slave_configure);
3408 EXPORT_SYMBOL(mptscsih_abort);
3409 EXPORT_SYMBOL(mptscsih_dev_reset);
3410 EXPORT_SYMBOL(mptscsih_bus_reset);
3411 EXPORT_SYMBOL(mptscsih_host_reset);
3412 EXPORT_SYMBOL(mptscsih_bios_param);
3413 EXPORT_SYMBOL(mptscsih_io_done);
3414 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3415 EXPORT_SYMBOL(mptscsih_scandv_complete);
3416 EXPORT_SYMBOL(mptscsih_event_process);
3417 EXPORT_SYMBOL(mptscsih_ioc_reset);
3418 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3419 EXPORT_SYMBOL(mptscsih_timer_expired);
3420 EXPORT_SYMBOL(mptscsih_TMHandler);
3421 
3422 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3423