xref: /openbmc/linux/drivers/message/fusion/mptbase.c (revision d335cc38c75e28407455463444b912b09c92daec)
1 /*
2  *  linux/drivers/message/fusion/mptbase.c
3  *      This is the Fusion MPT base driver which supports multiple
4  *      (SCSI + LAN) specialized protocol drivers.
5  *      For use with LSI Logic PCI chip/adapter(s)
6  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7  *
8  *  Copyright (c) 1999-2005 LSI Logic Corporation
9  *  (mailto:mpt_linux_developer@lsil.com)
10  *
11  */
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13 /*
14     This program is free software; you can redistribute it and/or modify
15     it under the terms of the GNU General Public License as published by
16     the Free Software Foundation; version 2 of the License.
17 
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22 
23     NO WARRANTY
24     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28     solely responsible for determining the appropriateness of using and
29     distributing the Program and assumes all risks associated with its
30     exercise of rights under this Agreement, including but not limited to
31     the risks and costs of program errors, damage to or loss of data,
32     programs or equipment, and unavailability or interruption of operations.
33 
34     DISCLAIMER OF LIABILITY
35     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
42 
43     You should have received a copy of the GNU General Public License
44     along with this program; if not, write to the Free Software
45     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
46 */
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 
49 #include <linux/config.h>
50 #include <linux/version.h>
51 #include <linux/kernel.h>
52 #include <linux/module.h>
53 #include <linux/errno.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
56 #include <linux/types.h>
57 #include <linux/pci.h>
58 #include <linux/kdev_t.h>
59 #include <linux/blkdev.h>
60 #include <linux/delay.h>
61 #include <linux/interrupt.h>		/* needed for in_interrupt() proto */
62 #include <linux/dma-mapping.h>
63 #include <asm/io.h>
64 #ifdef CONFIG_MTRR
65 #include <asm/mtrr.h>
66 #endif
67 #ifdef __sparc__
68 #include <asm/irq.h>			/* needed for __irq_itoa() proto */
69 #endif
70 
71 #include "mptbase.h"
72 
73 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
74 #define my_NAME		"Fusion MPT base driver"
75 #define my_VERSION	MPT_LINUX_VERSION_COMMON
76 #define MYNAM		"mptbase"
77 
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
81 
82 /*
83  *  cmd line parameters
84  */
85 #ifdef MFCNT
86 static int mfcounter = 0;
87 #define PRINT_MF_COUNT 20000
88 #endif
89 
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 /*
92  *  Public data...
93  */
94 int mpt_lan_index = -1;
95 int mpt_stm_index = -1;
96 
97 struct proc_dir_entry *mpt_proc_root_dir;
98 
99 #define WHOINIT_UNKNOWN		0xAA
100 
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
102 /*
103  *  Private data...
104  */
105 					/* Adapter link list */
106 LIST_HEAD(ioc_list);
107 					/* Callback lookup table */
108 static MPT_CALLBACK		 MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
109 					/* Protocol driver class lookup table */
110 static int			 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
111 					/* Event handler lookup table */
112 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
113 					/* Reset handler lookup table */
114 static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
115 static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
116 
117 static int	mpt_base_index = -1;
118 static int	last_drv_idx = -1;
119 
120 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
121 
122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
123 /*
124  *  Forward protos...
125  */
126 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
127 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
128 static int	mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
129 			u32 *req, int replyBytes, u16 *u16reply, int maxwait,
130 			int sleepFlag);
131 static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
132 static void	mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
133 static void	mpt_adapter_disable(MPT_ADAPTER *ioc);
134 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
135 
136 static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
137 static int	MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
138 //static u32	mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
139 static int	GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
140 static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141 static int	SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
142 static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
143 static int	mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
144 static int	mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
145 static int	mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
146 static int	KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
147 static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
148 static int	PrimeIocFifos(MPT_ADAPTER *ioc);
149 static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
151 static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
152 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
153 static int	GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
154 static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
155 static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
156 static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
157 static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
158 static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
159 static void	mpt_timer_expired(unsigned long data);
160 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
161 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
162 
163 #ifdef CONFIG_PROC_FS
164 static int	procmpt_summary_read(char *buf, char **start, off_t offset,
165 				int request, int *eof, void *data);
166 static int	procmpt_version_read(char *buf, char **start, off_t offset,
167 				int request, int *eof, void *data);
168 static int	procmpt_iocinfo_read(char *buf, char **start, off_t offset,
169 				int request, int *eof, void *data);
170 #endif
171 static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
172 
173 //int		mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
174 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
175 static void	mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
176 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
177 static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
178 
179 /* module entry point */
180 static int  __init    fusion_init  (void);
181 static void __exit    fusion_exit  (void);
182 
183 #define CHIPREG_READ32(addr) 		readl_relaxed(addr)
184 #define CHIPREG_READ32_dmasync(addr)	readl(addr)
185 #define CHIPREG_WRITE32(addr,val) 	writel(val, addr)
186 #define CHIPREG_PIO_WRITE32(addr,val)	outl(val, (unsigned long)addr)
187 #define CHIPREG_PIO_READ32(addr) 	inl((unsigned long)addr)
188 
189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
190 /*
191  *	mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
192  *	@irq: irq number (not used)
193  *	@bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
194  *	@r: pt_regs pointer (not used)
195  *
196  *	This routine is registered via the request_irq() kernel API call,
197  *	and handles all interrupts generated from a specific MPT adapter
198  *	(also referred to as a IO Controller or IOC).
199  *	This routine must clear the interrupt from the adapter and does
200  *	so by reading the reply FIFO.  Multiple replies may be processed
201  *	per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
202  *	which is currently set to 32 in mptbase.h.
203  *
204  *	This routine handles register-level access of the adapter but
205  *	dispatches (calls) a protocol-specific callback routine to handle
206  *	the protocol-specific details of the MPT request completion.
207  */
208 static irqreturn_t
209 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
210 {
211 	MPT_ADAPTER	*ioc;
212 	MPT_FRAME_HDR	*mf;
213 	MPT_FRAME_HDR	*mr;
214 	u32		 pa;
215 	int		 req_idx;
216 	int		 cb_idx;
217 	int		 type;
218 	int		 freeme;
219 
220 	ioc = (MPT_ADAPTER *)bus_id;
221 
222 	/*
223 	 *  Drain the reply FIFO!
224 	 *
225 	 * NOTES: I've seen up to 10 replies processed in this loop, so far...
226 	 * Update: I've seen up to 9182 replies processed in this loop! ??
227 	 * Update: Limit ourselves to processing max of N replies
228 	 *	(bottom of loop).
229 	 */
230 	while (1) {
231 
232 		if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
233 			return IRQ_HANDLED;
234 
235 		cb_idx = 0;
236 		freeme = 0;
237 
238 		/*
239 		 *  Check for non-TURBO reply!
240 		 */
241 		if (pa & MPI_ADDRESS_REPLY_A_BIT) {
242 			u32 reply_dma_low;
243 			u16 ioc_stat;
244 
245 			/* non-TURBO reply!  Hmmm, something may be up...
246 			 *  Newest turbo reply mechanism; get address
247 			 *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
248 			 */
249 
250 			/* Map DMA address of reply header to cpu address.
251 			 * pa is 32 bits - but the dma address may be 32 or 64 bits
252 			 * get offset based only only the low addresses
253 			 */
254 			reply_dma_low = (pa = (pa << 1));
255 			mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
256 					 (reply_dma_low - ioc->reply_frames_low_dma));
257 
258 			req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
259 			cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
260 			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
261 
262 			dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
263 					ioc->name, mr, req_idx));
264 			DBG_DUMP_REPLY_FRAME(mr)
265 
266 			/*  Check/log IOC log info
267 			 */
268 			ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
269 			if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
270 				u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
271 				if (ioc->bus_type == FC)
272 					mpt_fc_log_info(ioc, log_info);
273 				else if (ioc->bus_type == SCSI)
274 					mpt_sp_log_info(ioc, log_info);
275 			}
276 			if (ioc_stat & MPI_IOCSTATUS_MASK) {
277 				if (ioc->bus_type == SCSI)
278 					mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
279 			}
280 		} else {
281 			/*
282 			 *  Process turbo (context) reply...
283 			 */
284 			dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
285 			type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
286 			if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
287 				cb_idx = mpt_stm_index;
288 				mf = NULL;
289 				mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
290 			} else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
291 				cb_idx = mpt_lan_index;
292 				 /*  Blind set of mf to NULL here was fatal
293 				 *  after lan_reply says "freeme"
294 				 *  Fix sort of combined with an optimization here;
295 				 *  added explicit check for case where lan_reply
296 				 *  was just returning 1 and doing nothing else.
297 				 *  For this case skip the callback, but set up
298 				 *  proper mf value first here:-)
299 				 */
300 				if ((pa & 0x58000000) == 0x58000000) {
301 					req_idx = pa & 0x0000FFFF;
302 					mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
303 					freeme = 1;
304 					/*
305 					 *  IMPORTANT!  Invalidate the callback!
306 					 */
307 					cb_idx = 0;
308 				} else {
309 					mf = NULL;
310 				}
311 				mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
312 			} else {
313 				req_idx = pa & 0x0000FFFF;
314 				cb_idx = (pa & 0x00FF0000) >> 16;
315 				mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
316 				mr = NULL;
317 			}
318 			pa = 0;					/* No reply flush! */
319 		}
320 
321 #ifdef MPT_DEBUG_IRQ
322 		if (ioc->bus_type == SCSI) {
323 			/* Verify mf, mr are reasonable.
324 			 */
325 			if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
326 				|| (mf < ioc->req_frames)) ) {
327 				printk(MYIOC_s_WARN_FMT
328 					"mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
329 				cb_idx = 0;
330 				pa = 0;
331 				freeme = 0;
332 			}
333 			if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
334 				|| (mr < ioc->reply_frames)) ) {
335 				printk(MYIOC_s_WARN_FMT
336 					"mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
337 				cb_idx = 0;
338 				pa = 0;
339 				freeme = 0;
340 			}
341 			if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
342 				printk(MYIOC_s_WARN_FMT
343 					"mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
344 				cb_idx = 0;
345 				pa = 0;
346 				freeme = 0;
347 			}
348 		}
349 #endif
350 
351 		/*  Check for (valid) IO callback!  */
352 		if (cb_idx) {
353 			/*  Do the callback!  */
354 			freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
355 		}
356 
357 		if (pa) {
358 			/*  Flush (non-TURBO) reply with a WRITE!  */
359 			CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
360 		}
361 
362 		if (freeme) {
363 			/*  Put Request back on FreeQ!  */
364 			mpt_free_msg_frame(ioc, mf);
365 		}
366 
367 		mb();
368 	}	/* drain reply FIFO */
369 
370 	return IRQ_HANDLED;
371 }
372 
373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
374 /*
375  *	mpt_base_reply - MPT base driver's callback routine; all base driver
376  *	"internal" request/reply processing is routed here.
377  *	Currently used for EventNotification and EventAck handling.
378  *	@ioc: Pointer to MPT_ADAPTER structure
379  *	@mf: Pointer to original MPT request frame
380  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
381  *
382 	*	Returns 1 indicating original alloc'd request frame ptr
383  *	should be freed, or 0 if it shouldn't.
384  */
385 static int
386 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
387 {
388 	int freereq = 1;
389 	u8 func;
390 
391 	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
392 
393 	if ((mf == NULL) ||
394 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
395 		printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
396 				ioc->name, (void *)mf);
397 		return 1;
398 	}
399 
400 	if (reply == NULL) {
401 		dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
402 				ioc->name));
403 		return 1;
404 	}
405 
406 	if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
407 		dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
408 		DBG_DUMP_REQUEST_FRAME_HDR(mf)
409 	}
410 
411 	func = reply->u.hdr.Function;
412 	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
413 			ioc->name, func));
414 
415 	if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
416 		EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
417 		int evHandlers = 0;
418 		int results;
419 
420 		results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
421 		if (results != evHandlers) {
422 			/* CHECKME! Any special handling needed here? */
423 			devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
424 					ioc->name, evHandlers, results));
425 		}
426 
427 		/*
428 		 *	Hmmm...  It seems that EventNotificationReply is an exception
429 		 *	to the rule of one reply per request.
430 		 */
431 		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
432 			freereq = 0;
433 
434 #ifdef CONFIG_PROC_FS
435 //		LogEvent(ioc, pEvReply);
436 #endif
437 
438 	} else if (func == MPI_FUNCTION_EVENT_ACK) {
439 		dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
440 				ioc->name));
441 	} else if (func == MPI_FUNCTION_CONFIG ||
442 		   func == MPI_FUNCTION_TOOLBOX) {
443 		CONFIGPARMS *pCfg;
444 		unsigned long flags;
445 
446 		dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
447 				ioc->name, mf, reply));
448 
449 		pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
450 
451 		if (pCfg) {
452 			/* disable timer and remove from linked list */
453 			del_timer(&pCfg->timer);
454 
455 			spin_lock_irqsave(&ioc->FreeQlock, flags);
456 			list_del(&pCfg->linkage);
457 			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
458 
459 			/*
460 			 *	If IOC Status is SUCCESS, save the header
461 			 *	and set the status code to GOOD.
462 			 */
463 			pCfg->status = MPT_CONFIG_ERROR;
464 			if (reply) {
465 				ConfigReply_t	*pReply = (ConfigReply_t *)reply;
466 				u16		 status;
467 
468 				status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
469 				dcprintk((KERN_NOTICE "  IOCStatus=%04xh, IOCLogInfo=%08xh\n",
470 				     status, le32_to_cpu(pReply->IOCLogInfo)));
471 
472 				pCfg->status = status;
473 				if (status == MPI_IOCSTATUS_SUCCESS) {
474 					pCfg->hdr->PageVersion = pReply->Header.PageVersion;
475 					pCfg->hdr->PageLength = pReply->Header.PageLength;
476 					pCfg->hdr->PageNumber = pReply->Header.PageNumber;
477 					pCfg->hdr->PageType = pReply->Header.PageType;
478 				}
479 			}
480 
481 			/*
482 			 *	Wake up the original calling thread
483 			 */
484 			pCfg->wait_done = 1;
485 			wake_up(&mpt_waitq);
486 		}
487 	} else {
488 		printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
489 				ioc->name, func);
490 	}
491 
492 	/*
493 	 *	Conditionally tell caller to free the original
494 	 *	EventNotification/EventAck/unexpected request frame!
495 	 */
496 	return freereq;
497 }
498 
499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
500 /**
501  *	mpt_register - Register protocol-specific main callback handler.
502  *	@cbfunc: callback function pointer
503  *	@dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
504  *
505  *	This routine is called by a protocol-specific driver (SCSI host,
506  *	LAN, SCSI target) to register it's reply callback routine.  Each
507  *	protocol-specific driver must do this before it will be able to
508  *	use any IOC resources, such as obtaining request frames.
509  *
510  *	NOTES: The SCSI protocol driver currently calls this routine thrice
511  *	in order to register separate callbacks; one for "normal" SCSI IO;
512  *	one for MptScsiTaskMgmt requests; one for Scan/DV requests.
513  *
514  *	Returns a positive integer valued "handle" in the
515  *	range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
516  *	Any non-positive return value (including zero!) should be considered
517  *	an error by the caller.
518  */
519 int
520 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
521 {
522 	int i;
523 
524 	last_drv_idx = -1;
525 
526 	/*
527 	 *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
528 	 *  (slot/handle 0 is reserved!)
529 	 */
530 	for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
531 		if (MptCallbacks[i] == NULL) {
532 			MptCallbacks[i] = cbfunc;
533 			MptDriverClass[i] = dclass;
534 			MptEvHandlers[i] = NULL;
535 			last_drv_idx = i;
536 			break;
537 		}
538 	}
539 
540 	return last_drv_idx;
541 }
542 
543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
544 /**
545  *	mpt_deregister - Deregister a protocol drivers resources.
546  *	@cb_idx: previously registered callback handle
547  *
548  *	Each protocol-specific driver should call this routine when it's
549  *	module is unloaded.
550  */
551 void
552 mpt_deregister(int cb_idx)
553 {
554 	if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
555 		MptCallbacks[cb_idx] = NULL;
556 		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
557 		MptEvHandlers[cb_idx] = NULL;
558 
559 		last_drv_idx++;
560 	}
561 }
562 
563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
564 /**
565  *	mpt_event_register - Register protocol-specific event callback
566  *	handler.
567  *	@cb_idx: previously registered (via mpt_register) callback handle
568  *	@ev_cbfunc: callback function
569  *
570  *	This routine can be called by one or more protocol-specific drivers
571  *	if/when they choose to be notified of MPT events.
572  *
573  *	Returns 0 for success.
574  */
575 int
576 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
577 {
578 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
579 		return -1;
580 
581 	MptEvHandlers[cb_idx] = ev_cbfunc;
582 	return 0;
583 }
584 
585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
586 /**
587  *	mpt_event_deregister - Deregister protocol-specific event callback
588  *	handler.
589  *	@cb_idx: previously registered callback handle
590  *
591  *	Each protocol-specific driver should call this routine
592  *	when it does not (or can no longer) handle events,
593  *	or when it's module is unloaded.
594  */
595 void
596 mpt_event_deregister(int cb_idx)
597 {
598 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
599 		return;
600 
601 	MptEvHandlers[cb_idx] = NULL;
602 }
603 
604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
605 /**
606  *	mpt_reset_register - Register protocol-specific IOC reset handler.
607  *	@cb_idx: previously registered (via mpt_register) callback handle
608  *	@reset_func: reset function
609  *
610  *	This routine can be called by one or more protocol-specific drivers
611  *	if/when they choose to be notified of IOC resets.
612  *
613  *	Returns 0 for success.
614  */
615 int
616 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
617 {
618 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
619 		return -1;
620 
621 	MptResetHandlers[cb_idx] = reset_func;
622 	return 0;
623 }
624 
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 /**
627  *	mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
628  *	@cb_idx: previously registered callback handle
629  *
630  *	Each protocol-specific driver should call this routine
631  *	when it does not (or can no longer) handle IOC reset handling,
632  *	or when it's module is unloaded.
633  */
634 void
635 mpt_reset_deregister(int cb_idx)
636 {
637 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
638 		return;
639 
640 	MptResetHandlers[cb_idx] = NULL;
641 }
642 
643 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
644 /**
645  *	mpt_device_driver_register - Register device driver hooks
646  */
647 int
648 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
649 {
650 	MPT_ADAPTER	*ioc;
651 
652 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
653 		return -EINVAL;
654 	}
655 
656 	MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
657 
658 	/* call per pci device probe entry point */
659 	list_for_each_entry(ioc, &ioc_list, list) {
660 		if(dd_cbfunc->probe) {
661 			dd_cbfunc->probe(ioc->pcidev,
662 			  ioc->pcidev->driver->id_table);
663   		}
664 	 }
665 
666 	return 0;
667 }
668 
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 /**
671  *	mpt_device_driver_deregister - DeRegister device driver hooks
672  */
673 void
674 mpt_device_driver_deregister(int cb_idx)
675 {
676 	struct mpt_pci_driver *dd_cbfunc;
677 	MPT_ADAPTER	*ioc;
678 
679 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
680 		return;
681 
682 	dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
683 
684 	list_for_each_entry(ioc, &ioc_list, list) {
685 		if (dd_cbfunc->remove)
686 			dd_cbfunc->remove(ioc->pcidev);
687 	}
688 
689 	MptDeviceDriverHandlers[cb_idx] = NULL;
690 }
691 
692 
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
694 /**
695  *	mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
696  *	allocated per MPT adapter.
697  *	@handle: Handle of registered MPT protocol driver
698  *	@ioc: Pointer to MPT adapter structure
699  *
700  *	Returns pointer to a MPT request frame or %NULL if none are available
701  *	or IOC is not active.
702  */
703 MPT_FRAME_HDR*
704 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
705 {
706 	MPT_FRAME_HDR *mf;
707 	unsigned long flags;
708 	u16	 req_idx;	/* Request index */
709 
710 	/* validate handle and ioc identifier */
711 
712 #ifdef MFCNT
713 	if (!ioc->active)
714 		printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
715 #endif
716 
717 	/* If interrupts are not attached, do not return a request frame */
718 	if (!ioc->active)
719 		return NULL;
720 
721 	spin_lock_irqsave(&ioc->FreeQlock, flags);
722 	if (!list_empty(&ioc->FreeQ)) {
723 		int req_offset;
724 
725 		mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
726 				u.frame.linkage.list);
727 		list_del(&mf->u.frame.linkage.list);
728 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;	/* byte */
729 		req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
730 								/* u16! */
731 		req_idx = req_offset / ioc->req_sz;
732 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
733 		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
734 		ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
735 #ifdef MFCNT
736 		ioc->mfcnt++;
737 #endif
738 	}
739 	else
740 		mf = NULL;
741 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
742 
743 #ifdef MFCNT
744 	if (mf == NULL)
745 		printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
746 	mfcounter++;
747 	if (mfcounter == PRINT_MF_COUNT)
748 		printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
749 #endif
750 
751 	dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
752 			ioc->name, handle, ioc->id, mf));
753 	return mf;
754 }
755 
756 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
757 /**
758  *	mpt_put_msg_frame - Send a protocol specific MPT request frame
759  *	to a IOC.
760  *	@handle: Handle of registered MPT protocol driver
761  *	@ioc: Pointer to MPT adapter structure
762  *	@mf: Pointer to MPT request frame
763  *
764  *	This routine posts a MPT request frame to the request post FIFO of a
765  *	specific MPT adapter.
766  */
767 void
768 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
769 {
770 	u32 mf_dma_addr;
771 	int req_offset;
772 	u16	 req_idx;	/* Request index */
773 
774 	/* ensure values are reset properly! */
775 	mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		/* byte */
776 	req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
777 								/* u16! */
778 	req_idx = req_offset / ioc->req_sz;
779 	mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
780 	mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
781 
782 #ifdef MPT_DEBUG_MSG_FRAME
783 	{
784 		u32	*m = mf->u.frame.hwhdr.__hdr;
785 		int	 ii, n;
786 
787 		printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
788 				ioc->name, m);
789 		n = ioc->req_sz/4 - 1;
790 		while (m[n] == 0)
791 			n--;
792 		for (ii=0; ii<=n; ii++) {
793 			if (ii && ((ii%8)==0))
794 				printk("\n" KERN_INFO " ");
795 			printk(" %08x", le32_to_cpu(m[ii]));
796 		}
797 		printk("\n");
798 	}
799 #endif
800 
801 	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
802 	dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
803 	CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
804 }
805 
806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
807 /**
808  *	mpt_free_msg_frame - Place MPT request frame back on FreeQ.
809  *	@handle: Handle of registered MPT protocol driver
810  *	@ioc: Pointer to MPT adapter structure
811  *	@mf: Pointer to MPT request frame
812  *
813  *	This routine places a MPT request frame back on the MPT adapter's
814  *	FreeQ.
815  */
816 void
817 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
818 {
819 	unsigned long flags;
820 
821 	/*  Put Request back on FreeQ!  */
822 	spin_lock_irqsave(&ioc->FreeQlock, flags);
823 	list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
824 #ifdef MFCNT
825 	ioc->mfcnt--;
826 #endif
827 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
828 }
829 
830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
831 /**
832  *	mpt_add_sge - Place a simple SGE at address pAddr.
833  *	@pAddr: virtual address for SGE
834  *	@flagslength: SGE flags and data transfer length
835  *	@dma_addr: Physical address
836  *
837  *	This routine places a MPT request frame back on the MPT adapter's
838  *	FreeQ.
839  */
840 void
841 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
842 {
843 	if (sizeof(dma_addr_t) == sizeof(u64)) {
844 		SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
845 		u32 tmp = dma_addr & 0xFFFFFFFF;
846 
847 		pSge->FlagsLength = cpu_to_le32(flagslength);
848 		pSge->Address.Low = cpu_to_le32(tmp);
849 		tmp = (u32) ((u64)dma_addr >> 32);
850 		pSge->Address.High = cpu_to_le32(tmp);
851 
852 	} else {
853 		SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
854 		pSge->FlagsLength = cpu_to_le32(flagslength);
855 		pSge->Address = cpu_to_le32(dma_addr);
856 	}
857 }
858 
859 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
860 /**
861  *	mpt_send_handshake_request - Send MPT request via doorbell
862  *	handshake method.
863  *	@handle: Handle of registered MPT protocol driver
864  *	@ioc: Pointer to MPT adapter structure
865  *	@reqBytes: Size of the request in bytes
866  *	@req: Pointer to MPT request frame
867  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
868  *
869  *	This routine is used exclusively to send MptScsiTaskMgmt
870  *	requests since they are required to be sent via doorbell handshake.
871  *
872  *	NOTE: It is the callers responsibility to byte-swap fields in the
873  *	request which are greater than 1 byte in size.
874  *
875  *	Returns 0 for success, non-zero for failure.
876  */
877 int
878 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
879 {
880 	int		 r = 0;
881 	u8	*req_as_bytes;
882 	int	 ii;
883 
884 	/* State is known to be good upon entering
885 	 * this function so issue the bus reset
886 	 * request.
887 	 */
888 
889 	/*
890 	 * Emulate what mpt_put_msg_frame() does /wrt to sanity
891 	 * setting cb_idx/req_idx.  But ONLY if this request
892 	 * is in proper (pre-alloc'd) request buffer range...
893 	 */
894 	ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
895 	if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
896 		MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
897 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
898 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
899 	}
900 
901 	/* Make sure there are no doorbells */
902 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
903 
904 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
905 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
906 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
907 
908 	/* Wait for IOC doorbell int */
909 	if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
910 		return ii;
911 	}
912 
913 	/* Read doorbell and check for active bit */
914 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
915 		return -5;
916 
917 	dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
918 			ioc->name, ii));
919 
920 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
921 
922 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
923 		return -2;
924 	}
925 
926 	/* Send request via doorbell handshake */
927 	req_as_bytes = (u8 *) req;
928 	for (ii = 0; ii < reqBytes/4; ii++) {
929 		u32 word;
930 
931 		word = ((req_as_bytes[(ii*4) + 0] <<  0) |
932 			(req_as_bytes[(ii*4) + 1] <<  8) |
933 			(req_as_bytes[(ii*4) + 2] << 16) |
934 			(req_as_bytes[(ii*4) + 3] << 24));
935 		CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
936 		if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
937 			r = -3;
938 			break;
939 		}
940 	}
941 
942 	if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
943 		r = 0;
944 	else
945 		r = -4;
946 
947 	/* Make sure there are no doorbells */
948 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
949 
950 	return r;
951 }
952 
953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
954 /**
955  *	mpt_verify_adapter - Given a unique IOC identifier, set pointer to
956  *	the associated MPT adapter structure.
957  *	@iocid: IOC unique identifier (integer)
958  *	@iocpp: Pointer to pointer to IOC adapter
959  *
960  *	Returns iocid and sets iocpp.
961  */
962 int
963 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
964 {
965 	MPT_ADAPTER *ioc;
966 
967 	list_for_each_entry(ioc,&ioc_list,list) {
968 		if (ioc->id == iocid) {
969 			*iocpp =ioc;
970 			return iocid;
971 		}
972 	}
973 
974 	*iocpp = NULL;
975 	return -1;
976 }
977 
978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
979 /*
980  *	mpt_attach - Install a PCI intelligent MPT adapter.
981  *	@pdev: Pointer to pci_dev structure
982  *
983  *	This routine performs all the steps necessary to bring the IOC of
984  *	a MPT adapter to a OPERATIONAL state.  This includes registering
985  *	memory regions, registering the interrupt, and allocating request
986  *	and reply memory pools.
987  *
988  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
989  *	MPT adapter.
990  *
991  *	Returns 0 for success, non-zero for failure.
992  *
993  *	TODO: Add support for polled controllers
994  */
995 int
996 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
997 {
998 	MPT_ADAPTER	*ioc;
999 	u8		__iomem *mem;
1000 	unsigned long	 mem_phys;
1001 	unsigned long	 port;
1002 	u32		 msize;
1003 	u32		 psize;
1004 	int		 ii;
1005 	int		 r = -ENODEV;
1006 	u8		 revision;
1007 	u8		 pcixcmd;
1008 	static int	 mpt_ids = 0;
1009 #ifdef CONFIG_PROC_FS
1010 	struct proc_dir_entry *dent, *ent;
1011 #endif
1012 
1013 	if (pci_enable_device(pdev))
1014 		return r;
1015 
1016 	dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1017 
1018 	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1019 		dprintk((KERN_INFO MYNAM
1020 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1021 	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1022 		printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1023 		return r;
1024 	}
1025 
1026 	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1027 		dprintk((KERN_INFO MYNAM
1028 			": Using 64 bit consistent mask\n"));
1029 	else
1030 		dprintk((KERN_INFO MYNAM
1031 			": Not using 64 bit consistent mask\n"));
1032 
1033 	ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1034 	if (ioc == NULL) {
1035 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1036 		return -ENOMEM;
1037 	}
1038 	memset(ioc, 0, sizeof(MPT_ADAPTER));
1039 	ioc->alloc_total = sizeof(MPT_ADAPTER);
1040 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
1041 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1042 
1043 	ioc->pcidev = pdev;
1044 	ioc->diagPending = 0;
1045 	spin_lock_init(&ioc->diagLock);
1046 
1047 	/* Initialize the event logging.
1048 	 */
1049 	ioc->eventTypes = 0;	/* None */
1050 	ioc->eventContext = 0;
1051 	ioc->eventLogSize = 0;
1052 	ioc->events = NULL;
1053 
1054 #ifdef MFCNT
1055 	ioc->mfcnt = 0;
1056 #endif
1057 
1058 	ioc->cached_fw = NULL;
1059 
1060 	/* Initilize SCSI Config Data structure
1061 	 */
1062 	memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1063 
1064 	/* Initialize the running configQ head.
1065 	 */
1066 	INIT_LIST_HEAD(&ioc->configQ);
1067 
1068 	/* Find lookup slot. */
1069 	INIT_LIST_HEAD(&ioc->list);
1070 	ioc->id = mpt_ids++;
1071 
1072 	mem_phys = msize = 0;
1073 	port = psize = 0;
1074 	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1075 		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1076 			/* Get I/O space! */
1077 			port = pci_resource_start(pdev, ii);
1078 			psize = pci_resource_len(pdev,ii);
1079 		} else {
1080 			/* Get memmap */
1081 			mem_phys = pci_resource_start(pdev, ii);
1082 			msize = pci_resource_len(pdev,ii);
1083 			break;
1084 		}
1085 	}
1086 	ioc->mem_size = msize;
1087 
1088 	if (ii == DEVICE_COUNT_RESOURCE) {
1089 		printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1090 		kfree(ioc);
1091 		return -EINVAL;
1092 	}
1093 
1094 	dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1095 	dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1096 
1097 	mem = NULL;
1098 	/* Get logical ptr for PciMem0 space */
1099 	/*mem = ioremap(mem_phys, msize);*/
1100 	mem = ioremap(mem_phys, 0x100);
1101 	if (mem == NULL) {
1102 		printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1103 		kfree(ioc);
1104 		return -EINVAL;
1105 	}
1106 	ioc->memmap = mem;
1107 	dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1108 
1109 	dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1110 			&ioc->facts, &ioc->pfacts[0]));
1111 
1112 	ioc->mem_phys = mem_phys;
1113 	ioc->chip = (SYSIF_REGS __iomem *)mem;
1114 
1115 	/* Save Port IO values in case we need to do downloadboot */
1116 	{
1117 		u8 *pmem = (u8*)port;
1118 		ioc->pio_mem_phys = port;
1119 		ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1120 	}
1121 
1122 	if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1123 		ioc->prod_name = "LSIFC909";
1124 		ioc->bus_type = FC;
1125 	}
1126 	if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1127 		ioc->prod_name = "LSIFC929";
1128 		ioc->bus_type = FC;
1129 	}
1130 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1131 		ioc->prod_name = "LSIFC919";
1132 		ioc->bus_type = FC;
1133 	}
1134 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1135 		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1136 		ioc->bus_type = FC;
1137 		if (revision < XL_929) {
1138 			ioc->prod_name = "LSIFC929X";
1139 			/* 929X Chip Fix. Set Split transactions level
1140 		 	* for PCIX. Set MOST bits to zero.
1141 		 	*/
1142 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1143 			pcixcmd &= 0x8F;
1144 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1145 		} else {
1146 			ioc->prod_name = "LSIFC929XL";
1147 			/* 929XL Chip Fix. Set MMRBC to 0x08.
1148 		 	*/
1149 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1150 			pcixcmd |= 0x08;
1151 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1152 		}
1153 	}
1154 	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1155 		ioc->prod_name = "LSIFC919X";
1156 		ioc->bus_type = FC;
1157 		/* 919X Chip Fix. Set Split transactions level
1158 		 * for PCIX. Set MOST bits to zero.
1159 		 */
1160 		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1161 		pcixcmd &= 0x8F;
1162 		pci_write_config_byte(pdev, 0x6a, pcixcmd);
1163 	}
1164 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1165 		ioc->prod_name = "LSI53C1030";
1166 		ioc->bus_type = SCSI;
1167 		/* 1030 Chip Fix. Disable Split transactions
1168 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1169 		 */
1170 		pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1171 		if (revision < C0_1030) {
1172 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1173 			pcixcmd &= 0x8F;
1174 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1175 		}
1176 	}
1177 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1178 		ioc->prod_name = "LSI53C1035";
1179 		ioc->bus_type = SCSI;
1180 	}
1181 
1182 	sprintf(ioc->name, "ioc%d", ioc->id);
1183 
1184 	spin_lock_init(&ioc->FreeQlock);
1185 
1186 	/* Disable all! */
1187 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1188 	ioc->active = 0;
1189 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1190 
1191 	/* Set lookup ptr. */
1192 	list_add_tail(&ioc->list, &ioc_list);
1193 
1194 	ioc->pci_irq = -1;
1195 	if (pdev->irq) {
1196 		r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1197 
1198 		if (r < 0) {
1199 #ifndef __sparc__
1200 			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1201 					ioc->name, pdev->irq);
1202 #else
1203 			printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1204 					ioc->name, __irq_itoa(pdev->irq));
1205 #endif
1206 			list_del(&ioc->list);
1207 			iounmap(mem);
1208 			kfree(ioc);
1209 			return -EBUSY;
1210 		}
1211 
1212 		ioc->pci_irq = pdev->irq;
1213 
1214 		pci_set_master(pdev);			/* ?? */
1215 		pci_set_drvdata(pdev, ioc);
1216 
1217 #ifndef __sparc__
1218 		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1219 #else
1220 		dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1221 #endif
1222 	}
1223 
1224 	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1225 	 */
1226 	mpt_detect_bound_ports(ioc, pdev);
1227 
1228 	if ((r = mpt_do_ioc_recovery(ioc,
1229 	  MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1230 		printk(KERN_WARNING MYNAM
1231 		  ": WARNING - %s did not initialize properly! (%d)\n",
1232 		  ioc->name, r);
1233 
1234 		list_del(&ioc->list);
1235 		free_irq(ioc->pci_irq, ioc);
1236 		iounmap(mem);
1237 		kfree(ioc);
1238 		pci_set_drvdata(pdev, NULL);
1239 		return r;
1240 	}
1241 
1242 	/* call per device driver probe entry point */
1243 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1244 		if(MptDeviceDriverHandlers[ii] &&
1245 		  MptDeviceDriverHandlers[ii]->probe) {
1246 			MptDeviceDriverHandlers[ii]->probe(pdev,id);
1247 		}
1248 	}
1249 
1250 #ifdef CONFIG_PROC_FS
1251 	/*
1252 	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1253 	 */
1254 	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1255 	if (dent) {
1256 		ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1257 		if (ent) {
1258 			ent->read_proc = procmpt_iocinfo_read;
1259 			ent->data = ioc;
1260 		}
1261 		ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1262 		if (ent) {
1263 			ent->read_proc = procmpt_summary_read;
1264 			ent->data = ioc;
1265 		}
1266 	}
1267 #endif
1268 
1269 	return 0;
1270 }
1271 
1272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1273 /*
1274  *	mpt_detach - Remove a PCI intelligent MPT adapter.
1275  *	@pdev: Pointer to pci_dev structure
1276  *
1277  */
1278 
1279 void
1280 mpt_detach(struct pci_dev *pdev)
1281 {
1282 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
1283 	char pname[32];
1284 	int ii;
1285 
1286 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1287 	remove_proc_entry(pname, NULL);
1288 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1289 	remove_proc_entry(pname, NULL);
1290 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1291 	remove_proc_entry(pname, NULL);
1292 
1293 	/* call per device driver remove entry point */
1294 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1295 		if(MptDeviceDriverHandlers[ii] &&
1296 		  MptDeviceDriverHandlers[ii]->remove) {
1297 			MptDeviceDriverHandlers[ii]->remove(pdev);
1298 		}
1299 	}
1300 
1301 	/* Disable interrupts! */
1302 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1303 
1304 	ioc->active = 0;
1305 	synchronize_irq(pdev->irq);
1306 
1307 	/* Clear any lingering interrupt */
1308 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1309 
1310 	CHIPREG_READ32(&ioc->chip->IntStatus);
1311 
1312 	mpt_adapter_dispose(ioc);
1313 
1314 	pci_set_drvdata(pdev, NULL);
1315 }
1316 
1317 /**************************************************************************
1318  * Power Management
1319  */
1320 #ifdef CONFIG_PM
1321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1322 /*
1323  *	mpt_suspend - Fusion MPT base driver suspend routine.
1324  *
1325  *
1326  */
1327 int
1328 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1329 {
1330 	u32 device_state;
1331 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1332 
1333 	switch(state)
1334 	{
1335 		case 1: /* S1 */
1336 			device_state=1; /* D1 */;
1337 			break;
1338 		case 3: /* S3 */
1339 		case 4: /* S4 */
1340 			device_state=3; /* D3 */;
1341 			break;
1342 		default:
1343 			return -EAGAIN /*FIXME*/;
1344 			break;
1345 	}
1346 
1347 	printk(MYIOC_s_INFO_FMT
1348 	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1349 		ioc->name, pdev, pci_name(pdev), device_state);
1350 
1351 	pci_save_state(pdev);
1352 
1353 	/* put ioc into READY_STATE */
1354 	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1355 		printk(MYIOC_s_ERR_FMT
1356 		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
1357 	}
1358 
1359 	/* disable interrupts */
1360 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1361 	ioc->active = 0;
1362 
1363 	/* Clear any lingering interrupt */
1364 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1365 
1366 	pci_disable_device(pdev);
1367 	pci_set_power_state(pdev, device_state);
1368 
1369 	return 0;
1370 }
1371 
1372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1373 /*
1374  *	mpt_resume - Fusion MPT base driver resume routine.
1375  *
1376  *
1377  */
1378 int
1379 mpt_resume(struct pci_dev *pdev)
1380 {
1381 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1382 	u32 device_state = pdev->current_state;
1383 	int recovery_state;
1384 	int ii;
1385 
1386 	printk(MYIOC_s_INFO_FMT
1387 	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1388 		ioc->name, pdev, pci_name(pdev), device_state);
1389 
1390 	pci_set_power_state(pdev, 0);
1391 	pci_restore_state(pdev);
1392 	pci_enable_device(pdev);
1393 
1394 	/* enable interrupts */
1395 	CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1396 	ioc->active = 1;
1397 
1398 	/* F/W not running */
1399 	if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1400 		/* enable domain validation flags */
1401 		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1402 			ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1403 		}
1404 	}
1405 
1406 	printk(MYIOC_s_INFO_FMT
1407 		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1408 		ioc->name,
1409 		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1410 		CHIPREG_READ32(&ioc->chip->Doorbell));
1411 
1412 	/* bring ioc to operational state */
1413 	if ((recovery_state = mpt_do_ioc_recovery(ioc,
1414 	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1415 		printk(MYIOC_s_INFO_FMT
1416 			"pci-resume: Cannot recover, error:[%x]\n",
1417 			ioc->name, recovery_state);
1418 	} else {
1419 		printk(MYIOC_s_INFO_FMT
1420 			"pci-resume: success\n", ioc->name);
1421 	}
1422 
1423 	return 0;
1424 }
1425 #endif
1426 
1427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1428 /*
1429  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1430  *	@ioc: Pointer to MPT adapter structure
1431  *	@reason: Event word / reason
1432  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1433  *
1434  *	This routine performs all the steps necessary to bring the IOC
1435  *	to a OPERATIONAL state.
1436  *
1437  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1438  *	MPT adapter.
1439  *
1440  *	Returns:
1441  *		 0 for success
1442  *		-1 if failed to get board READY
1443  *		-2 if READY but IOCFacts Failed
1444  *		-3 if READY but PrimeIOCFifos Failed
1445  *		-4 if READY but IOCInit Failed
1446  */
1447 static int
1448 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1449 {
1450 	int	 hard_reset_done = 0;
1451 	int	 alt_ioc_ready = 0;
1452 	int	 hard;
1453 	int	 rc=0;
1454 	int	 ii;
1455 	int	 handlers;
1456 	int	 ret = 0;
1457 	int	 reset_alt_ioc_active = 0;
1458 
1459 	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1460 			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1461 
1462 	/* Disable reply interrupts (also blocks FreeQ) */
1463 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1464 	ioc->active = 0;
1465 
1466 	if (ioc->alt_ioc) {
1467 		if (ioc->alt_ioc->active)
1468 			reset_alt_ioc_active = 1;
1469 
1470 		/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1471 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1472 		ioc->alt_ioc->active = 0;
1473 	}
1474 
1475 	hard = 1;
1476 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1477 		hard = 0;
1478 
1479 	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1480 		if (hard_reset_done == -4) {
1481 			printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1482 					ioc->name);
1483 
1484 			if (reset_alt_ioc_active && ioc->alt_ioc) {
1485 				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1486 				dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1487 						ioc->alt_ioc->name));
1488 				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1489 				ioc->alt_ioc->active = 1;
1490 			}
1491 
1492 		} else {
1493 			printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1494 					ioc->name);
1495 		}
1496 		return -1;
1497 	}
1498 
1499 	/* hard_reset_done = 0 if a soft reset was performed
1500 	 * and 1 if a hard reset was performed.
1501 	 */
1502 	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1503 		if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1504 			alt_ioc_ready = 1;
1505 		else
1506 			printk(KERN_WARNING MYNAM
1507 					": alt-%s: Not ready WARNING!\n",
1508 					ioc->alt_ioc->name);
1509 	}
1510 
1511 	for (ii=0; ii<5; ii++) {
1512 		/* Get IOC facts! Allow 5 retries */
1513 		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1514 			break;
1515 	}
1516 
1517 
1518 	if (ii == 5) {
1519 		dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1520 		ret = -2;
1521 	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1522 		MptDisplayIocCapabilities(ioc);
1523 	}
1524 
1525 	if (alt_ioc_ready) {
1526 		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1527 			dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1528 			/* Retry - alt IOC was initialized once
1529 			 */
1530 			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1531 		}
1532 		if (rc) {
1533 			dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1534 			alt_ioc_ready = 0;
1535 			reset_alt_ioc_active = 0;
1536 		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1537 			MptDisplayIocCapabilities(ioc->alt_ioc);
1538 		}
1539 	}
1540 
1541 	/* Prime reply & request queues!
1542 	 * (mucho alloc's) Must be done prior to
1543 	 * init as upper addresses are needed for init.
1544 	 * If fails, continue with alt-ioc processing
1545 	 */
1546 	if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1547 		ret = -3;
1548 
1549 	/* May need to check/upload firmware & data here!
1550 	 * If fails, continue with alt-ioc processing
1551 	 */
1552 	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1553 		ret = -4;
1554 // NEW!
1555 	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1556 		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1557 				ioc->alt_ioc->name, rc);
1558 		alt_ioc_ready = 0;
1559 		reset_alt_ioc_active = 0;
1560 	}
1561 
1562 	if (alt_ioc_ready) {
1563 		if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1564 			alt_ioc_ready = 0;
1565 			reset_alt_ioc_active = 0;
1566 			printk(KERN_WARNING MYNAM
1567 				": alt-%s: (%d) init failure WARNING!\n",
1568 					ioc->alt_ioc->name, rc);
1569 		}
1570 	}
1571 
1572 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1573 		if (ioc->upload_fw) {
1574 			ddlprintk((MYIOC_s_INFO_FMT
1575 				"firmware upload required!\n", ioc->name));
1576 
1577 			/* Controller is not operational, cannot do upload
1578 			 */
1579 			if (ret == 0) {
1580 				rc = mpt_do_upload(ioc, sleepFlag);
1581 				if (rc != 0)
1582 					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1583 			}
1584 		}
1585 	}
1586 
1587 	if (ret == 0) {
1588 		/* Enable! (reply interrupt) */
1589 		CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1590 		ioc->active = 1;
1591 	}
1592 
1593 	if (reset_alt_ioc_active && ioc->alt_ioc) {
1594 		/* (re)Enable alt-IOC! (reply interrupt) */
1595 		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1596 				ioc->alt_ioc->name));
1597 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1598 		ioc->alt_ioc->active = 1;
1599 	}
1600 
1601 	/*  Enable MPT base driver management of EventNotification
1602 	 *  and EventAck handling.
1603 	 */
1604 	if ((ret == 0) && (!ioc->facts.EventState))
1605 		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
1606 
1607 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1608 		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
1609 
1610 	/*	Add additional "reason" check before call to GetLanConfigPages
1611 	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
1612 	 *	recursive scenario; GetLanConfigPages times out, timer expired
1613 	 *	routine calls HardResetHandler, which calls into here again,
1614 	 *	and we try GetLanConfigPages again...
1615 	 */
1616 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1617 		if (ioc->bus_type == FC) {
1618 			/*
1619 			 *  Pre-fetch FC port WWN and stuff...
1620 			 *  (FCPortPage0_t stuff)
1621 			 */
1622 			for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1623 				(void) GetFcPortPage0(ioc, ii);
1624 			}
1625 
1626 			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1627 			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1628 				/*
1629 				 *  Pre-fetch the ports LAN MAC address!
1630 				 *  (LANPage1_t stuff)
1631 				 */
1632 				(void) GetLanConfigPages(ioc);
1633 #ifdef MPT_DEBUG
1634 				{
1635 					u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1636 					dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1637 							ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1638 				}
1639 #endif
1640 			}
1641 		} else {
1642 			/* Get NVRAM and adapter maximums from SPP 0 and 2
1643 			 */
1644 			mpt_GetScsiPortSettings(ioc, 0);
1645 
1646 			/* Get version and length of SDP 1
1647 			 */
1648 			mpt_readScsiDevicePageHeaders(ioc, 0);
1649 
1650 			/* Find IM volumes
1651 			 */
1652 			if (ioc->facts.MsgVersion >= 0x0102)
1653 				mpt_findImVolumes(ioc);
1654 
1655 			/* Check, and possibly reset, the coalescing value
1656 			 */
1657 			mpt_read_ioc_pg_1(ioc);
1658 
1659 			mpt_read_ioc_pg_4(ioc);
1660 		}
1661 
1662 		GetIoUnitPage2(ioc);
1663 	}
1664 
1665 	/*
1666 	 * Call each currently registered protocol IOC reset handler
1667 	 * with post-reset indication.
1668 	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1669 	 * MptResetHandlers[] registered yet.
1670 	 */
1671 	if (hard_reset_done) {
1672 		rc = handlers = 0;
1673 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1674 			if ((ret == 0) && MptResetHandlers[ii]) {
1675 				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1676 						ioc->name, ii));
1677 				rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1678 				handlers++;
1679 			}
1680 
1681 			if (alt_ioc_ready && MptResetHandlers[ii]) {
1682 				dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1683 						ioc->name, ioc->alt_ioc->name, ii));
1684 				rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1685 				handlers++;
1686 			}
1687 		}
1688 		/* FIXME?  Examine results here? */
1689 	}
1690 
1691 	return ret;
1692 }
1693 
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1695 /*
1696  *	mpt_detect_bound_ports - Search for PCI bus/dev_function
1697  *	which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1698  *	929X, 1030 or 1035.
1699  *	@ioc: Pointer to MPT adapter structure
1700  *	@pdev: Pointer to (struct pci_dev) structure
1701  *
1702  *	If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1703  *	using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1704  */
1705 static void
1706 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1707 {
1708 	struct pci_dev *peer=NULL;
1709 	unsigned int slot = PCI_SLOT(pdev->devfn);
1710 	unsigned int func = PCI_FUNC(pdev->devfn);
1711 	MPT_ADAPTER *ioc_srch;
1712 
1713 	dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1714 	    " searching for devfn match on %x or %x\n",
1715 		ioc->name, pci_name(pdev), pdev->devfn,
1716 		func-1, func+1));
1717 
1718 	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1719 	if (!peer) {
1720 		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1721 		if (!peer)
1722 			return;
1723 	}
1724 
1725 	list_for_each_entry(ioc_srch, &ioc_list, list) {
1726 		struct pci_dev *_pcidev = ioc_srch->pcidev;
1727 		if (_pcidev == peer) {
1728 			/* Paranoia checks */
1729 			if (ioc->alt_ioc != NULL) {
1730 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1731 					ioc->name, ioc->alt_ioc->name);
1732 				break;
1733 			} else if (ioc_srch->alt_ioc != NULL) {
1734 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1735 					ioc_srch->name, ioc_srch->alt_ioc->name);
1736 				break;
1737 			}
1738 			dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1739 				ioc->name, ioc_srch->name));
1740 			ioc_srch->alt_ioc = ioc;
1741 			ioc->alt_ioc = ioc_srch;
1742 		}
1743 	}
1744 	pci_dev_put(peer);
1745 }
1746 
1747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1748 /*
1749  *	mpt_adapter_disable - Disable misbehaving MPT adapter.
1750  *	@this: Pointer to MPT adapter structure
1751  */
1752 static void
1753 mpt_adapter_disable(MPT_ADAPTER *ioc)
1754 {
1755 	int sz;
1756 	int ret;
1757 
1758 	if (ioc->cached_fw != NULL) {
1759 		ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1760 		if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1761 			printk(KERN_WARNING MYNAM
1762 				": firmware downloadboot failure (%d)!\n", ret);
1763 		}
1764 	}
1765 
1766 	/* Disable adapter interrupts! */
1767 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1768 	ioc->active = 0;
1769 	/* Clear any lingering interrupt */
1770 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1771 
1772 	if (ioc->alloc != NULL) {
1773 		sz = ioc->alloc_sz;
1774 		dexitprintk((KERN_INFO MYNAM ": %s.free  @ %p, sz=%d bytes\n",
1775 		 	ioc->name, ioc->alloc, ioc->alloc_sz));
1776 		pci_free_consistent(ioc->pcidev, sz,
1777 				ioc->alloc, ioc->alloc_dma);
1778 		ioc->reply_frames = NULL;
1779 		ioc->req_frames = NULL;
1780 		ioc->alloc = NULL;
1781 		ioc->alloc_total -= sz;
1782 	}
1783 
1784 	if (ioc->sense_buf_pool != NULL) {
1785 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1786 		pci_free_consistent(ioc->pcidev, sz,
1787 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1788 		ioc->sense_buf_pool = NULL;
1789 		ioc->alloc_total -= sz;
1790 	}
1791 
1792 	if (ioc->events != NULL){
1793 		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1794 		kfree(ioc->events);
1795 		ioc->events = NULL;
1796 		ioc->alloc_total -= sz;
1797 	}
1798 
1799 	if (ioc->cached_fw != NULL) {
1800 		sz = ioc->facts.FWImageSize;
1801 		pci_free_consistent(ioc->pcidev, sz,
1802 			ioc->cached_fw, ioc->cached_fw_dma);
1803 		ioc->cached_fw = NULL;
1804 		ioc->alloc_total -= sz;
1805 	}
1806 
1807 	if (ioc->spi_data.nvram != NULL) {
1808 		kfree(ioc->spi_data.nvram);
1809 		ioc->spi_data.nvram = NULL;
1810 	}
1811 
1812 	if (ioc->spi_data.pIocPg3 != NULL) {
1813 		kfree(ioc->spi_data.pIocPg3);
1814 		ioc->spi_data.pIocPg3 = NULL;
1815 	}
1816 
1817 	if (ioc->spi_data.pIocPg4 != NULL) {
1818 		sz = ioc->spi_data.IocPg4Sz;
1819 		pci_free_consistent(ioc->pcidev, sz,
1820 			ioc->spi_data.pIocPg4,
1821 			ioc->spi_data.IocPg4_dma);
1822 		ioc->spi_data.pIocPg4 = NULL;
1823 		ioc->alloc_total -= sz;
1824 	}
1825 
1826 	if (ioc->ReqToChain != NULL) {
1827 		kfree(ioc->ReqToChain);
1828 		kfree(ioc->RequestNB);
1829 		ioc->ReqToChain = NULL;
1830 	}
1831 
1832 	if (ioc->ChainToChain != NULL) {
1833 		kfree(ioc->ChainToChain);
1834 		ioc->ChainToChain = NULL;
1835 	}
1836 }
1837 
1838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1839 /*
1840  *	mpt_adapter_dispose - Free all resources associated with a MPT
1841  *	adapter.
1842  *	@ioc: Pointer to MPT adapter structure
1843  *
1844  *	This routine unregisters h/w resources and frees all alloc'd memory
1845  *	associated with a MPT adapter structure.
1846  */
1847 static void
1848 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1849 {
1850 	if (ioc != NULL) {
1851 		int sz_first, sz_last;
1852 
1853 		sz_first = ioc->alloc_total;
1854 
1855 		mpt_adapter_disable(ioc);
1856 
1857 		if (ioc->pci_irq != -1) {
1858 			free_irq(ioc->pci_irq, ioc);
1859 			ioc->pci_irq = -1;
1860 		}
1861 
1862 		if (ioc->memmap != NULL)
1863 			iounmap(ioc->memmap);
1864 
1865 #if defined(CONFIG_MTRR) && 0
1866 		if (ioc->mtrr_reg > 0) {
1867 			mtrr_del(ioc->mtrr_reg, 0, 0);
1868 			dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1869 		}
1870 #endif
1871 
1872 		/*  Zap the adapter lookup ptr!  */
1873 		list_del(&ioc->list);
1874 
1875 		sz_last = ioc->alloc_total;
1876 		dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1877 				ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1878 		kfree(ioc);
1879 	}
1880 }
1881 
1882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1883 /*
1884  *	MptDisplayIocCapabilities - Disply IOC's capacilities.
1885  *	@ioc: Pointer to MPT adapter structure
1886  */
1887 static void
1888 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1889 {
1890 	int i = 0;
1891 
1892 	printk(KERN_INFO "%s: ", ioc->name);
1893 	if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1894 		printk("%s: ", ioc->prod_name+3);
1895 	printk("Capabilities={");
1896 
1897 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1898 		printk("Initiator");
1899 		i++;
1900 	}
1901 
1902 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1903 		printk("%sTarget", i ? "," : "");
1904 		i++;
1905 	}
1906 
1907 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1908 		printk("%sLAN", i ? "," : "");
1909 		i++;
1910 	}
1911 
1912 #if 0
1913 	/*
1914 	 *  This would probably evoke more questions than it's worth
1915 	 */
1916 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1917 		printk("%sLogBusAddr", i ? "," : "");
1918 		i++;
1919 	}
1920 #endif
1921 
1922 	printk("}\n");
1923 }
1924 
1925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1926 /*
1927  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1928  *	@ioc: Pointer to MPT_ADAPTER structure
1929  *	@force: Force hard KickStart of IOC
1930  *	@sleepFlag: Specifies whether the process can sleep
1931  *
1932  *	Returns:
1933  *		 1 - DIAG reset and READY
1934  *		 0 - READY initially OR soft reset and READY
1935  *		-1 - Any failure on KickStart
1936  *		-2 - Msg Unit Reset Failed
1937  *		-3 - IO Unit Reset Failed
1938  *		-4 - IOC owned by a PEER
1939  */
1940 static int
1941 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1942 {
1943 	u32	 ioc_state;
1944 	int	 statefault = 0;
1945 	int	 cntdn;
1946 	int	 hard_reset_done = 0;
1947 	int	 r;
1948 	int	 ii;
1949 	int	 whoinit;
1950 
1951 	/* Get current [raw] IOC state  */
1952 	ioc_state = mpt_GetIocState(ioc, 0);
1953 	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1954 
1955 	/*
1956 	 *	Check to see if IOC got left/stuck in doorbell handshake
1957 	 *	grip of death.  If so, hard reset the IOC.
1958 	 */
1959 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
1960 		statefault = 1;
1961 		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1962 				ioc->name);
1963 	}
1964 
1965 	/* Is it already READY? */
1966 	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
1967 		return 0;
1968 
1969 	/*
1970 	 *	Check to see if IOC is in FAULT state.
1971 	 */
1972 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
1973 		statefault = 2;
1974 		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
1975 				ioc->name);
1976 		printk(KERN_WARNING "           FAULT code = %04xh\n",
1977 				ioc_state & MPI_DOORBELL_DATA_MASK);
1978 	}
1979 
1980 	/*
1981 	 *	Hmmm...  Did it get left operational?
1982 	 */
1983 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
1984 		dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
1985 				ioc->name));
1986 
1987 		/* Check WhoInit.
1988 		 * If PCI Peer, exit.
1989 		 * Else, if no fault conditions are present, issue a MessageUnitReset
1990 		 * Else, fall through to KickStart case
1991 		 */
1992 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
1993 		dprintk((KERN_WARNING MYNAM
1994 			": whoinit 0x%x\n statefault %d force %d\n",
1995 			whoinit, statefault, force));
1996 		if (whoinit == MPI_WHOINIT_PCI_PEER)
1997 			return -4;
1998 		else {
1999 			if ((statefault == 0 ) && (force == 0)) {
2000 				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2001 					return 0;
2002 			}
2003 			statefault = 3;
2004 		}
2005 	}
2006 
2007 	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2008 	if (hard_reset_done < 0)
2009 		return -1;
2010 
2011 	/*
2012 	 *  Loop here waiting for IOC to come READY.
2013 	 */
2014 	ii = 0;
2015 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
2016 
2017 	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2018 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2019 			/*
2020 			 *  BIOS or previous driver load left IOC in OP state.
2021 			 *  Reset messaging FIFOs.
2022 			 */
2023 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2024 				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2025 				return -2;
2026 			}
2027 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
2028 			/*
2029 			 *  Something is wrong.  Try to get IOC back
2030 			 *  to a known state.
2031 			 */
2032 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2033 				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2034 				return -3;
2035 			}
2036 		}
2037 
2038 		ii++; cntdn--;
2039 		if (!cntdn) {
2040 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2041 					ioc->name, (int)((ii+5)/HZ));
2042 			return -ETIME;
2043 		}
2044 
2045 		if (sleepFlag == CAN_SLEEP) {
2046 			msleep_interruptible(1);
2047 		} else {
2048 			mdelay (1);	/* 1 msec delay */
2049 		}
2050 
2051 	}
2052 
2053 	if (statefault < 3) {
2054 		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2055 				ioc->name,
2056 				statefault==1 ? "stuck handshake" : "IOC FAULT");
2057 	}
2058 
2059 	return hard_reset_done;
2060 }
2061 
2062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2063 /*
2064  *	mpt_GetIocState - Get the current state of a MPT adapter.
2065  *	@ioc: Pointer to MPT_ADAPTER structure
2066  *	@cooked: Request raw or cooked IOC state
2067  *
2068  *	Returns all IOC Doorbell register bits if cooked==0, else just the
2069  *	Doorbell bits in MPI_IOC_STATE_MASK.
2070  */
2071 u32
2072 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2073 {
2074 	u32 s, sc;
2075 
2076 	/*  Get!  */
2077 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
2078 //	dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2079 	sc = s & MPI_IOC_STATE_MASK;
2080 
2081 	/*  Save!  */
2082 	ioc->last_state = sc;
2083 
2084 	return cooked ? sc : s;
2085 }
2086 
2087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2088 /*
2089  *	GetIocFacts - Send IOCFacts request to MPT adapter.
2090  *	@ioc: Pointer to MPT_ADAPTER structure
2091  *	@sleepFlag: Specifies whether the process can sleep
2092  *	@reason: If recovery, only update facts.
2093  *
2094  *	Returns 0 for success, non-zero for failure.
2095  */
2096 static int
2097 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2098 {
2099 	IOCFacts_t		 get_facts;
2100 	IOCFactsReply_t		*facts;
2101 	int			 r;
2102 	int			 req_sz;
2103 	int			 reply_sz;
2104 	int			 sz;
2105 	u32			 status, vv;
2106 	u8			 shiftFactor=1;
2107 
2108 	/* IOC *must* NOT be in RESET state! */
2109 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2110 		printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2111 				ioc->name,
2112 				ioc->last_state );
2113 		return -44;
2114 	}
2115 
2116 	facts = &ioc->facts;
2117 
2118 	/* Destination (reply area)... */
2119 	reply_sz = sizeof(*facts);
2120 	memset(facts, 0, reply_sz);
2121 
2122 	/* Request area (get_facts on the stack right now!) */
2123 	req_sz = sizeof(get_facts);
2124 	memset(&get_facts, 0, req_sz);
2125 
2126 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2127 	/* Assert: All other get_facts fields are zero! */
2128 
2129 	dinitprintk((MYIOC_s_INFO_FMT
2130 	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2131 	    ioc->name, req_sz, reply_sz));
2132 
2133 	/* No non-zero fields in the get_facts request are greater than
2134 	 * 1 byte in size, so we can just fire it off as is.
2135 	 */
2136 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2137 			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2138 	if (r != 0)
2139 		return r;
2140 
2141 	/*
2142 	 * Now byte swap (GRRR) the necessary fields before any further
2143 	 * inspection of reply contents.
2144 	 *
2145 	 * But need to do some sanity checks on MsgLength (byte) field
2146 	 * to make sure we don't zero IOC's req_sz!
2147 	 */
2148 	/* Did we get a valid reply? */
2149 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2150 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2151 			/*
2152 			 * If not been here, done that, save off first WhoInit value
2153 			 */
2154 			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2155 				ioc->FirstWhoInit = facts->WhoInit;
2156 		}
2157 
2158 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2159 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
2160 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2161 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2162 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2163 		status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2164 		/* CHECKME! IOCStatus, IOCLogInfo */
2165 
2166 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2167 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2168 
2169 		/*
2170 		 * FC f/w version changed between 1.1 and 1.2
2171 		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
2172 		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2173 		 */
2174 		if (facts->MsgVersion < 0x0102) {
2175 			/*
2176 			 *	Handle old FC f/w style, convert to new...
2177 			 */
2178 			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2179 			facts->FWVersion.Word =
2180 					((oldv<<12) & 0xFF000000) |
2181 					((oldv<<8)  & 0x000FFF00);
2182 		} else
2183 			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2184 
2185 		facts->ProductID = le16_to_cpu(facts->ProductID);
2186 		facts->CurrentHostMfaHighAddr =
2187 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
2188 		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2189 		facts->CurrentSenseBufferHighAddr =
2190 				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2191 		facts->CurReplyFrameSize =
2192 				le16_to_cpu(facts->CurReplyFrameSize);
2193 
2194 		/*
2195 		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2196 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2197 		 * to 14 in MPI-1.01.0x.
2198 		 */
2199 		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2200 		    facts->MsgVersion > 0x0100) {
2201 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2202 		}
2203 
2204 		sz = facts->FWImageSize;
2205 		if ( sz & 0x01 )
2206 			sz += 1;
2207 		if ( sz & 0x02 )
2208 			sz += 2;
2209 		facts->FWImageSize = sz;
2210 
2211 		if (!facts->RequestFrameSize) {
2212 			/*  Something is wrong!  */
2213 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2214 					ioc->name);
2215 			return -55;
2216 		}
2217 
2218 		r = sz = facts->BlockSize;
2219 		vv = ((63 / (sz * 4)) + 1) & 0x03;
2220 		ioc->NB_for_64_byte_frame = vv;
2221 		while ( sz )
2222 		{
2223 			shiftFactor++;
2224 			sz = sz >> 1;
2225 		}
2226 		ioc->NBShiftFactor  = shiftFactor;
2227 		dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2228 					ioc->name, vv, shiftFactor, r));
2229 
2230 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2231 			/*
2232 			 * Set values for this IOC's request & reply frame sizes,
2233 			 * and request & reply queue depths...
2234 			 */
2235 			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2236 			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2237 			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2238 			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2239 
2240 			dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2241 				ioc->name, ioc->reply_sz, ioc->reply_depth));
2242 			dinitprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
2243 				ioc->name, ioc->req_sz, ioc->req_depth));
2244 
2245 			/* Get port facts! */
2246 			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2247 				return r;
2248 		}
2249 	} else {
2250 		printk(MYIOC_s_ERR_FMT
2251 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2252 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2253 		     RequestFrameSize)/sizeof(u32)));
2254 		return -66;
2255 	}
2256 
2257 	return 0;
2258 }
2259 
2260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2261 /*
2262  *	GetPortFacts - Send PortFacts request to MPT adapter.
2263  *	@ioc: Pointer to MPT_ADAPTER structure
2264  *	@portnum: Port number
2265  *	@sleepFlag: Specifies whether the process can sleep
2266  *
2267  *	Returns 0 for success, non-zero for failure.
2268  */
2269 static int
2270 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2271 {
2272 	PortFacts_t		 get_pfacts;
2273 	PortFactsReply_t	*pfacts;
2274 	int			 ii;
2275 	int			 req_sz;
2276 	int			 reply_sz;
2277 
2278 	/* IOC *must* NOT be in RESET state! */
2279 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2280 		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2281 				ioc->name,
2282 				ioc->last_state );
2283 		return -4;
2284 	}
2285 
2286 	pfacts = &ioc->pfacts[portnum];
2287 
2288 	/* Destination (reply area)...  */
2289 	reply_sz = sizeof(*pfacts);
2290 	memset(pfacts, 0, reply_sz);
2291 
2292 	/* Request area (get_pfacts on the stack right now!) */
2293 	req_sz = sizeof(get_pfacts);
2294 	memset(&get_pfacts, 0, req_sz);
2295 
2296 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2297 	get_pfacts.PortNumber = portnum;
2298 	/* Assert: All other get_pfacts fields are zero! */
2299 
2300 	dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2301 			ioc->name, portnum));
2302 
2303 	/* No non-zero fields in the get_pfacts request are greater than
2304 	 * 1 byte in size, so we can just fire it off as is.
2305 	 */
2306 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2307 				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2308 	if (ii != 0)
2309 		return ii;
2310 
2311 	/* Did we get a valid reply? */
2312 
2313 	/* Now byte swap the necessary fields in the response. */
2314 	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2315 	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2316 	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2317 	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2318 	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2319 	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2320 	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2321 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2322 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2323 
2324 	return 0;
2325 }
2326 
2327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2328 /*
2329  *	SendIocInit - Send IOCInit request to MPT adapter.
2330  *	@ioc: Pointer to MPT_ADAPTER structure
2331  *	@sleepFlag: Specifies whether the process can sleep
2332  *
2333  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2334  *
2335  *	Returns 0 for success, non-zero for failure.
2336  */
2337 static int
2338 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2339 {
2340 	IOCInit_t		 ioc_init;
2341 	MPIDefaultReply_t	 init_reply;
2342 	u32			 state;
2343 	int			 r;
2344 	int			 count;
2345 	int			 cntdn;
2346 
2347 	memset(&ioc_init, 0, sizeof(ioc_init));
2348 	memset(&init_reply, 0, sizeof(init_reply));
2349 
2350 	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2351 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2352 
2353 	/* If we are in a recovery mode and we uploaded the FW image,
2354 	 * then this pointer is not NULL. Skip the upload a second time.
2355 	 * Set this flag if cached_fw set for either IOC.
2356 	 */
2357 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2358 		ioc->upload_fw = 1;
2359 	else
2360 		ioc->upload_fw = 0;
2361 	ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2362 		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
2363 
2364 	if (ioc->bus_type == FC)
2365 		ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2366 	else
2367 		ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2368 
2369 	ioc_init.MaxBuses = MPT_MAX_BUS;
2370 
2371 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
2372 
2373 	if (sizeof(dma_addr_t) == sizeof(u64)) {
2374 		/* Save the upper 32-bits of the request
2375 		 * (reply) and sense buffers.
2376 		 */
2377 		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2378 		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2379 	} else {
2380 		/* Force 32-bit addressing */
2381 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2382 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2383 	}
2384 
2385 	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2386 	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2387 
2388 	dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2389 			ioc->name, &ioc_init));
2390 
2391 	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2392 				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2393 	if (r != 0)
2394 		return r;
2395 
2396 	/* No need to byte swap the multibyte fields in the reply
2397 	 * since we don't even look at it's contents.
2398 	 */
2399 
2400 	dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2401 			ioc->name, &ioc_init));
2402 
2403 	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2404 		return r;
2405 
2406 	/* YIKES!  SUPER IMPORTANT!!!
2407 	 *  Poll IocState until _OPERATIONAL while IOC is doing
2408 	 *  LoopInit and TargetDiscovery!
2409 	 */
2410 	count = 0;
2411 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
2412 	state = mpt_GetIocState(ioc, 1);
2413 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2414 		if (sleepFlag == CAN_SLEEP) {
2415 			msleep_interruptible(1);
2416 		} else {
2417 			mdelay(1);
2418 		}
2419 
2420 		if (!cntdn) {
2421 			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2422 					ioc->name, (int)((count+5)/HZ));
2423 			return -9;
2424 		}
2425 
2426 		state = mpt_GetIocState(ioc, 1);
2427 		count++;
2428 	}
2429 	dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2430 			ioc->name, count));
2431 
2432 	return r;
2433 }
2434 
2435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2436 /*
2437  *	SendPortEnable - Send PortEnable request to MPT adapter port.
2438  *	@ioc: Pointer to MPT_ADAPTER structure
2439  *	@portnum: Port number to enable
2440  *	@sleepFlag: Specifies whether the process can sleep
2441  *
2442  *	Send PortEnable to bring IOC to OPERATIONAL state.
2443  *
2444  *	Returns 0 for success, non-zero for failure.
2445  */
2446 static int
2447 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2448 {
2449 	PortEnable_t		 port_enable;
2450 	MPIDefaultReply_t	 reply_buf;
2451 	int	 ii;
2452 	int	 req_sz;
2453 	int	 reply_sz;
2454 
2455 	/*  Destination...  */
2456 	reply_sz = sizeof(MPIDefaultReply_t);
2457 	memset(&reply_buf, 0, reply_sz);
2458 
2459 	req_sz = sizeof(PortEnable_t);
2460 	memset(&port_enable, 0, req_sz);
2461 
2462 	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2463 	port_enable.PortNumber = portnum;
2464 /*	port_enable.ChainOffset = 0;		*/
2465 /*	port_enable.MsgFlags = 0;		*/
2466 /*	port_enable.MsgContext = 0;		*/
2467 
2468 	dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2469 			ioc->name, portnum, &port_enable));
2470 
2471 	/* RAID FW may take a long time to enable
2472 	 */
2473 	if (ioc->bus_type == FC) {
2474 		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2475 				reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2476 	} else {
2477 		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2478 				reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2479 	}
2480 
2481 	if (ii != 0)
2482 		return ii;
2483 
2484 	/* We do not even look at the reply, so we need not
2485 	 * swap the multi-byte fields.
2486 	 */
2487 
2488 	return 0;
2489 }
2490 
2491 /*
2492  *	ioc: Pointer to MPT_ADAPTER structure
2493  *      size - total FW bytes
2494  */
2495 void
2496 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2497 {
2498 	if (ioc->cached_fw)
2499 		return;  /* use already allocated memory */
2500 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2501 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2502 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2503 	} else {
2504 		if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2505 			ioc->alloc_total += size;
2506 	}
2507 }
2508 /*
2509  * If alt_img is NULL, delete from ioc structure.
2510  * Else, delete a secondary image in same format.
2511  */
2512 void
2513 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2514 {
2515 	int sz;
2516 
2517 	sz = ioc->facts.FWImageSize;
2518 	dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2519 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2520 	pci_free_consistent(ioc->pcidev, sz,
2521 			ioc->cached_fw, ioc->cached_fw_dma);
2522 	ioc->cached_fw = NULL;
2523 
2524 	return;
2525 }
2526 
2527 
2528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2529 /*
2530  *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2531  *	@ioc: Pointer to MPT_ADAPTER structure
2532  *	@sleepFlag: Specifies whether the process can sleep
2533  *
2534  *	Returns 0 for success, >0 for handshake failure
2535  *		<0 for fw upload failure.
2536  *
2537  *	Remark: If bound IOC and a successful FWUpload was performed
2538  *	on the bound IOC, the second image is discarded
2539  *	and memory is free'd. Both channels must upload to prevent
2540  *	IOC from running in degraded mode.
2541  */
2542 static int
2543 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2544 {
2545 	u8			 request[ioc->req_sz];
2546 	u8			 reply[sizeof(FWUploadReply_t)];
2547 	FWUpload_t		*prequest;
2548 	FWUploadReply_t		*preply;
2549 	FWUploadTCSGE_t		*ptcsge;
2550 	int			 sgeoffset;
2551 	u32			 flagsLength;
2552 	int			 ii, sz, reply_sz;
2553 	int			 cmdStatus;
2554 
2555 	/* If the image size is 0, we are done.
2556 	 */
2557 	if ((sz = ioc->facts.FWImageSize) == 0)
2558 		return 0;
2559 
2560 	mpt_alloc_fw_memory(ioc, sz);
2561 
2562 	dinitprintk((KERN_WARNING MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2563 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2564 
2565 	if (ioc->cached_fw == NULL) {
2566 		/* Major Failure.
2567 		 */
2568 		return -ENOMEM;
2569 	}
2570 
2571 	prequest = (FWUpload_t *)&request;
2572 	preply = (FWUploadReply_t *)&reply;
2573 
2574 	/*  Destination...  */
2575 	memset(prequest, 0, ioc->req_sz);
2576 
2577 	reply_sz = sizeof(reply);
2578 	memset(preply, 0, reply_sz);
2579 
2580 	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2581 	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2582 
2583 	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2584 	ptcsge->DetailsLength = 12;
2585 	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2586 	ptcsge->ImageSize = cpu_to_le32(sz);
2587 
2588 	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2589 
2590 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2591 	mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2592 
2593 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2594 	dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2595 			prequest, sgeoffset));
2596 	DBG_DUMP_FW_REQUEST_FRAME(prequest)
2597 
2598 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2599 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2600 
2601 	dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2602 
2603 	cmdStatus = -EFAULT;
2604 	if (ii == 0) {
2605 		/* Handshake transfer was complete and successful.
2606 		 * Check the Reply Frame.
2607 		 */
2608 		int status, transfer_sz;
2609 		status = le16_to_cpu(preply->IOCStatus);
2610 		if (status == MPI_IOCSTATUS_SUCCESS) {
2611 			transfer_sz = le32_to_cpu(preply->ActualImageSize);
2612 			if (transfer_sz == sz)
2613 				cmdStatus = 0;
2614 		}
2615 	}
2616 	dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2617 			ioc->name, cmdStatus));
2618 
2619 
2620 	if (cmdStatus) {
2621 
2622 		ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2623 			ioc->name));
2624 		mpt_free_fw_memory(ioc);
2625 	}
2626 
2627 	return cmdStatus;
2628 }
2629 
2630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2631 /*
2632  *	mpt_downloadboot - DownloadBoot code
2633  *	@ioc: Pointer to MPT_ADAPTER structure
2634  *	@flag: Specify which part of IOC memory is to be uploaded.
2635  *	@sleepFlag: Specifies whether the process can sleep
2636  *
2637  *	FwDownloadBoot requires Programmed IO access.
2638  *
2639  *	Returns 0 for success
2640  *		-1 FW Image size is 0
2641  *		-2 No valid cached_fw Pointer
2642  *		<0 for fw upload failure.
2643  */
2644 static int
2645 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2646 {
2647 	MpiFwHeader_t		*pFwHeader;
2648 	MpiExtImageHeader_t	*pExtImage;
2649 	u32			 fwSize;
2650 	u32			 diag0val;
2651 	int			 count;
2652 	u32			*ptrFw;
2653 	u32			 diagRwData;
2654 	u32			 nextImage;
2655 	u32			 load_addr;
2656 	u32 			 ioc_state=0;
2657 
2658 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2659 				ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2660 
2661 	if ( ioc->facts.FWImageSize == 0 )
2662 		return -1;
2663 
2664 	if (ioc->cached_fw == NULL)
2665 		return -2;
2666 
2667 	/* prevent a second downloadboot and memory free with alt_ioc */
2668 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2669 		ioc->alt_ioc->cached_fw = NULL;
2670 
2671 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2672 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2673 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2674 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2675 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2676 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2677 
2678 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2679 
2680 	/* wait 1 msec */
2681 	if (sleepFlag == CAN_SLEEP) {
2682 		msleep_interruptible(1);
2683 	} else {
2684 		mdelay (1);
2685 	}
2686 
2687 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2688 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2689 
2690 	for (count = 0; count < 30; count ++) {
2691 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2692 		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2693 			ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2694 				ioc->name, count));
2695 			break;
2696 		}
2697 		/* wait 1 sec */
2698 		if (sleepFlag == CAN_SLEEP) {
2699 			msleep_interruptible (1000);
2700 		} else {
2701 			mdelay (1000);
2702 		}
2703 	}
2704 
2705 	if ( count == 30 ) {
2706 		ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2707 		ioc->name, diag0val));
2708 		return -3;
2709 	}
2710 
2711 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2712 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2713 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2714 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2715 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2716 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2717 
2718 	/* Set the DiagRwEn and Disable ARM bits */
2719 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2720 
2721 	pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2722 	fwSize = (pFwHeader->ImageSize + 3)/4;
2723 	ptrFw = (u32 *) pFwHeader;
2724 
2725 	/* Write the LoadStartAddress to the DiagRw Address Register
2726 	 * using Programmed IO
2727 	 */
2728 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2729 	ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2730 		ioc->name, pFwHeader->LoadStartAddress));
2731 
2732 	ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2733 				ioc->name, fwSize*4, ptrFw));
2734 	while (fwSize--) {
2735 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2736 	}
2737 
2738 	nextImage = pFwHeader->NextImageHeaderOffset;
2739 	while (nextImage) {
2740 		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2741 
2742 		load_addr = pExtImage->LoadStartAddress;
2743 
2744 		fwSize = (pExtImage->ImageSize + 3) >> 2;
2745 		ptrFw = (u32 *)pExtImage;
2746 
2747 		ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2748 						ioc->name, fwSize*4, ptrFw, load_addr));
2749 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2750 
2751 		while (fwSize--) {
2752 			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2753 		}
2754 		nextImage = pExtImage->NextImageHeaderOffset;
2755 	}
2756 
2757 	/* Write the IopResetVectorRegAddr */
2758 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
2759 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2760 
2761 	/* Write the IopResetVectorValue */
2762 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2763 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2764 
2765 	/* Clear the internal flash bad bit - autoincrementing register,
2766 	 * so must do two writes.
2767 	 */
2768 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2769 	diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2770 	diagRwData |= 0x4000000;
2771 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2772 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2773 
2774 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2775 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2776 		ioc->name, diag0val));
2777 	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2778 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2779 		ioc->name, diag0val));
2780 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2781 
2782 	/* Write 0xFF to reset the sequencer */
2783 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2784 
2785 	for (count=0; count<HZ*20; count++) {
2786 		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2787 			ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2788 					ioc->name, count, ioc_state));
2789 			if ((SendIocInit(ioc, sleepFlag)) != 0) {
2790 				ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2791 					ioc->name));
2792 				return -EFAULT;
2793 			}
2794 			ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2795 					ioc->name));
2796 			return 0;
2797 		}
2798 		if (sleepFlag == CAN_SLEEP) {
2799 			msleep_interruptible (10);
2800 		} else {
2801 			mdelay (10);
2802 		}
2803 	}
2804 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2805 		ioc->name, ioc_state));
2806 	return -EFAULT;
2807 }
2808 
2809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2810 /*
2811  *	KickStart - Perform hard reset of MPT adapter.
2812  *	@ioc: Pointer to MPT_ADAPTER structure
2813  *	@force: Force hard reset
2814  *	@sleepFlag: Specifies whether the process can sleep
2815  *
2816  *	This routine places MPT adapter in diagnostic mode via the
2817  *	WriteSequence register, and then performs a hard reset of adapter
2818  *	via the Diagnostic register.
2819  *
2820  *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
2821  *			or NO_SLEEP (interrupt thread, use mdelay)
2822  *		  force - 1 if doorbell active, board fault state
2823  *				board operational, IOC_RECOVERY or
2824  *				IOC_BRINGUP and there is an alt_ioc.
2825  *			  0 else
2826  *
2827  *	Returns:
2828  *		 1 - hard reset, READY
2829  *		 0 - no reset due to History bit, READY
2830  *		-1 - no reset due to History bit but not READY
2831  *		     OR reset but failed to come READY
2832  *		-2 - no reset, could not enter DIAG mode
2833  *		-3 - reset but bad FW bit
2834  */
2835 static int
2836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2837 {
2838 	int hard_reset_done = 0;
2839 	u32 ioc_state=0;
2840 	int cnt,cntdn;
2841 
2842 	dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2843 	if (ioc->bus_type == SCSI) {
2844 		/* Always issue a Msg Unit Reset first. This will clear some
2845 		 * SCSI bus hang conditions.
2846 		 */
2847 		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2848 
2849 		if (sleepFlag == CAN_SLEEP) {
2850 			msleep_interruptible (1000);
2851 		} else {
2852 			mdelay (1000);
2853 		}
2854 	}
2855 
2856 	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2857 	if (hard_reset_done < 0)
2858 		return hard_reset_done;
2859 
2860 	dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2861 			ioc->name));
2862 
2863 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;	/* 2 seconds */
2864 	for (cnt=0; cnt<cntdn; cnt++) {
2865 		ioc_state = mpt_GetIocState(ioc, 1);
2866 		if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2867 			dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2868  					ioc->name, cnt));
2869 			return hard_reset_done;
2870 		}
2871 		if (sleepFlag == CAN_SLEEP) {
2872 			msleep_interruptible (10);
2873 		} else {
2874 			mdelay (10);
2875 		}
2876 	}
2877 
2878 	printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2879 			ioc->name, ioc_state);
2880 	return -1;
2881 }
2882 
2883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2884 /*
2885  *	mpt_diag_reset - Perform hard reset of the adapter.
2886  *	@ioc: Pointer to MPT_ADAPTER structure
2887  *	@ignore: Set if to honor and clear to ignore
2888  *		the reset history bit
2889  *	@sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2890  *		else set to NO_SLEEP (use mdelay instead)
2891  *
2892  *	This routine places the adapter in diagnostic mode via the
2893  *	WriteSequence register and then performs a hard reset of adapter
2894  *	via the Diagnostic register. Adapter should be in ready state
2895  *	upon successful completion.
2896  *
2897  *	Returns:  1  hard reset successful
2898  *		  0  no reset performed because reset history bit set
2899  *		 -2  enabling diagnostic mode failed
2900  *		 -3  diagnostic reset failed
2901  */
2902 static int
2903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2904 {
2905 	u32 diag0val;
2906 	u32 doorbell;
2907 	int hard_reset_done = 0;
2908 	int count = 0;
2909 #ifdef MPT_DEBUG
2910 	u32 diag1val = 0;
2911 #endif
2912 
2913 	/* Clear any existing interrupts */
2914 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2915 
2916 	/* Use "Diagnostic reset" method! (only thing available!) */
2917 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2918 
2919 #ifdef MPT_DEBUG
2920 	if (ioc->alt_ioc)
2921 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2922 	dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2923 			ioc->name, diag0val, diag1val));
2924 #endif
2925 
2926 	/* Do the reset if we are told to ignore the reset history
2927 	 * or if the reset history is 0
2928 	 */
2929 	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2930 		while ((diag0val & MPI_DIAG_DRWE) == 0) {
2931 			/* Write magic sequence to WriteSequence register
2932 			 * Loop until in diagnostic mode
2933 			 */
2934 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2935 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2936 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2937 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2938 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2939 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2940 
2941 			/* wait 100 msec */
2942 			if (sleepFlag == CAN_SLEEP) {
2943 				msleep_interruptible (100);
2944 			} else {
2945 				mdelay (100);
2946 			}
2947 
2948 			count++;
2949 			if (count > 20) {
2950 				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2951 						ioc->name, diag0val);
2952 				return -2;
2953 
2954 			}
2955 
2956 			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2957 
2958 			dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2959 					ioc->name, diag0val));
2960 		}
2961 
2962 #ifdef MPT_DEBUG
2963 		if (ioc->alt_ioc)
2964 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2965 		dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
2966 				ioc->name, diag0val, diag1val));
2967 #endif
2968 		/*
2969 		 * Disable the ARM (Bug fix)
2970 		 *
2971 		 */
2972 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
2973 		mdelay (1);
2974 
2975 		/*
2976 		 * Now hit the reset bit in the Diagnostic register
2977 		 * (THE BIG HAMMER!) (Clears DRWE bit).
2978 		 */
2979 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2980 		hard_reset_done = 1;
2981 		dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
2982 				ioc->name));
2983 
2984 		/*
2985 		 * Call each currently registered protocol IOC reset handler
2986 		 * with pre-reset indication.
2987 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2988 		 * MptResetHandlers[] registered yet.
2989 		 */
2990 		{
2991 			int	 ii;
2992 			int	 r = 0;
2993 
2994 			for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2995 				if (MptResetHandlers[ii]) {
2996 					dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
2997 							ioc->name, ii));
2998 					r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
2999 					if (ioc->alt_ioc) {
3000 						dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3001 								ioc->name, ioc->alt_ioc->name, ii));
3002 						r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3003 					}
3004 				}
3005 			}
3006 			/* FIXME?  Examine results here? */
3007 		}
3008 
3009 		if (ioc->cached_fw) {
3010 			/* If the DownloadBoot operation fails, the
3011 			 * IOC will be left unusable. This is a fatal error
3012 			 * case.  _diag_reset will return < 0
3013 			 */
3014 			for (count = 0; count < 30; count ++) {
3015 				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3016 				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3017 					break;
3018 				}
3019 
3020 				/* wait 1 sec */
3021 				if (sleepFlag == CAN_SLEEP) {
3022 					ssleep(1);
3023 				} else {
3024 					mdelay (1000);
3025 				}
3026 			}
3027 			if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3028 				printk(KERN_WARNING MYNAM
3029 					": firmware downloadboot failure (%d)!\n", count);
3030 			}
3031 
3032 		} else {
3033 			/* Wait for FW to reload and for board
3034 			 * to go to the READY state.
3035 			 * Maximum wait is 60 seconds.
3036 			 * If fail, no error will check again
3037 			 * with calling program.
3038 			 */
3039 			for (count = 0; count < 60; count ++) {
3040 				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3041 				doorbell &= MPI_IOC_STATE_MASK;
3042 
3043 				if (doorbell == MPI_IOC_STATE_READY) {
3044 					break;
3045 				}
3046 
3047 				/* wait 1 sec */
3048 				if (sleepFlag == CAN_SLEEP) {
3049 					msleep_interruptible (1000);
3050 				} else {
3051 					mdelay (1000);
3052 				}
3053 			}
3054 		}
3055 	}
3056 
3057 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3058 #ifdef MPT_DEBUG
3059 	if (ioc->alt_ioc)
3060 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3061 	dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3062 		ioc->name, diag0val, diag1val));
3063 #endif
3064 
3065 	/* Clear RESET_HISTORY bit!  Place board in the
3066 	 * diagnostic mode to update the diag register.
3067 	 */
3068 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3069 	count = 0;
3070 	while ((diag0val & MPI_DIAG_DRWE) == 0) {
3071 		/* Write magic sequence to WriteSequence register
3072 		 * Loop until in diagnostic mode
3073 		 */
3074 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3075 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3076 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3077 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3078 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3079 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3080 
3081 		/* wait 100 msec */
3082 		if (sleepFlag == CAN_SLEEP) {
3083 			msleep_interruptible (100);
3084 		} else {
3085 			mdelay (100);
3086 		}
3087 
3088 		count++;
3089 		if (count > 20) {
3090 			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3091 					ioc->name, diag0val);
3092 			break;
3093 		}
3094 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3095 	}
3096 	diag0val &= ~MPI_DIAG_RESET_HISTORY;
3097 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3098 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3099 	if (diag0val & MPI_DIAG_RESET_HISTORY) {
3100 		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3101 				ioc->name);
3102 	}
3103 
3104 	/* Disable Diagnostic Mode
3105 	 */
3106 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3107 
3108 	/* Check FW reload status flags.
3109 	 */
3110 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3111 	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3112 		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3113 				ioc->name, diag0val);
3114 		return -3;
3115 	}
3116 
3117 #ifdef MPT_DEBUG
3118 	if (ioc->alt_ioc)
3119 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3120 	dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3121 			ioc->name, diag0val, diag1val));
3122 #endif
3123 
3124 	/*
3125 	 * Reset flag that says we've enabled event notification
3126 	 */
3127 	ioc->facts.EventState = 0;
3128 
3129 	if (ioc->alt_ioc)
3130 		ioc->alt_ioc->facts.EventState = 0;
3131 
3132 	return hard_reset_done;
3133 }
3134 
3135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3136 /*
3137  *	SendIocReset - Send IOCReset request to MPT adapter.
3138  *	@ioc: Pointer to MPT_ADAPTER structure
3139  *	@reset_type: reset type, expected values are
3140  *	%MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3141  *
3142  *	Send IOCReset request to the MPT adapter.
3143  *
3144  *	Returns 0 for success, non-zero for failure.
3145  */
3146 static int
3147 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3148 {
3149 	int r;
3150 	u32 state;
3151 	int cntdn, count;
3152 
3153 	drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3154 			ioc->name, reset_type));
3155 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3156 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3157 		return r;
3158 
3159 	/* FW ACK'd request, wait for READY state
3160 	 */
3161 	count = 0;
3162 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
3163 
3164 	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3165 		cntdn--;
3166 		count++;
3167 		if (!cntdn) {
3168 			if (sleepFlag != CAN_SLEEP)
3169 				count *= 10;
3170 
3171 			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3172 					ioc->name, (int)((count+5)/HZ));
3173 			return -ETIME;
3174 		}
3175 
3176 		if (sleepFlag == CAN_SLEEP) {
3177 			msleep_interruptible(1);
3178 		} else {
3179 			mdelay (1);	/* 1 msec delay */
3180 		}
3181 	}
3182 
3183 	/* TODO!
3184 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
3185 	 *  request if needed.
3186 	 */
3187 	if (ioc->facts.Function)
3188 		ioc->facts.EventState = 0;
3189 
3190 	return 0;
3191 }
3192 
3193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3194 /*
3195  *	initChainBuffers - Allocate memory for and initialize
3196  *	chain buffers, chain buffer control arrays and spinlock.
3197  *	@hd: Pointer to MPT_SCSI_HOST structure
3198  *	@init: If set, initialize the spin lock.
3199  */
3200 static int
3201 initChainBuffers(MPT_ADAPTER *ioc)
3202 {
3203 	u8		*mem;
3204 	int		sz, ii, num_chain;
3205 	int 		scale, num_sge, numSGE;
3206 
3207 	/* ReqToChain size must equal the req_depth
3208 	 * index = req_idx
3209 	 */
3210 	if (ioc->ReqToChain == NULL) {
3211 		sz = ioc->req_depth * sizeof(int);
3212 		mem = kmalloc(sz, GFP_ATOMIC);
3213 		if (mem == NULL)
3214 			return -1;
3215 
3216 		ioc->ReqToChain = (int *) mem;
3217 		dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc  @ %p, sz=%d bytes\n",
3218 			 	ioc->name, mem, sz));
3219 		mem = kmalloc(sz, GFP_ATOMIC);
3220 		if (mem == NULL)
3221 			return -1;
3222 
3223 		ioc->RequestNB = (int *) mem;
3224 		dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc  @ %p, sz=%d bytes\n",
3225 			 	ioc->name, mem, sz));
3226 	}
3227 	for (ii = 0; ii < ioc->req_depth; ii++) {
3228 		ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3229 	}
3230 
3231 	/* ChainToChain size must equal the total number
3232 	 * of chain buffers to be allocated.
3233 	 * index = chain_idx
3234 	 *
3235 	 * Calculate the number of chain buffers needed(plus 1) per I/O
3236 	 * then multiply the the maximum number of simultaneous cmds
3237 	 *
3238 	 * num_sge = num sge in request frame + last chain buffer
3239 	 * scale = num sge per chain buffer if no chain element
3240 	 */
3241 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3242 	if (sizeof(dma_addr_t) == sizeof(u64))
3243 		num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3244 	else
3245 		num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3246 
3247 	if (sizeof(dma_addr_t) == sizeof(u64)) {
3248 		numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3249 			(ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3250 	} else {
3251 		numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3252 			(ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3253 	}
3254 	dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3255 		ioc->name, num_sge, numSGE));
3256 
3257 	if ( numSGE > MPT_SCSI_SG_DEPTH	)
3258 		numSGE = MPT_SCSI_SG_DEPTH;
3259 
3260 	num_chain = 1;
3261 	while (numSGE - num_sge > 0) {
3262 		num_chain++;
3263 		num_sge += (scale - 1);
3264 	}
3265 	num_chain++;
3266 
3267 	dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3268 		ioc->name, numSGE, num_sge, num_chain));
3269 
3270 	if (ioc->bus_type == SCSI)
3271 		num_chain *= MPT_SCSI_CAN_QUEUE;
3272 	else
3273 		num_chain *= MPT_FC_CAN_QUEUE;
3274 
3275 	ioc->num_chain = num_chain;
3276 
3277 	sz = num_chain * sizeof(int);
3278 	if (ioc->ChainToChain == NULL) {
3279 		mem = kmalloc(sz, GFP_ATOMIC);
3280 		if (mem == NULL)
3281 			return -1;
3282 
3283 		ioc->ChainToChain = (int *) mem;
3284 		dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3285 			 	ioc->name, mem, sz));
3286 	} else {
3287 		mem = (u8 *) ioc->ChainToChain;
3288 	}
3289 	memset(mem, 0xFF, sz);
3290 	return num_chain;
3291 }
3292 
3293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3294 /*
3295  *	PrimeIocFifos - Initialize IOC request and reply FIFOs.
3296  *	@ioc: Pointer to MPT_ADAPTER structure
3297  *
3298  *	This routine allocates memory for the MPT reply and request frame
3299  *	pools (if necessary), and primes the IOC reply FIFO with
3300  *	reply frames.
3301  *
3302  *	Returns 0 for success, non-zero for failure.
3303  */
3304 static int
3305 PrimeIocFifos(MPT_ADAPTER *ioc)
3306 {
3307 	MPT_FRAME_HDR *mf;
3308 	unsigned long flags;
3309 	dma_addr_t alloc_dma;
3310 	u8 *mem;
3311 	int i, reply_sz, sz, total_size, num_chain;
3312 
3313 	/*  Prime reply FIFO...  */
3314 
3315 	if (ioc->reply_frames == NULL) {
3316 		if ( (num_chain = initChainBuffers(ioc)) < 0)
3317 			return -1;
3318 
3319 		total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3320 		dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3321 			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
3322 		dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3323 			 	ioc->name, reply_sz, reply_sz));
3324 
3325 		sz = (ioc->req_sz * ioc->req_depth);
3326 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3327 			 	ioc->name, ioc->req_sz, ioc->req_depth));
3328 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3329 			 	ioc->name, sz, sz));
3330 		total_size += sz;
3331 
3332 		sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3333 		dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3334 			 	ioc->name, ioc->req_sz, num_chain));
3335 		dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3336 			 	ioc->name, sz, sz, num_chain));
3337 
3338 		total_size += sz;
3339 		mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3340 		if (mem == NULL) {
3341 			printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3342 				ioc->name);
3343 			goto out_fail;
3344 		}
3345 
3346 		dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3347 			 	ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3348 
3349 		memset(mem, 0, total_size);
3350 		ioc->alloc_total += total_size;
3351 		ioc->alloc = mem;
3352 		ioc->alloc_dma = alloc_dma;
3353 		ioc->alloc_sz = total_size;
3354 		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3355 		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3356 
3357 		alloc_dma += reply_sz;
3358 		mem += reply_sz;
3359 
3360 		/*  Request FIFO - WE manage this!  */
3361 
3362 		ioc->req_frames = (MPT_FRAME_HDR *) mem;
3363 		ioc->req_frames_dma = alloc_dma;
3364 
3365 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3366 			 	ioc->name, mem, (void *)(ulong)alloc_dma));
3367 
3368 		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3369 
3370 #if defined(CONFIG_MTRR) && 0
3371 		/*
3372 		 *  Enable Write Combining MTRR for IOC's memory region.
3373 		 *  (at least as much as we can; "size and base must be
3374 		 *  multiples of 4 kiB"
3375 		 */
3376 		ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3377 					 sz,
3378 					 MTRR_TYPE_WRCOMB, 1);
3379 		dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3380 				ioc->name, ioc->req_frames_dma, sz));
3381 #endif
3382 
3383 		for (i = 0; i < ioc->req_depth; i++) {
3384 			alloc_dma += ioc->req_sz;
3385 			mem += ioc->req_sz;
3386 		}
3387 
3388 		ioc->ChainBuffer = mem;
3389 		ioc->ChainBufferDMA = alloc_dma;
3390 
3391 		dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3392 			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3393 
3394 		/* Initialize the free chain Q.
3395 	 	*/
3396 
3397 		INIT_LIST_HEAD(&ioc->FreeChainQ);
3398 
3399 		/* Post the chain buffers to the FreeChainQ.
3400 	 	*/
3401 		mem = (u8 *)ioc->ChainBuffer;
3402 		for (i=0; i < num_chain; i++) {
3403 			mf = (MPT_FRAME_HDR *) mem;
3404 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3405 			mem += ioc->req_sz;
3406 		}
3407 
3408 		/* Initialize Request frames linked list
3409 		 */
3410 		alloc_dma = ioc->req_frames_dma;
3411 		mem = (u8 *) ioc->req_frames;
3412 
3413 		spin_lock_irqsave(&ioc->FreeQlock, flags);
3414 		INIT_LIST_HEAD(&ioc->FreeQ);
3415 		for (i = 0; i < ioc->req_depth; i++) {
3416 			mf = (MPT_FRAME_HDR *) mem;
3417 
3418 			/*  Queue REQUESTs *internally*!  */
3419 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3420 
3421 			mem += ioc->req_sz;
3422 		}
3423 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3424 
3425 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3426 		ioc->sense_buf_pool =
3427 			pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3428 		if (ioc->sense_buf_pool == NULL) {
3429 			printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3430 				ioc->name);
3431 			goto out_fail;
3432 		}
3433 
3434 		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3435 		ioc->alloc_total += sz;
3436 		dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3437  			ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3438 
3439 	}
3440 
3441 	/* Post Reply frames to FIFO
3442 	 */
3443 	alloc_dma = ioc->alloc_dma;
3444 	dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3445 	 	ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3446 
3447 	for (i = 0; i < ioc->reply_depth; i++) {
3448 		/*  Write each address to the IOC!  */
3449 		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3450 		alloc_dma += ioc->reply_sz;
3451 	}
3452 
3453 	return 0;
3454 
3455 out_fail:
3456 	if (ioc->alloc != NULL) {
3457 		sz = ioc->alloc_sz;
3458 		pci_free_consistent(ioc->pcidev,
3459 				sz,
3460 				ioc->alloc, ioc->alloc_dma);
3461 		ioc->reply_frames = NULL;
3462 		ioc->req_frames = NULL;
3463 		ioc->alloc_total -= sz;
3464 	}
3465 	if (ioc->sense_buf_pool != NULL) {
3466 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3467 		pci_free_consistent(ioc->pcidev,
3468 				sz,
3469 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3470 		ioc->sense_buf_pool = NULL;
3471 	}
3472 	return -1;
3473 }
3474 
3475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3476 /**
3477  *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3478  *	from IOC via doorbell handshake method.
3479  *	@ioc: Pointer to MPT_ADAPTER structure
3480  *	@reqBytes: Size of the request in bytes
3481  *	@req: Pointer to MPT request frame
3482  *	@replyBytes: Expected size of the reply in bytes
3483  *	@u16reply: Pointer to area where reply should be written
3484  *	@maxwait: Max wait time for a reply (in seconds)
3485  *	@sleepFlag: Specifies whether the process can sleep
3486  *
3487  *	NOTES: It is the callers responsibility to byte-swap fields in the
3488  *	request which are greater than 1 byte in size.  It is also the
3489  *	callers responsibility to byte-swap response fields which are
3490  *	greater than 1 byte in size.
3491  *
3492  *	Returns 0 for success, non-zero for failure.
3493  */
3494 static int
3495 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3496 				int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3497 {
3498 	MPIDefaultReply_t *mptReply;
3499 	int failcnt = 0;
3500 	int t;
3501 
3502 	/*
3503 	 * Get ready to cache a handshake reply
3504 	 */
3505 	ioc->hs_reply_idx = 0;
3506 	mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3507 	mptReply->MsgLength = 0;
3508 
3509 	/*
3510 	 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3511 	 * then tell IOC that we want to handshake a request of N words.
3512 	 * (WRITE u32val to Doorbell reg).
3513 	 */
3514 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3515 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
3516 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3517 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3518 
3519 	/*
3520 	 * Wait for IOC's doorbell handshake int
3521 	 */
3522 	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3523 		failcnt++;
3524 
3525 	dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3526 			ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3527 
3528 	/* Read doorbell and check for active bit */
3529 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3530 			return -1;
3531 
3532 	/*
3533 	 * Clear doorbell int (WRITE 0 to IntStatus reg),
3534 	 * then wait for IOC to ACKnowledge that it's ready for
3535 	 * our handshake request.
3536 	 */
3537 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3538 	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3539 		failcnt++;
3540 
3541 	if (!failcnt) {
3542 		int	 ii;
3543 		u8	*req_as_bytes = (u8 *) req;
3544 
3545 		/*
3546 		 * Stuff request words via doorbell handshake,
3547 		 * with ACK from IOC for each.
3548 		 */
3549 		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3550 			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
3551 				    (req_as_bytes[(ii*4) + 1] <<  8) |
3552 				    (req_as_bytes[(ii*4) + 2] << 16) |
3553 				    (req_as_bytes[(ii*4) + 3] << 24));
3554 
3555 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3556 			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3557 				failcnt++;
3558 		}
3559 
3560 		dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3561 		DBG_DUMP_REQUEST_FRAME_HDR(req)
3562 
3563 		dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3564 				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3565 
3566 		/*
3567 		 * Wait for completion of doorbell handshake reply from the IOC
3568 		 */
3569 		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3570 			failcnt++;
3571 
3572 		dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3573 				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3574 
3575 		/*
3576 		 * Copy out the cached reply...
3577 		 */
3578 		for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3579 			u16reply[ii] = ioc->hs_reply[ii];
3580 	} else {
3581 		return -99;
3582 	}
3583 
3584 	return -failcnt;
3585 }
3586 
3587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3588 /*
3589  *	WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3590  *	in it's IntStatus register.
3591  *	@ioc: Pointer to MPT_ADAPTER structure
3592  *	@howlong: How long to wait (in seconds)
3593  *	@sleepFlag: Specifies whether the process can sleep
3594  *
3595  *	This routine waits (up to ~2 seconds max) for IOC doorbell
3596  *	handshake ACKnowledge.
3597  *
3598  *	Returns a negative value on failure, else wait loop count.
3599  */
3600 static int
3601 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3602 {
3603 	int cntdn;
3604 	int count = 0;
3605 	u32 intstat=0;
3606 
3607 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3608 
3609 	if (sleepFlag == CAN_SLEEP) {
3610 		while (--cntdn) {
3611 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3612 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3613 				break;
3614 			msleep_interruptible (1);
3615 			count++;
3616 		}
3617 	} else {
3618 		while (--cntdn) {
3619 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3620 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3621 				break;
3622 			mdelay (1);
3623 			count++;
3624 		}
3625 	}
3626 
3627 	if (cntdn) {
3628 		dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3629 				ioc->name, count));
3630 		return count;
3631 	}
3632 
3633 	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3634 			ioc->name, count, intstat);
3635 	return -1;
3636 }
3637 
3638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3639 /*
3640  *	WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3641  *	in it's IntStatus register.
3642  *	@ioc: Pointer to MPT_ADAPTER structure
3643  *	@howlong: How long to wait (in seconds)
3644  *	@sleepFlag: Specifies whether the process can sleep
3645  *
3646  *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3647  *
3648  *	Returns a negative value on failure, else wait loop count.
3649  */
3650 static int
3651 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3652 {
3653 	int cntdn;
3654 	int count = 0;
3655 	u32 intstat=0;
3656 
3657 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3658 	if (sleepFlag == CAN_SLEEP) {
3659 		while (--cntdn) {
3660 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3661 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3662 				break;
3663 			msleep_interruptible(1);
3664 			count++;
3665 		}
3666 	} else {
3667 		while (--cntdn) {
3668 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3669 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3670 				break;
3671 			mdelay(1);
3672 			count++;
3673 		}
3674 	}
3675 
3676 	if (cntdn) {
3677 		dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3678 				ioc->name, count, howlong));
3679 		return count;
3680 	}
3681 
3682 	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3683 			ioc->name, count, intstat);
3684 	return -1;
3685 }
3686 
3687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3688 /*
3689  *	WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3690  *	@ioc: Pointer to MPT_ADAPTER structure
3691  *	@howlong: How long to wait (in seconds)
3692  *	@sleepFlag: Specifies whether the process can sleep
3693  *
3694  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
3695  *	Reply is cached to IOC private area large enough to hold a maximum
3696  *	of 128 bytes of reply data.
3697  *
3698  *	Returns a negative value on failure, else size of reply in WORDS.
3699  */
3700 static int
3701 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3702 {
3703 	int u16cnt = 0;
3704 	int failcnt = 0;
3705 	int t;
3706 	u16 *hs_reply = ioc->hs_reply;
3707 	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3708 	u16 hword;
3709 
3710 	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3711 
3712 	/*
3713 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
3714 	 */
3715 	u16cnt=0;
3716 	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3717 		failcnt++;
3718 	} else {
3719 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3720 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3721 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3722 			failcnt++;
3723 		else {
3724 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3725 			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3726 		}
3727 	}
3728 
3729 	dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3730 			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3731 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3732 
3733 	/*
3734 	 * If no error (and IOC said MsgLength is > 0), piece together
3735 	 * reply 16 bits at a time.
3736 	 */
3737 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3738 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3739 			failcnt++;
3740 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3741 		/* don't overflow our IOC hs_reply[] buffer! */
3742 		if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3743 			hs_reply[u16cnt] = hword;
3744 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3745 	}
3746 
3747 	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3748 		failcnt++;
3749 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3750 
3751 	if (failcnt) {
3752 		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3753 				ioc->name);
3754 		return -failcnt;
3755 	}
3756 #if 0
3757 	else if (u16cnt != (2 * mptReply->MsgLength)) {
3758 		return -101;
3759 	}
3760 	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3761 		return -102;
3762 	}
3763 #endif
3764 
3765 	dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3766 	DBG_DUMP_REPLY_FRAME(mptReply)
3767 
3768 	dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3769 			ioc->name, t, u16cnt/2));
3770 	return u16cnt/2;
3771 }
3772 
3773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3774 /*
3775  *	GetLanConfigPages - Fetch LANConfig pages.
3776  *	@ioc: Pointer to MPT_ADAPTER structure
3777  *
3778  *	Return: 0 for success
3779  *	-ENOMEM if no memory available
3780  *		-EPERM if not allowed due to ISR context
3781  *		-EAGAIN if no msg frames currently available
3782  *		-EFAULT for non-successful reply or no reply (timeout)
3783  */
3784 static int
3785 GetLanConfigPages(MPT_ADAPTER *ioc)
3786 {
3787 	ConfigPageHeader_t	 hdr;
3788 	CONFIGPARMS		 cfg;
3789 	LANPage0_t		*ppage0_alloc;
3790 	dma_addr_t		 page0_dma;
3791 	LANPage1_t		*ppage1_alloc;
3792 	dma_addr_t		 page1_dma;
3793 	int			 rc = 0;
3794 	int			 data_sz;
3795 	int			 copy_sz;
3796 
3797 	/* Get LAN Page 0 header */
3798 	hdr.PageVersion = 0;
3799 	hdr.PageLength = 0;
3800 	hdr.PageNumber = 0;
3801 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3802 	cfg.hdr = &hdr;
3803 	cfg.physAddr = -1;
3804 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3805 	cfg.dir = 0;
3806 	cfg.pageAddr = 0;
3807 	cfg.timeout = 0;
3808 
3809 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3810 		return rc;
3811 
3812 	if (hdr.PageLength > 0) {
3813 		data_sz = hdr.PageLength * 4;
3814 		ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3815 		rc = -ENOMEM;
3816 		if (ppage0_alloc) {
3817 			memset((u8 *)ppage0_alloc, 0, data_sz);
3818 			cfg.physAddr = page0_dma;
3819 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3820 
3821 			if ((rc = mpt_config(ioc, &cfg)) == 0) {
3822 				/* save the data */
3823 				copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3824 				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
3825 
3826 			}
3827 
3828 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3829 
3830 			/* FIXME!
3831 			 *	Normalize endianness of structure data,
3832 			 *	by byte-swapping all > 1 byte fields!
3833 			 */
3834 
3835 		}
3836 
3837 		if (rc)
3838 			return rc;
3839 	}
3840 
3841 	/* Get LAN Page 1 header */
3842 	hdr.PageVersion = 0;
3843 	hdr.PageLength = 0;
3844 	hdr.PageNumber = 1;
3845 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3846 	cfg.hdr = &hdr;
3847 	cfg.physAddr = -1;
3848 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3849 	cfg.dir = 0;
3850 	cfg.pageAddr = 0;
3851 
3852 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3853 		return rc;
3854 
3855 	if (hdr.PageLength == 0)
3856 		return 0;
3857 
3858 	data_sz = hdr.PageLength * 4;
3859 	rc = -ENOMEM;
3860 	ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
3861 	if (ppage1_alloc) {
3862 		memset((u8 *)ppage1_alloc, 0, data_sz);
3863 		cfg.physAddr = page1_dma;
3864 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3865 
3866 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
3867 			/* save the data */
3868 			copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
3869 			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
3870 		}
3871 
3872 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
3873 
3874 		/* FIXME!
3875 		 *	Normalize endianness of structure data,
3876 		 *	by byte-swapping all > 1 byte fields!
3877 		 */
3878 
3879 	}
3880 
3881 	return rc;
3882 }
3883 
3884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3885 /*
3886  *	GetFcPortPage0 - Fetch FCPort config Page0.
3887  *	@ioc: Pointer to MPT_ADAPTER structure
3888  *	@portnum: IOC Port number
3889  *
3890  *	Return: 0 for success
3891  *	-ENOMEM if no memory available
3892  *		-EPERM if not allowed due to ISR context
3893  *		-EAGAIN if no msg frames currently available
3894  *		-EFAULT for non-successful reply or no reply (timeout)
3895  */
3896 static int
3897 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
3898 {
3899 	ConfigPageHeader_t	 hdr;
3900 	CONFIGPARMS		 cfg;
3901 	FCPortPage0_t		*ppage0_alloc;
3902 	FCPortPage0_t		*pp0dest;
3903 	dma_addr_t		 page0_dma;
3904 	int			 data_sz;
3905 	int			 copy_sz;
3906 	int			 rc;
3907 
3908 	/* Get FCPort Page 0 header */
3909 	hdr.PageVersion = 0;
3910 	hdr.PageLength = 0;
3911 	hdr.PageNumber = 0;
3912 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
3913 	cfg.hdr = &hdr;
3914 	cfg.physAddr = -1;
3915 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3916 	cfg.dir = 0;
3917 	cfg.pageAddr = portnum;
3918 	cfg.timeout = 0;
3919 
3920 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3921 		return rc;
3922 
3923 	if (hdr.PageLength == 0)
3924 		return 0;
3925 
3926 	data_sz = hdr.PageLength * 4;
3927 	rc = -ENOMEM;
3928 	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3929 	if (ppage0_alloc) {
3930 		memset((u8 *)ppage0_alloc, 0, data_sz);
3931 		cfg.physAddr = page0_dma;
3932 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3933 
3934 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
3935 			/* save the data */
3936 			pp0dest = &ioc->fc_port_page0[portnum];
3937 			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
3938 			memcpy(pp0dest, ppage0_alloc, copy_sz);
3939 
3940 			/*
3941 			 *	Normalize endianness of structure data,
3942 			 *	by byte-swapping all > 1 byte fields!
3943 			 */
3944 			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
3945 			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
3946 			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
3947 			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
3948 			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
3949 			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
3950 			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
3951 			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
3952 			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
3953 			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
3954 			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
3955 			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
3956 			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
3957 			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
3958 			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
3959 			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
3960 
3961 		}
3962 
3963 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3964 	}
3965 
3966 	return rc;
3967 }
3968 
3969 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3970 /*
3971  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
3972  *	@ioc: Pointer to MPT_ADAPTER structure
3973  *
3974  *	Returns: 0 for success
3975  *	-ENOMEM if no memory available
3976  *		-EPERM if not allowed due to ISR context
3977  *		-EAGAIN if no msg frames currently available
3978  *		-EFAULT for non-successful reply or no reply (timeout)
3979  */
3980 static int
3981 GetIoUnitPage2(MPT_ADAPTER *ioc)
3982 {
3983 	ConfigPageHeader_t	 hdr;
3984 	CONFIGPARMS		 cfg;
3985 	IOUnitPage2_t		*ppage_alloc;
3986 	dma_addr_t		 page_dma;
3987 	int			 data_sz;
3988 	int			 rc;
3989 
3990 	/* Get the page header */
3991 	hdr.PageVersion = 0;
3992 	hdr.PageLength = 0;
3993 	hdr.PageNumber = 2;
3994 	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
3995 	cfg.hdr = &hdr;
3996 	cfg.physAddr = -1;
3997 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3998 	cfg.dir = 0;
3999 	cfg.pageAddr = 0;
4000 	cfg.timeout = 0;
4001 
4002 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4003 		return rc;
4004 
4005 	if (hdr.PageLength == 0)
4006 		return 0;
4007 
4008 	/* Read the config page */
4009 	data_sz = hdr.PageLength * 4;
4010 	rc = -ENOMEM;
4011 	ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4012 	if (ppage_alloc) {
4013 		memset((u8 *)ppage_alloc, 0, data_sz);
4014 		cfg.physAddr = page_dma;
4015 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4016 
4017 		/* If Good, save data */
4018 		if ((rc = mpt_config(ioc, &cfg)) == 0)
4019 			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4020 
4021 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4022 	}
4023 
4024 	return rc;
4025 }
4026 
4027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4028 /*	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4029  *	@ioc: Pointer to a Adapter Strucutre
4030  *	@portnum: IOC port number
4031  *
4032  *	Return: -EFAULT if read of config page header fails
4033  *			or if no nvram
4034  *	If read of SCSI Port Page 0 fails,
4035  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4036  *		Adapter settings: async, narrow
4037  *		Return 1
4038  *	If read of SCSI Port Page 2 fails,
4039  *		Adapter settings valid
4040  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4041  *		Return 1
4042  *	Else
4043  *		Both valid
4044  *		Return 0
4045  *	CHECK - what type of locking mechanisms should be used????
4046  */
4047 static int
4048 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4049 {
4050 	u8			*pbuf;
4051 	dma_addr_t		 buf_dma;
4052 	CONFIGPARMS		 cfg;
4053 	ConfigPageHeader_t	 header;
4054 	int			 ii;
4055 	int			 data, rc = 0;
4056 
4057 	/* Allocate memory
4058 	 */
4059 	if (!ioc->spi_data.nvram) {
4060 		int	 sz;
4061 		u8	*mem;
4062 		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4063 		mem = kmalloc(sz, GFP_ATOMIC);
4064 		if (mem == NULL)
4065 			return -EFAULT;
4066 
4067 		ioc->spi_data.nvram = (int *) mem;
4068 
4069 		dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4070 			ioc->name, ioc->spi_data.nvram, sz));
4071 	}
4072 
4073 	/* Invalidate NVRAM information
4074 	 */
4075 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4076 		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4077 	}
4078 
4079 	/* Read SPP0 header, allocate memory, then read page.
4080 	 */
4081 	header.PageVersion = 0;
4082 	header.PageLength = 0;
4083 	header.PageNumber = 0;
4084 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4085 	cfg.hdr = &header;
4086 	cfg.physAddr = -1;
4087 	cfg.pageAddr = portnum;
4088 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4089 	cfg.dir = 0;
4090 	cfg.timeout = 0;	/* use default */
4091 	if (mpt_config(ioc, &cfg) != 0)
4092 		 return -EFAULT;
4093 
4094 	if (header.PageLength > 0) {
4095 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4096 		if (pbuf) {
4097 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4098 			cfg.physAddr = buf_dma;
4099 			if (mpt_config(ioc, &cfg) != 0) {
4100 				ioc->spi_data.maxBusWidth = MPT_NARROW;
4101 				ioc->spi_data.maxSyncOffset = 0;
4102 				ioc->spi_data.minSyncFactor = MPT_ASYNC;
4103 				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4104 				rc = 1;
4105 			} else {
4106 				/* Save the Port Page 0 data
4107 				 */
4108 				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4109 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4110 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4111 
4112 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4113 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4114 					dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4115 						ioc->name, pPP0->Capabilities));
4116 				}
4117 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4118 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4119 				if (data) {
4120 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4121 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4122 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4123 				} else {
4124 					ioc->spi_data.maxSyncOffset = 0;
4125 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
4126 				}
4127 
4128 				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4129 
4130 				/* Update the minSyncFactor based on bus type.
4131 				 */
4132 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4133 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4134 
4135 				if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4136 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
4137 				}
4138 			}
4139 			if (pbuf) {
4140 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4141 			}
4142 		}
4143 	}
4144 
4145 	/* SCSI Port Page 2 - Read the header then the page.
4146 	 */
4147 	header.PageVersion = 0;
4148 	header.PageLength = 0;
4149 	header.PageNumber = 2;
4150 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4151 	cfg.hdr = &header;
4152 	cfg.physAddr = -1;
4153 	cfg.pageAddr = portnum;
4154 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4155 	cfg.dir = 0;
4156 	if (mpt_config(ioc, &cfg) != 0)
4157 		return -EFAULT;
4158 
4159 	if (header.PageLength > 0) {
4160 		/* Allocate memory and read SCSI Port Page 2
4161 		 */
4162 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4163 		if (pbuf) {
4164 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4165 			cfg.physAddr = buf_dma;
4166 			if (mpt_config(ioc, &cfg) != 0) {
4167 				/* Nvram data is left with INVALID mark
4168 				 */
4169 				rc = 1;
4170 			} else {
4171 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4172 				MpiDeviceInfo_t	*pdevice = NULL;
4173 
4174 				/* Save the Port Page 2 data
4175 				 * (reformat into a 32bit quantity)
4176 				 */
4177 				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4178 				ioc->spi_data.PortFlags = data;
4179 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4180 					pdevice = &pPP2->DeviceSettings[ii];
4181 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4182 						(pdevice->SyncFactor << 8) | pdevice->Timeout;
4183 					ioc->spi_data.nvram[ii] = data;
4184 				}
4185 			}
4186 
4187 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4188 		}
4189 	}
4190 
4191 	/* Update Adapter limits with those from NVRAM
4192 	 * Comment: Don't need to do this. Target performance
4193 	 * parameters will never exceed the adapters limits.
4194 	 */
4195 
4196 	return rc;
4197 }
4198 
4199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4200 /*	mpt_readScsiDevicePageHeaders - save version and length of SDP1
4201  *	@ioc: Pointer to a Adapter Strucutre
4202  *	@portnum: IOC port number
4203  *
4204  *	Return: -EFAULT if read of config page header fails
4205  *		or 0 if success.
4206  */
4207 static int
4208 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4209 {
4210 	CONFIGPARMS		 cfg;
4211 	ConfigPageHeader_t	 header;
4212 
4213 	/* Read the SCSI Device Page 1 header
4214 	 */
4215 	header.PageVersion = 0;
4216 	header.PageLength = 0;
4217 	header.PageNumber = 1;
4218 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4219 	cfg.hdr = &header;
4220 	cfg.physAddr = -1;
4221 	cfg.pageAddr = portnum;
4222 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4223 	cfg.dir = 0;
4224 	cfg.timeout = 0;
4225 	if (mpt_config(ioc, &cfg) != 0)
4226 		 return -EFAULT;
4227 
4228 	ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4229 	ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4230 
4231 	header.PageVersion = 0;
4232 	header.PageLength = 0;
4233 	header.PageNumber = 0;
4234 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4235 	if (mpt_config(ioc, &cfg) != 0)
4236 		 return -EFAULT;
4237 
4238 	ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4239 	ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4240 
4241 	dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4242 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4243 
4244 	dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4245 			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4246 	return 0;
4247 }
4248 
4249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4250 /**
4251  *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4252  *	@ioc: Pointer to a Adapter Strucutre
4253  *	@portnum: IOC port number
4254  *
4255  *	Return:
4256  *	0 on success
4257  *	-EFAULT if read of config page header fails or data pointer not NULL
4258  *	-ENOMEM if pci_alloc failed
4259  */
4260 int
4261 mpt_findImVolumes(MPT_ADAPTER *ioc)
4262 {
4263 	IOCPage2_t		*pIoc2;
4264 	u8			*mem;
4265 	ConfigPageIoc2RaidVol_t	*pIocRv;
4266 	dma_addr_t		 ioc2_dma;
4267 	CONFIGPARMS		 cfg;
4268 	ConfigPageHeader_t	 header;
4269 	int			 jj;
4270 	int			 rc = 0;
4271 	int			 iocpage2sz;
4272 	u8			 nVols, nPhys;
4273 	u8			 vid, vbus, vioc;
4274 
4275 	/* Read IOCP2 header then the page.
4276 	 */
4277 	header.PageVersion = 0;
4278 	header.PageLength = 0;
4279 	header.PageNumber = 2;
4280 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4281 	cfg.hdr = &header;
4282 	cfg.physAddr = -1;
4283 	cfg.pageAddr = 0;
4284 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4285 	cfg.dir = 0;
4286 	cfg.timeout = 0;
4287 	if (mpt_config(ioc, &cfg) != 0)
4288 		 return -EFAULT;
4289 
4290 	if (header.PageLength == 0)
4291 		return -EFAULT;
4292 
4293 	iocpage2sz = header.PageLength * 4;
4294 	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4295 	if (!pIoc2)
4296 		return -ENOMEM;
4297 
4298 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4299 	cfg.physAddr = ioc2_dma;
4300 	if (mpt_config(ioc, &cfg) != 0)
4301 		goto done_and_free;
4302 
4303 	if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4304 		mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4305 		if (mem) {
4306 			ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4307 		} else {
4308 			goto done_and_free;
4309 		}
4310 	}
4311 	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4312 
4313 	/* Identify RAID Volume Id's */
4314 	nVols = pIoc2->NumActiveVolumes;
4315 	if ( nVols == 0) {
4316 		/* No RAID Volume.
4317 		 */
4318 		goto done_and_free;
4319 	} else {
4320 		/* At least 1 RAID Volume
4321 		 */
4322 		pIocRv = pIoc2->RaidVolume;
4323 		ioc->spi_data.isRaid = 0;
4324 		for (jj = 0; jj < nVols; jj++, pIocRv++) {
4325 			vid = pIocRv->VolumeID;
4326 			vbus = pIocRv->VolumeBus;
4327 			vioc = pIocRv->VolumeIOC;
4328 
4329 			/* find the match
4330 			 */
4331 			if (vbus == 0) {
4332 				ioc->spi_data.isRaid |= (1 << vid);
4333 			} else {
4334 				/* Error! Always bus 0
4335 				 */
4336 			}
4337 		}
4338 	}
4339 
4340 	/* Identify Hidden Physical Disk Id's */
4341 	nPhys = pIoc2->NumActivePhysDisks;
4342 	if (nPhys == 0) {
4343 		/* No physical disks.
4344 		 */
4345 	} else {
4346 		mpt_read_ioc_pg_3(ioc);
4347 	}
4348 
4349 done_and_free:
4350 	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4351 
4352 	return rc;
4353 }
4354 
4355 int
4356 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4357 {
4358 	IOCPage3_t		*pIoc3;
4359 	u8			*mem;
4360 	CONFIGPARMS		 cfg;
4361 	ConfigPageHeader_t	 header;
4362 	dma_addr_t		 ioc3_dma;
4363 	int			 iocpage3sz = 0;
4364 
4365 	/* Free the old page
4366 	 */
4367 	if (ioc->spi_data.pIocPg3) {
4368 		kfree(ioc->spi_data.pIocPg3);
4369 		ioc->spi_data.pIocPg3 = NULL;
4370 	}
4371 
4372 	/* There is at least one physical disk.
4373 	 * Read and save IOC Page 3
4374 	 */
4375 	header.PageVersion = 0;
4376 	header.PageLength = 0;
4377 	header.PageNumber = 3;
4378 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4379 	cfg.hdr = &header;
4380 	cfg.physAddr = -1;
4381 	cfg.pageAddr = 0;
4382 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4383 	cfg.dir = 0;
4384 	cfg.timeout = 0;
4385 	if (mpt_config(ioc, &cfg) != 0)
4386 		return 0;
4387 
4388 	if (header.PageLength == 0)
4389 		return 0;
4390 
4391 	/* Read Header good, alloc memory
4392 	 */
4393 	iocpage3sz = header.PageLength * 4;
4394 	pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4395 	if (!pIoc3)
4396 		return 0;
4397 
4398 	/* Read the Page and save the data
4399 	 * into malloc'd memory.
4400 	 */
4401 	cfg.physAddr = ioc3_dma;
4402 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4403 	if (mpt_config(ioc, &cfg) == 0) {
4404 		mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4405 		if (mem) {
4406 			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4407 			ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4408 		}
4409 	}
4410 
4411 	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4412 
4413 	return 0;
4414 }
4415 
4416 static void
4417 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4418 {
4419 	IOCPage4_t		*pIoc4;
4420 	CONFIGPARMS		 cfg;
4421 	ConfigPageHeader_t	 header;
4422 	dma_addr_t		 ioc4_dma;
4423 	int			 iocpage4sz;
4424 
4425 	/* Read and save IOC Page 4
4426 	 */
4427 	header.PageVersion = 0;
4428 	header.PageLength = 0;
4429 	header.PageNumber = 4;
4430 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4431 	cfg.hdr = &header;
4432 	cfg.physAddr = -1;
4433 	cfg.pageAddr = 0;
4434 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4435 	cfg.dir = 0;
4436 	cfg.timeout = 0;
4437 	if (mpt_config(ioc, &cfg) != 0)
4438 		return;
4439 
4440 	if (header.PageLength == 0)
4441 		return;
4442 
4443 	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4444 		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4445 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4446 		if (!pIoc4)
4447 			return;
4448 	} else {
4449 		ioc4_dma = ioc->spi_data.IocPg4_dma;
4450 		iocpage4sz = ioc->spi_data.IocPg4Sz;
4451 	}
4452 
4453 	/* Read the Page into dma memory.
4454 	 */
4455 	cfg.physAddr = ioc4_dma;
4456 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4457 	if (mpt_config(ioc, &cfg) == 0) {
4458 		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4459 		ioc->spi_data.IocPg4_dma = ioc4_dma;
4460 		ioc->spi_data.IocPg4Sz = iocpage4sz;
4461 	} else {
4462 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4463 		ioc->spi_data.pIocPg4 = NULL;
4464 	}
4465 }
4466 
4467 static void
4468 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4469 {
4470 	IOCPage1_t		*pIoc1;
4471 	CONFIGPARMS		 cfg;
4472 	ConfigPageHeader_t	 header;
4473 	dma_addr_t		 ioc1_dma;
4474 	int			 iocpage1sz = 0;
4475 	u32			 tmp;
4476 
4477 	/* Check the Coalescing Timeout in IOC Page 1
4478 	 */
4479 	header.PageVersion = 0;
4480 	header.PageLength = 0;
4481 	header.PageNumber = 1;
4482 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4483 	cfg.hdr = &header;
4484 	cfg.physAddr = -1;
4485 	cfg.pageAddr = 0;
4486 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4487 	cfg.dir = 0;
4488 	cfg.timeout = 0;
4489 	if (mpt_config(ioc, &cfg) != 0)
4490 		return;
4491 
4492 	if (header.PageLength == 0)
4493 		return;
4494 
4495 	/* Read Header good, alloc memory
4496 	 */
4497 	iocpage1sz = header.PageLength * 4;
4498 	pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4499 	if (!pIoc1)
4500 		return;
4501 
4502 	/* Read the Page and check coalescing timeout
4503 	 */
4504 	cfg.physAddr = ioc1_dma;
4505 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4506 	if (mpt_config(ioc, &cfg) == 0) {
4507 
4508 		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4509 		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4510 			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4511 
4512 			dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4513 					ioc->name, tmp));
4514 
4515 			if (tmp > MPT_COALESCING_TIMEOUT) {
4516 				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4517 
4518 				/* Write NVRAM and current
4519 				 */
4520 				cfg.dir = 1;
4521 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4522 				if (mpt_config(ioc, &cfg) == 0) {
4523 					dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4524 							ioc->name, MPT_COALESCING_TIMEOUT));
4525 
4526 					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4527 					if (mpt_config(ioc, &cfg) == 0) {
4528 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4529 								ioc->name, MPT_COALESCING_TIMEOUT));
4530 					} else {
4531 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4532 									ioc->name));
4533 					}
4534 
4535 				} else {
4536 					dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4537 								ioc->name));
4538 				}
4539 			}
4540 
4541 		} else {
4542 			dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4543 		}
4544 	}
4545 
4546 	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4547 
4548 	return;
4549 }
4550 
4551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4552 /*
4553  *	SendEventNotification - Send EventNotification (on or off) request
4554  *	to MPT adapter.
4555  *	@ioc: Pointer to MPT_ADAPTER structure
4556  *	@EvSwitch: Event switch flags
4557  */
4558 static int
4559 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4560 {
4561 	EventNotification_t	*evnp;
4562 
4563 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4564 	if (evnp == NULL) {
4565 		dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4566 				ioc->name));
4567 		return 0;
4568 	}
4569 	memset(evnp, 0, sizeof(*evnp));
4570 
4571 	dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4572 
4573 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4574 	evnp->ChainOffset = 0;
4575 	evnp->MsgFlags = 0;
4576 	evnp->Switch = EvSwitch;
4577 
4578 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4579 
4580 	return 0;
4581 }
4582 
4583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4584 /**
4585  *	SendEventAck - Send EventAck request to MPT adapter.
4586  *	@ioc: Pointer to MPT_ADAPTER structure
4587  *	@evnp: Pointer to original EventNotification request
4588  */
4589 static int
4590 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4591 {
4592 	EventAck_t	*pAck;
4593 
4594 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4595 		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4596 				ioc->name);
4597 		return -1;
4598 	}
4599 	memset(pAck, 0, sizeof(*pAck));
4600 
4601 	dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4602 
4603 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
4604 	pAck->ChainOffset  = 0;
4605 	pAck->MsgFlags     = 0;
4606 	pAck->Event        = evnp->Event;
4607 	pAck->EventContext = evnp->EventContext;
4608 
4609 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4610 
4611 	return 0;
4612 }
4613 
4614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4615 /**
4616  *	mpt_config - Generic function to issue config message
4617  *	@ioc - Pointer to an adapter structure
4618  *	@cfg - Pointer to a configuration structure. Struct contains
4619  *		action, page address, direction, physical address
4620  *		and pointer to a configuration page header
4621  *		Page header is updated.
4622  *
4623  *	Returns 0 for success
4624  *	-EPERM if not allowed due to ISR context
4625  *	-EAGAIN if no msg frames currently available
4626  *	-EFAULT for non-successful reply or no reply (timeout)
4627  */
4628 int
4629 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4630 {
4631 	Config_t	*pReq;
4632 	MPT_FRAME_HDR	*mf;
4633 	unsigned long	 flags;
4634 	int		 ii, rc;
4635 	u32		 flagsLength;
4636 	int		 in_isr;
4637 
4638 	/*	Prevent calling wait_event() (below), if caller happens
4639 	 *	to be in ISR context, because that is fatal!
4640 	 */
4641 	in_isr = in_interrupt();
4642 	if (in_isr) {
4643 		dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4644 				ioc->name));
4645 		return -EPERM;
4646 	}
4647 
4648 	/* Get and Populate a free Frame
4649 	 */
4650 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4651 		dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4652 				ioc->name));
4653 		return -EAGAIN;
4654 	}
4655 	pReq = (Config_t *)mf;
4656 	pReq->Action = pCfg->action;
4657 	pReq->Reserved = 0;
4658 	pReq->ChainOffset = 0;
4659 	pReq->Function = MPI_FUNCTION_CONFIG;
4660 	pReq->ExtPageLength = 0;
4661 	pReq->ExtPageType = 0;
4662 	pReq->MsgFlags = 0;
4663 	for (ii=0; ii < 8; ii++)
4664 		pReq->Reserved2[ii] = 0;
4665 
4666 	pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4667 	pReq->Header.PageLength = pCfg->hdr->PageLength;
4668 	pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4669 	pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4670 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4671 
4672 	/* Add a SGE to the config request.
4673 	 */
4674 	if (pCfg->dir)
4675 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4676 	else
4677 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4678 
4679 	flagsLength |= pCfg->hdr->PageLength * 4;
4680 
4681 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4682 
4683 	dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4684 		ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4685 
4686 	/* Append pCfg pointer to end of mf
4687 	 */
4688 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
4689 
4690 	/* Initalize the timer
4691 	 */
4692 	init_timer(&pCfg->timer);
4693 	pCfg->timer.data = (unsigned long) ioc;
4694 	pCfg->timer.function = mpt_timer_expired;
4695 	pCfg->wait_done = 0;
4696 
4697 	/* Set the timer; ensure 10 second minimum */
4698 	if (pCfg->timeout < 10)
4699 		pCfg->timer.expires = jiffies + HZ*10;
4700 	else
4701 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4702 
4703 	/* Add to end of Q, set timer and then issue this command */
4704 	spin_lock_irqsave(&ioc->FreeQlock, flags);
4705 	list_add_tail(&pCfg->linkage, &ioc->configQ);
4706 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4707 
4708 	add_timer(&pCfg->timer);
4709 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4710 	wait_event(mpt_waitq, pCfg->wait_done);
4711 
4712 	/* mf has been freed - do not access */
4713 
4714 	rc = pCfg->status;
4715 
4716 	return rc;
4717 }
4718 
4719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4720 /**
4721  *	mpt_toolbox - Generic function to issue toolbox message
4722  *	@ioc - Pointer to an adapter structure
4723  *	@cfg - Pointer to a toolbox structure. Struct contains
4724  *		action, page address, direction, physical address
4725  *		and pointer to a configuration page header
4726  *		Page header is updated.
4727  *
4728  *	Returns 0 for success
4729  *	-EPERM if not allowed due to ISR context
4730  *	-EAGAIN if no msg frames currently available
4731  *	-EFAULT for non-successful reply or no reply (timeout)
4732  */
4733 int
4734 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4735 {
4736 	ToolboxIstwiReadWriteRequest_t	*pReq;
4737 	MPT_FRAME_HDR	*mf;
4738 	struct pci_dev	*pdev;
4739 	unsigned long	 flags;
4740 	int		 rc;
4741 	u32		 flagsLength;
4742 	int		 in_isr;
4743 
4744 	/*	Prevent calling wait_event() (below), if caller happens
4745 	 *	to be in ISR context, because that is fatal!
4746 	 */
4747 	in_isr = in_interrupt();
4748 	if (in_isr) {
4749 		dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4750 				ioc->name));
4751 		return -EPERM;
4752 	}
4753 
4754 	/* Get and Populate a free Frame
4755 	 */
4756 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4757 		dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4758 				ioc->name));
4759 		return -EAGAIN;
4760 	}
4761 	pReq = (ToolboxIstwiReadWriteRequest_t	*)mf;
4762 	pReq->Tool = pCfg->action;
4763 	pReq->Reserved = 0;
4764 	pReq->ChainOffset = 0;
4765 	pReq->Function = MPI_FUNCTION_TOOLBOX;
4766 	pReq->Reserved1 = 0;
4767 	pReq->Reserved2 = 0;
4768 	pReq->MsgFlags = 0;
4769 	pReq->Flags = pCfg->dir;
4770 	pReq->BusNum = 0;
4771 	pReq->Reserved3 = 0;
4772 	pReq->NumAddressBytes = 0x01;
4773 	pReq->Reserved4 = 0;
4774 	pReq->DataLength = 0x04;
4775 	pdev = (struct pci_dev *) ioc->pcidev;
4776 	if (pdev->devfn & 1)
4777 		pReq->DeviceAddr = 0xB2;
4778 	else
4779 		pReq->DeviceAddr = 0xB0;
4780 	pReq->Addr1 = 0;
4781 	pReq->Addr2 = 0;
4782 	pReq->Addr3 = 0;
4783 	pReq->Reserved5 = 0;
4784 
4785 	/* Add a SGE to the config request.
4786 	 */
4787 
4788 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4789 
4790 	mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4791 
4792 	dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4793 		ioc->name, pReq->Tool));
4794 
4795 	/* Append pCfg pointer to end of mf
4796 	 */
4797 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
4798 
4799 	/* Initalize the timer
4800 	 */
4801 	init_timer(&pCfg->timer);
4802 	pCfg->timer.data = (unsigned long) ioc;
4803 	pCfg->timer.function = mpt_timer_expired;
4804 	pCfg->wait_done = 0;
4805 
4806 	/* Set the timer; ensure 10 second minimum */
4807 	if (pCfg->timeout < 10)
4808 		pCfg->timer.expires = jiffies + HZ*10;
4809 	else
4810 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4811 
4812 	/* Add to end of Q, set timer and then issue this command */
4813 	spin_lock_irqsave(&ioc->FreeQlock, flags);
4814 	list_add_tail(&pCfg->linkage, &ioc->configQ);
4815 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4816 
4817 	add_timer(&pCfg->timer);
4818 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4819 	wait_event(mpt_waitq, pCfg->wait_done);
4820 
4821 	/* mf has been freed - do not access */
4822 
4823 	rc = pCfg->status;
4824 
4825 	return rc;
4826 }
4827 
4828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4829 /*
4830  *	mpt_timer_expired - Call back for timer process.
4831  *	Used only internal config functionality.
4832  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4833  */
4834 static void
4835 mpt_timer_expired(unsigned long data)
4836 {
4837 	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
4838 
4839 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
4840 
4841 	/* Perform a FW reload */
4842 	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
4843 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
4844 
4845 	/* No more processing.
4846 	 * Hard reset clean-up will wake up
4847 	 * process and free all resources.
4848 	 */
4849 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
4850 
4851 	return;
4852 }
4853 
4854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4855 /*
4856  *	mpt_ioc_reset - Base cleanup for hard reset
4857  *	@ioc: Pointer to the adapter structure
4858  *	@reset_phase: Indicates pre- or post-reset functionality
4859  *
4860  *	Remark: Free's resources with internally generated commands.
4861  */
4862 static int
4863 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
4864 {
4865 	CONFIGPARMS *pCfg;
4866 	unsigned long flags;
4867 
4868 	dprintk((KERN_WARNING MYNAM
4869 			": IOC %s_reset routed to MPT base driver!\n",
4870 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
4871 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
4872 
4873 	if (reset_phase == MPT_IOC_SETUP_RESET) {
4874 		;
4875 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
4876 		/* If the internal config Q is not empty -
4877 		 * delete timer. MF resources will be freed when
4878 		 * the FIFO's are primed.
4879 		 */
4880 		spin_lock_irqsave(&ioc->FreeQlock, flags);
4881 		list_for_each_entry(pCfg, &ioc->configQ, linkage)
4882 			del_timer(&pCfg->timer);
4883 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4884 
4885 	} else {
4886 		CONFIGPARMS *pNext;
4887 
4888 		/* Search the configQ for internal commands.
4889 		 * Flush the Q, and wake up all suspended threads.
4890 		 */
4891 		spin_lock_irqsave(&ioc->FreeQlock, flags);
4892 		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
4893 			list_del(&pCfg->linkage);
4894 
4895 			pCfg->status = MPT_CONFIG_ERROR;
4896 			pCfg->wait_done = 1;
4897 			wake_up(&mpt_waitq);
4898 		}
4899 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4900 	}
4901 
4902 	return 1;		/* currently means nothing really */
4903 }
4904 
4905 
4906 #ifdef CONFIG_PROC_FS		/* { */
4907 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4908 /*
4909  *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
4910  */
4911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4912 /*
4913  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
4914  *
4915  *	Returns 0 for success, non-zero for failure.
4916  */
4917 static int
4918 procmpt_create(void)
4919 {
4920 	struct proc_dir_entry	*ent;
4921 
4922 	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
4923 	if (mpt_proc_root_dir == NULL)
4924 		return -ENOTDIR;
4925 
4926 	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4927 	if (ent)
4928 		ent->read_proc = procmpt_summary_read;
4929 
4930 	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4931 	if (ent)
4932 		ent->read_proc = procmpt_version_read;
4933 
4934 	return 0;
4935 }
4936 
4937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4938 /*
4939  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
4940  *
4941  *	Returns 0 for success, non-zero for failure.
4942  */
4943 static void
4944 procmpt_destroy(void)
4945 {
4946 	remove_proc_entry("version", mpt_proc_root_dir);
4947 	remove_proc_entry("summary", mpt_proc_root_dir);
4948 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
4949 }
4950 
4951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4952 /*
4953  *	procmpt_summary_read - Handle read request from /proc/mpt/summary
4954  *	or from /proc/mpt/iocN/summary.
4955  *	@buf: Pointer to area to write information
4956  *	@start: Pointer to start pointer
4957  *	@offset: Offset to start writing
4958  *	@request:
4959  *	@eof: Pointer to EOF integer
4960  *	@data: Pointer
4961  *
4962  *	Returns number of characters written to process performing the read.
4963  */
4964 static int
4965 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
4966 {
4967 	MPT_ADAPTER *ioc;
4968 	char *out = buf;
4969 	int len;
4970 
4971 	if (data) {
4972 		int more = 0;
4973 
4974 		ioc = data;
4975 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4976 
4977 		out += more;
4978 	} else {
4979 		list_for_each_entry(ioc, &ioc_list, list) {
4980 			int	more = 0;
4981 
4982 			mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4983 
4984 			out += more;
4985 			if ((out-buf) >= request)
4986 				break;
4987 		}
4988 	}
4989 
4990 	len = out - buf;
4991 
4992 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
4993 }
4994 
4995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4996 /*
4997  *	procmpt_version_read - Handle read request from /proc/mpt/version.
4998  *	@buf: Pointer to area to write information
4999  *	@start: Pointer to start pointer
5000  *	@offset: Offset to start writing
5001  *	@request:
5002  *	@eof: Pointer to EOF integer
5003  *	@data: Pointer
5004  *
5005  *	Returns number of characters written to process performing the read.
5006  */
5007 static int
5008 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5009 {
5010 	int	 ii;
5011 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
5012 	char	*drvname;
5013 	int	 len;
5014 
5015 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5016 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
5017 
5018 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
5019 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5020 		drvname = NULL;
5021 		if (MptCallbacks[ii]) {
5022 			switch (MptDriverClass[ii]) {
5023 			case MPTSPI_DRIVER:
5024 				if (!scsi++) drvname = "SPI host";
5025 				break;
5026 			case MPTFC_DRIVER:
5027 				if (!fc++) drvname = "FC host";
5028 				break;
5029 			case MPTSAS_DRIVER:
5030 				if (!sas++) drvname = "SAS host";
5031 				break;
5032 			case MPTLAN_DRIVER:
5033 				if (!lan++) drvname = "LAN";
5034 				break;
5035 			case MPTSTM_DRIVER:
5036 				if (!targ++) drvname = "SCSI target";
5037 				break;
5038 			case MPTCTL_DRIVER:
5039 				if (!ctl++) drvname = "ioctl";
5040 				break;
5041 			}
5042 
5043 			if (drvname)
5044 				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5045 		}
5046 	}
5047 
5048 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5049 }
5050 
5051 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5052 /*
5053  *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5054  *	@buf: Pointer to area to write information
5055  *	@start: Pointer to start pointer
5056  *	@offset: Offset to start writing
5057  *	@request:
5058  *	@eof: Pointer to EOF integer
5059  *	@data: Pointer
5060  *
5061  *	Returns number of characters written to process performing the read.
5062  */
5063 static int
5064 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5065 {
5066 	MPT_ADAPTER	*ioc = data;
5067 	int		 len;
5068 	char		 expVer[32];
5069 	int		 sz;
5070 	int		 p;
5071 
5072 	mpt_get_fw_exp_ver(expVer, ioc);
5073 
5074 	len = sprintf(buf, "%s:", ioc->name);
5075 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5076 		len += sprintf(buf+len, "  (f/w download boot flag set)");
5077 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5078 //		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
5079 
5080 	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
5081 			ioc->facts.ProductID,
5082 			ioc->prod_name);
5083 	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5084 	if (ioc->facts.FWImageSize)
5085 		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5086 	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5087 	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5088 	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
5089 
5090 	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
5091 			ioc->facts.CurrentHostMfaHighAddr);
5092 	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
5093 			ioc->facts.CurrentSenseBufferHighAddr);
5094 
5095 	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5096 	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5097 
5098 	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5099 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5100 	/*
5101 	 *  Rounding UP to nearest 4-kB boundary here...
5102 	 */
5103 	sz = (ioc->req_sz * ioc->req_depth) + 128;
5104 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5105 	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5106 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5107 	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
5108 					4*ioc->facts.RequestFrameSize,
5109 					ioc->facts.GlobalCredits);
5110 
5111 	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
5112 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5113 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5114 	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5115 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5116 	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
5117 					ioc->facts.CurReplyFrameSize,
5118 					ioc->facts.ReplyQueueDepth);
5119 
5120 	len += sprintf(buf+len, "  MaxDevices = %d\n",
5121 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5122 	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
5123 
5124 	/* per-port info */
5125 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5126 		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
5127 				p+1,
5128 				ioc->facts.NumberOfPorts);
5129 		if (ioc->bus_type == FC) {
5130 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5131 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5132 				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5133 						a[5], a[4], a[3], a[2], a[1], a[0]);
5134 			}
5135 			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
5136 					ioc->fc_port_page0[p].WWNN.High,
5137 					ioc->fc_port_page0[p].WWNN.Low,
5138 					ioc->fc_port_page0[p].WWPN.High,
5139 					ioc->fc_port_page0[p].WWPN.Low);
5140 		}
5141 	}
5142 
5143 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5144 }
5145 
5146 #endif		/* CONFIG_PROC_FS } */
5147 
5148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5149 static void
5150 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5151 {
5152 	buf[0] ='\0';
5153 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5154 		sprintf(buf, " (Exp %02d%02d)",
5155 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
5156 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
5157 
5158 		/* insider hack! */
5159 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5160 			strcat(buf, " [MDBG]");
5161 	}
5162 }
5163 
5164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5165 /**
5166  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5167  *	@ioc: Pointer to MPT_ADAPTER structure
5168  *	@buffer: Pointer to buffer where IOC summary info should be written
5169  *	@size: Pointer to number of bytes we wrote (set by this routine)
5170  *	@len: Offset at which to start writing in buffer
5171  *	@showlan: Display LAN stuff?
5172  *
5173  *	This routine writes (english readable) ASCII text, which represents
5174  *	a summary of IOC information, to a buffer.
5175  */
5176 void
5177 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5178 {
5179 	char expVer[32];
5180 	int y;
5181 
5182 	mpt_get_fw_exp_ver(expVer, ioc);
5183 
5184 	/*
5185 	 *  Shorter summary of attached ioc's...
5186 	 */
5187 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5188 			ioc->name,
5189 			ioc->prod_name,
5190 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
5191 			ioc->facts.FWVersion.Word,
5192 			expVer,
5193 			ioc->facts.NumberOfPorts,
5194 			ioc->req_depth);
5195 
5196 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5197 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5198 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5199 			a[5], a[4], a[3], a[2], a[1], a[0]);
5200 	}
5201 
5202 #ifndef __sparc__
5203 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5204 #else
5205 	y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5206 #endif
5207 
5208 	if (!ioc->active)
5209 		y += sprintf(buffer+len+y, " (disabled)");
5210 
5211 	y += sprintf(buffer+len+y, "\n");
5212 
5213 	*size = y;
5214 }
5215 
5216 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5217 /*
5218  *	Reset Handling
5219  */
5220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5221 /**
5222  *	mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5223  *	Management call based on input arg values.  If TaskMgmt fails,
5224  *	return associated SCSI request.
5225  *	@ioc: Pointer to MPT_ADAPTER structure
5226  *	@sleepFlag: Indicates if sleep or schedule must be called.
5227  *
5228  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5229  *	or a non-interrupt thread.  In the former, must not call schedule().
5230  *
5231  *	Remark: A return of -1 is a FATAL error case, as it means a
5232  *	FW reload/initialization failed.
5233  *
5234  *	Returns 0 for SUCCESS or -1 if FAILED.
5235  */
5236 int
5237 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5238 {
5239 	int		 rc;
5240 	unsigned long	 flags;
5241 
5242 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5243 #ifdef MFCNT
5244 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5245 	printk("MF count 0x%x !\n", ioc->mfcnt);
5246 #endif
5247 
5248 	/* Reset the adapter. Prevent more than 1 call to
5249 	 * mpt_do_ioc_recovery at any instant in time.
5250 	 */
5251 	spin_lock_irqsave(&ioc->diagLock, flags);
5252 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5253 		spin_unlock_irqrestore(&ioc->diagLock, flags);
5254 		return 0;
5255 	} else {
5256 		ioc->diagPending = 1;
5257 	}
5258 	spin_unlock_irqrestore(&ioc->diagLock, flags);
5259 
5260 	/* FIXME: If do_ioc_recovery fails, repeat....
5261 	 */
5262 
5263 	/* The SCSI driver needs to adjust timeouts on all current
5264 	 * commands prior to the diagnostic reset being issued.
5265 	 * Prevents timeouts occuring during a diagnostic reset...very bad.
5266 	 * For all other protocol drivers, this is a no-op.
5267 	 */
5268 	{
5269 		int	 ii;
5270 		int	 r = 0;
5271 
5272 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5273 			if (MptResetHandlers[ii]) {
5274 				dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5275 						ioc->name, ii));
5276 				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5277 				if (ioc->alt_ioc) {
5278 					dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5279 							ioc->name, ioc->alt_ioc->name, ii));
5280 					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5281 				}
5282 			}
5283 		}
5284 	}
5285 
5286 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5287 		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5288 			rc, ioc->name);
5289 	}
5290 	ioc->reload_fw = 0;
5291 	if (ioc->alt_ioc)
5292 		ioc->alt_ioc->reload_fw = 0;
5293 
5294 	spin_lock_irqsave(&ioc->diagLock, flags);
5295 	ioc->diagPending = 0;
5296 	if (ioc->alt_ioc)
5297 		ioc->alt_ioc->diagPending = 0;
5298 	spin_unlock_irqrestore(&ioc->diagLock, flags);
5299 
5300 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5301 
5302 	return rc;
5303 }
5304 
5305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5306 static char *
5307 EventDescriptionStr(u8 event, u32 evData0)
5308 {
5309 	char *ds;
5310 
5311 	switch(event) {
5312 	case MPI_EVENT_NONE:
5313 		ds = "None";
5314 		break;
5315 	case MPI_EVENT_LOG_DATA:
5316 		ds = "Log Data";
5317 		break;
5318 	case MPI_EVENT_STATE_CHANGE:
5319 		ds = "State Change";
5320 		break;
5321 	case MPI_EVENT_UNIT_ATTENTION:
5322 		ds = "Unit Attention";
5323 		break;
5324 	case MPI_EVENT_IOC_BUS_RESET:
5325 		ds = "IOC Bus Reset";
5326 		break;
5327 	case MPI_EVENT_EXT_BUS_RESET:
5328 		ds = "External Bus Reset";
5329 		break;
5330 	case MPI_EVENT_RESCAN:
5331 		ds = "Bus Rescan Event";
5332 		/* Ok, do we need to do anything here? As far as
5333 		   I can tell, this is when a new device gets added
5334 		   to the loop. */
5335 		break;
5336 	case MPI_EVENT_LINK_STATUS_CHANGE:
5337 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5338 			ds = "Link Status(FAILURE) Change";
5339 		else
5340 			ds = "Link Status(ACTIVE) Change";
5341 		break;
5342 	case MPI_EVENT_LOOP_STATE_CHANGE:
5343 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5344 			ds = "Loop State(LIP) Change";
5345 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5346 			ds = "Loop State(LPE) Change";			/* ??? */
5347 		else
5348 			ds = "Loop State(LPB) Change";			/* ??? */
5349 		break;
5350 	case MPI_EVENT_LOGOUT:
5351 		ds = "Logout";
5352 		break;
5353 	case MPI_EVENT_EVENT_CHANGE:
5354 		if (evData0)
5355 			ds = "Events(ON) Change";
5356 		else
5357 			ds = "Events(OFF) Change";
5358 		break;
5359 	case MPI_EVENT_INTEGRATED_RAID:
5360 		ds = "Integrated Raid";
5361 		break;
5362 	/*
5363 	 *  MPT base "custom" events may be added here...
5364 	 */
5365 	default:
5366 		ds = "Unknown";
5367 		break;
5368 	}
5369 	return ds;
5370 }
5371 
5372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5373 /*
5374  *	ProcessEventNotification - Route a received EventNotificationReply to
5375  *	all currently regeistered event handlers.
5376  *	@ioc: Pointer to MPT_ADAPTER structure
5377  *	@pEventReply: Pointer to EventNotification reply frame
5378  *	@evHandlers: Pointer to integer, number of event handlers
5379  *
5380  *	Returns sum of event handlers return values.
5381  */
5382 static int
5383 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5384 {
5385 	u16 evDataLen;
5386 	u32 evData0 = 0;
5387 //	u32 evCtx;
5388 	int ii;
5389 	int r = 0;
5390 	int handlers = 0;
5391 	char *evStr;
5392 	u8 event;
5393 
5394 	/*
5395 	 *  Do platform normalization of values
5396 	 */
5397 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
5398 //	evCtx = le32_to_cpu(pEventReply->EventContext);
5399 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5400 	if (evDataLen) {
5401 		evData0 = le32_to_cpu(pEventReply->Data[0]);
5402 	}
5403 
5404 	evStr = EventDescriptionStr(event, evData0);
5405 	devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5406 			ioc->name,
5407 			evStr,
5408 			event));
5409 
5410 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5411 	printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5412 	for (ii = 0; ii < evDataLen; ii++)
5413 		printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5414 	printk("\n");
5415 #endif
5416 
5417 	/*
5418 	 *  Do general / base driver event processing
5419 	 */
5420 	switch(event) {
5421 	case MPI_EVENT_NONE:			/* 00 */
5422 	case MPI_EVENT_LOG_DATA:		/* 01 */
5423 	case MPI_EVENT_STATE_CHANGE:		/* 02 */
5424 	case MPI_EVENT_UNIT_ATTENTION:		/* 03 */
5425 	case MPI_EVENT_IOC_BUS_RESET:		/* 04 */
5426 	case MPI_EVENT_EXT_BUS_RESET:		/* 05 */
5427 	case MPI_EVENT_RESCAN:			/* 06 */
5428 	case MPI_EVENT_LINK_STATUS_CHANGE:	/* 07 */
5429 	case MPI_EVENT_LOOP_STATE_CHANGE:	/* 08 */
5430 	case MPI_EVENT_LOGOUT:			/* 09 */
5431 	case MPI_EVENT_INTEGRATED_RAID:		/* 0B */
5432 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:	/* 0C */
5433 	default:
5434 		break;
5435 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
5436 		if (evDataLen) {
5437 			u8 evState = evData0 & 0xFF;
5438 
5439 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
5440 
5441 			/* Update EventState field in cached IocFacts */
5442 			if (ioc->facts.Function) {
5443 				ioc->facts.EventState = evState;
5444 			}
5445 		}
5446 		break;
5447 	}
5448 
5449 	/*
5450 	 * Should this event be logged? Events are written sequentially.
5451 	 * When buffer is full, start again at the top.
5452 	 */
5453 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5454 		int idx;
5455 
5456 		idx = ioc->eventContext % ioc->eventLogSize;
5457 
5458 		ioc->events[idx].event = event;
5459 		ioc->events[idx].eventContext = ioc->eventContext;
5460 
5461 		for (ii = 0; ii < 2; ii++) {
5462 			if (ii < evDataLen)
5463 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5464 			else
5465 				ioc->events[idx].data[ii] =  0;
5466 		}
5467 
5468 		ioc->eventContext++;
5469 	}
5470 
5471 
5472 	/*
5473 	 *  Call each currently registered protocol event handler.
5474 	 */
5475 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5476 		if (MptEvHandlers[ii]) {
5477 			devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5478 					ioc->name, ii));
5479 			r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5480 			handlers++;
5481 		}
5482 	}
5483 	/* FIXME?  Examine results here? */
5484 
5485 	/*
5486 	 *  If needed, send (a single) EventAck.
5487 	 */
5488 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5489 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5490 			devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5491 					ioc->name, ii));
5492 		}
5493 	}
5494 
5495 	*evHandlers = handlers;
5496 	return r;
5497 }
5498 
5499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5500 /*
5501  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5502  *	@ioc: Pointer to MPT_ADAPTER structure
5503  *	@log_info: U32 LogInfo reply word from the IOC
5504  *
5505  *	Refer to lsi/fc_log.h.
5506  */
5507 static void
5508 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5509 {
5510 	static char *subcl_str[8] = {
5511 		"FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5512 		"FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5513 	};
5514 	u8 subcl = (log_info >> 24) & 0x7;
5515 
5516 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5517 			ioc->name, log_info, subcl_str[subcl]);
5518 }
5519 
5520 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5521 /*
5522  *	mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5523  *	@ioc: Pointer to MPT_ADAPTER structure
5524  *	@mr: Pointer to MPT reply frame
5525  *	@log_info: U32 LogInfo word from the IOC
5526  *
5527  *	Refer to lsi/sp_log.h.
5528  */
5529 static void
5530 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5531 {
5532 	u32 info = log_info & 0x00FF0000;
5533 	char *desc = "unknown";
5534 
5535 	switch (info) {
5536 	case 0x00010000:
5537 		desc = "bug! MID not found";
5538 		if (ioc->reload_fw == 0)
5539 			ioc->reload_fw++;
5540 		break;
5541 
5542 	case 0x00020000:
5543 		desc = "Parity Error";
5544 		break;
5545 
5546 	case 0x00030000:
5547 		desc = "ASYNC Outbound Overrun";
5548 		break;
5549 
5550 	case 0x00040000:
5551 		desc = "SYNC Offset Error";
5552 		break;
5553 
5554 	case 0x00050000:
5555 		desc = "BM Change";
5556 		break;
5557 
5558 	case 0x00060000:
5559 		desc = "Msg In Overflow";
5560 		break;
5561 
5562 	case 0x00070000:
5563 		desc = "DMA Error";
5564 		break;
5565 
5566 	case 0x00080000:
5567 		desc = "Outbound DMA Overrun";
5568 		break;
5569 
5570 	case 0x00090000:
5571 		desc = "Task Management";
5572 		break;
5573 
5574 	case 0x000A0000:
5575 		desc = "Device Problem";
5576 		break;
5577 
5578 	case 0x000B0000:
5579 		desc = "Invalid Phase Change";
5580 		break;
5581 
5582 	case 0x000C0000:
5583 		desc = "Untagged Table Size";
5584 		break;
5585 
5586 	}
5587 
5588 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5589 }
5590 
5591 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5592 /*
5593  *	mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5594  *	@ioc: Pointer to MPT_ADAPTER structure
5595  *	@ioc_status: U32 IOCStatus word from IOC
5596  *	@mf: Pointer to MPT request frame
5597  *
5598  *	Refer to lsi/mpi.h.
5599  */
5600 static void
5601 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5602 {
5603 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5604 	char *desc = "";
5605 
5606 	switch (status) {
5607 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5608 		desc = "Invalid Function";
5609 		break;
5610 
5611 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5612 		desc = "Busy";
5613 		break;
5614 
5615 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5616 		desc = "Invalid SGL";
5617 		break;
5618 
5619 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5620 		desc = "Internal Error";
5621 		break;
5622 
5623 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5624 		desc = "Reserved";
5625 		break;
5626 
5627 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5628 		desc = "Insufficient Resources";
5629 		break;
5630 
5631 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5632 		desc = "Invalid Field";
5633 		break;
5634 
5635 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5636 		desc = "Invalid State";
5637 		break;
5638 
5639 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5640 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
5641 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
5642 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
5643 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
5644 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
5645 		/* No message for Config IOCStatus values */
5646 		break;
5647 
5648 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5649 		/* No message for recovered error
5650 		desc = "SCSI Recovered Error";
5651 		*/
5652 		break;
5653 
5654 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5655 		desc = "SCSI Invalid Bus";
5656 		break;
5657 
5658 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5659 		desc = "SCSI Invalid TargetID";
5660 		break;
5661 
5662 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5663 	  {
5664 		SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5665 		U8 cdb = pScsiReq->CDB[0];
5666 		if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5667 			desc = "SCSI Device Not There";
5668 		}
5669 		break;
5670 	  }
5671 
5672 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5673 		desc = "SCSI Data Overrun";
5674 		break;
5675 
5676 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5677 		/* This error is checked in scsi_io_done(). Skip.
5678 		desc = "SCSI Data Underrun";
5679 		*/
5680 		break;
5681 
5682 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5683 		desc = "SCSI I/O Data Error";
5684 		break;
5685 
5686 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5687 		desc = "SCSI Protocol Error";
5688 		break;
5689 
5690 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5691 		desc = "SCSI Task Terminated";
5692 		break;
5693 
5694 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5695 		desc = "SCSI Residual Mismatch";
5696 		break;
5697 
5698 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5699 		desc = "SCSI Task Management Failed";
5700 		break;
5701 
5702 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5703 		desc = "SCSI IOC Terminated";
5704 		break;
5705 
5706 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5707 		desc = "SCSI Ext Terminated";
5708 		break;
5709 
5710 	default:
5711 		desc = "Others";
5712 		break;
5713 	}
5714 	if (desc != "")
5715 		printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5716 }
5717 
5718 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5719 EXPORT_SYMBOL(mpt_attach);
5720 EXPORT_SYMBOL(mpt_detach);
5721 #ifdef CONFIG_PM
5722 EXPORT_SYMBOL(mpt_resume);
5723 EXPORT_SYMBOL(mpt_suspend);
5724 #endif
5725 EXPORT_SYMBOL(ioc_list);
5726 EXPORT_SYMBOL(mpt_proc_root_dir);
5727 EXPORT_SYMBOL(mpt_register);
5728 EXPORT_SYMBOL(mpt_deregister);
5729 EXPORT_SYMBOL(mpt_event_register);
5730 EXPORT_SYMBOL(mpt_event_deregister);
5731 EXPORT_SYMBOL(mpt_reset_register);
5732 EXPORT_SYMBOL(mpt_reset_deregister);
5733 EXPORT_SYMBOL(mpt_device_driver_register);
5734 EXPORT_SYMBOL(mpt_device_driver_deregister);
5735 EXPORT_SYMBOL(mpt_get_msg_frame);
5736 EXPORT_SYMBOL(mpt_put_msg_frame);
5737 EXPORT_SYMBOL(mpt_free_msg_frame);
5738 EXPORT_SYMBOL(mpt_add_sge);
5739 EXPORT_SYMBOL(mpt_send_handshake_request);
5740 EXPORT_SYMBOL(mpt_verify_adapter);
5741 EXPORT_SYMBOL(mpt_GetIocState);
5742 EXPORT_SYMBOL(mpt_print_ioc_summary);
5743 EXPORT_SYMBOL(mpt_lan_index);
5744 EXPORT_SYMBOL(mpt_stm_index);
5745 EXPORT_SYMBOL(mpt_HardResetHandler);
5746 EXPORT_SYMBOL(mpt_config);
5747 EXPORT_SYMBOL(mpt_toolbox);
5748 EXPORT_SYMBOL(mpt_findImVolumes);
5749 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5750 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5751 EXPORT_SYMBOL(mpt_free_fw_memory);
5752 
5753 
5754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5755 /*
5756  *	fusion_init - Fusion MPT base driver initialization routine.
5757  *
5758  *	Returns 0 for success, non-zero for failure.
5759  */
5760 static int __init
5761 fusion_init(void)
5762 {
5763 	int i;
5764 
5765 	show_mptmod_ver(my_NAME, my_VERSION);
5766 	printk(KERN_INFO COPYRIGHT "\n");
5767 
5768 	for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5769 		MptCallbacks[i] = NULL;
5770 		MptDriverClass[i] = MPTUNKNOWN_DRIVER;
5771 		MptEvHandlers[i] = NULL;
5772 		MptResetHandlers[i] = NULL;
5773 	}
5774 
5775 	/*  Register ourselves (mptbase) in order to facilitate
5776 	 *  EventNotification handling.
5777 	 */
5778 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
5779 
5780 	/* Register for hard reset handling callbacks.
5781 	 */
5782 	if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
5783 		dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
5784 	} else {
5785 		/* FIXME! */
5786 	}
5787 
5788 #ifdef CONFIG_PROC_FS
5789 	(void) procmpt_create();
5790 #endif
5791 	return 0;
5792 }
5793 
5794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5795 /*
5796  *	fusion_exit - Perform driver unload cleanup.
5797  *
5798  *	This routine frees all resources associated with each MPT adapter
5799  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
5800  */
5801 static void __exit
5802 fusion_exit(void)
5803 {
5804 
5805 	dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
5806 
5807 	mpt_reset_deregister(mpt_base_index);
5808 
5809 #ifdef CONFIG_PROC_FS
5810 	procmpt_destroy();
5811 #endif
5812 }
5813 
5814 module_init(fusion_init);
5815 module_exit(fusion_exit);
5816