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