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