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