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