xref: /openbmc/linux/drivers/message/fusion/mptbase.c (revision 3fadc59d603caf70e7a5295158e4f6eb06dffb8f)
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 	if (ioc->spi_data.nvram != NULL) {
1841 		kfree(ioc->spi_data.nvram);
1842 		ioc->spi_data.nvram = NULL;
1843 	}
1844 
1845 	if (ioc->spi_data.pIocPg3 != NULL) {
1846 		kfree(ioc->spi_data.pIocPg3);
1847 		ioc->spi_data.pIocPg3 = NULL;
1848 	}
1849 
1850 	if (ioc->spi_data.pIocPg4 != NULL) {
1851 		sz = ioc->spi_data.IocPg4Sz;
1852 		pci_free_consistent(ioc->pcidev, sz,
1853 			ioc->spi_data.pIocPg4,
1854 			ioc->spi_data.IocPg4_dma);
1855 		ioc->spi_data.pIocPg4 = NULL;
1856 		ioc->alloc_total -= sz;
1857 	}
1858 
1859 	if (ioc->ReqToChain != NULL) {
1860 		kfree(ioc->ReqToChain);
1861 		kfree(ioc->RequestNB);
1862 		ioc->ReqToChain = NULL;
1863 	}
1864 
1865 	if (ioc->ChainToChain != NULL) {
1866 		kfree(ioc->ChainToChain);
1867 		ioc->ChainToChain = NULL;
1868 	}
1869 }
1870 
1871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1872 /*
1873  *	mpt_adapter_dispose - Free all resources associated with a MPT
1874  *	adapter.
1875  *	@ioc: Pointer to MPT adapter structure
1876  *
1877  *	This routine unregisters h/w resources and frees all alloc'd memory
1878  *	associated with a MPT adapter structure.
1879  */
1880 static void
1881 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1882 {
1883 	if (ioc != NULL) {
1884 		int sz_first, sz_last;
1885 
1886 		sz_first = ioc->alloc_total;
1887 
1888 		mpt_adapter_disable(ioc);
1889 
1890 		if (ioc->pci_irq != -1) {
1891 			free_irq(ioc->pci_irq, ioc);
1892 			ioc->pci_irq = -1;
1893 		}
1894 
1895 		if (ioc->memmap != NULL)
1896 			iounmap(ioc->memmap);
1897 
1898 #if defined(CONFIG_MTRR) && 0
1899 		if (ioc->mtrr_reg > 0) {
1900 			mtrr_del(ioc->mtrr_reg, 0, 0);
1901 			dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1902 		}
1903 #endif
1904 
1905 		/*  Zap the adapter lookup ptr!  */
1906 		list_del(&ioc->list);
1907 
1908 		sz_last = ioc->alloc_total;
1909 		dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1910 				ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1911 		kfree(ioc);
1912 	}
1913 }
1914 
1915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1916 /*
1917  *	MptDisplayIocCapabilities - Disply IOC's capacilities.
1918  *	@ioc: Pointer to MPT adapter structure
1919  */
1920 static void
1921 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1922 {
1923 	int i = 0;
1924 
1925 	printk(KERN_INFO "%s: ", ioc->name);
1926 	if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1927 		printk("%s: ", ioc->prod_name+3);
1928 	printk("Capabilities={");
1929 
1930 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1931 		printk("Initiator");
1932 		i++;
1933 	}
1934 
1935 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1936 		printk("%sTarget", i ? "," : "");
1937 		i++;
1938 	}
1939 
1940 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1941 		printk("%sLAN", i ? "," : "");
1942 		i++;
1943 	}
1944 
1945 #if 0
1946 	/*
1947 	 *  This would probably evoke more questions than it's worth
1948 	 */
1949 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1950 		printk("%sLogBusAddr", i ? "," : "");
1951 		i++;
1952 	}
1953 #endif
1954 
1955 	printk("}\n");
1956 }
1957 
1958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1959 /*
1960  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1961  *	@ioc: Pointer to MPT_ADAPTER structure
1962  *	@force: Force hard KickStart of IOC
1963  *	@sleepFlag: Specifies whether the process can sleep
1964  *
1965  *	Returns:
1966  *		 1 - DIAG reset and READY
1967  *		 0 - READY initially OR soft reset and READY
1968  *		-1 - Any failure on KickStart
1969  *		-2 - Msg Unit Reset Failed
1970  *		-3 - IO Unit Reset Failed
1971  *		-4 - IOC owned by a PEER
1972  */
1973 static int
1974 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1975 {
1976 	u32	 ioc_state;
1977 	int	 statefault = 0;
1978 	int	 cntdn;
1979 	int	 hard_reset_done = 0;
1980 	int	 r;
1981 	int	 ii;
1982 	int	 whoinit;
1983 
1984 	/* Get current [raw] IOC state  */
1985 	ioc_state = mpt_GetIocState(ioc, 0);
1986 	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1987 
1988 	/*
1989 	 *	Check to see if IOC got left/stuck in doorbell handshake
1990 	 *	grip of death.  If so, hard reset the IOC.
1991 	 */
1992 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
1993 		statefault = 1;
1994 		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1995 				ioc->name);
1996 	}
1997 
1998 	/* Is it already READY? */
1999 	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2000 		return 0;
2001 
2002 	/*
2003 	 *	Check to see if IOC is in FAULT state.
2004 	 */
2005 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2006 		statefault = 2;
2007 		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2008 				ioc->name);
2009 		printk(KERN_WARNING "           FAULT code = %04xh\n",
2010 				ioc_state & MPI_DOORBELL_DATA_MASK);
2011 	}
2012 
2013 	/*
2014 	 *	Hmmm...  Did it get left operational?
2015 	 */
2016 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2017 		dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2018 				ioc->name));
2019 
2020 		/* Check WhoInit.
2021 		 * If PCI Peer, exit.
2022 		 * Else, if no fault conditions are present, issue a MessageUnitReset
2023 		 * Else, fall through to KickStart case
2024 		 */
2025 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2026 		dprintk((KERN_WARNING MYNAM
2027 			": whoinit 0x%x\n statefault %d force %d\n",
2028 			whoinit, statefault, force));
2029 		if (whoinit == MPI_WHOINIT_PCI_PEER)
2030 			return -4;
2031 		else {
2032 			if ((statefault == 0 ) && (force == 0)) {
2033 				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2034 					return 0;
2035 			}
2036 			statefault = 3;
2037 		}
2038 	}
2039 
2040 	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2041 	if (hard_reset_done < 0)
2042 		return -1;
2043 
2044 	/*
2045 	 *  Loop here waiting for IOC to come READY.
2046 	 */
2047 	ii = 0;
2048 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
2049 
2050 	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2051 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2052 			/*
2053 			 *  BIOS or previous driver load left IOC in OP state.
2054 			 *  Reset messaging FIFOs.
2055 			 */
2056 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2057 				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2058 				return -2;
2059 			}
2060 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
2061 			/*
2062 			 *  Something is wrong.  Try to get IOC back
2063 			 *  to a known state.
2064 			 */
2065 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2066 				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2067 				return -3;
2068 			}
2069 		}
2070 
2071 		ii++; cntdn--;
2072 		if (!cntdn) {
2073 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2074 					ioc->name, (int)((ii+5)/HZ));
2075 			return -ETIME;
2076 		}
2077 
2078 		if (sleepFlag == CAN_SLEEP) {
2079 			msleep_interruptible(1);
2080 		} else {
2081 			mdelay (1);	/* 1 msec delay */
2082 		}
2083 
2084 	}
2085 
2086 	if (statefault < 3) {
2087 		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2088 				ioc->name,
2089 				statefault==1 ? "stuck handshake" : "IOC FAULT");
2090 	}
2091 
2092 	return hard_reset_done;
2093 }
2094 
2095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2096 /*
2097  *	mpt_GetIocState - Get the current state of a MPT adapter.
2098  *	@ioc: Pointer to MPT_ADAPTER structure
2099  *	@cooked: Request raw or cooked IOC state
2100  *
2101  *	Returns all IOC Doorbell register bits if cooked==0, else just the
2102  *	Doorbell bits in MPI_IOC_STATE_MASK.
2103  */
2104 u32
2105 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2106 {
2107 	u32 s, sc;
2108 
2109 	/*  Get!  */
2110 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
2111 //	dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2112 	sc = s & MPI_IOC_STATE_MASK;
2113 
2114 	/*  Save!  */
2115 	ioc->last_state = sc;
2116 
2117 	return cooked ? sc : s;
2118 }
2119 
2120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2121 /*
2122  *	GetIocFacts - Send IOCFacts request to MPT adapter.
2123  *	@ioc: Pointer to MPT_ADAPTER structure
2124  *	@sleepFlag: Specifies whether the process can sleep
2125  *	@reason: If recovery, only update facts.
2126  *
2127  *	Returns 0 for success, non-zero for failure.
2128  */
2129 static int
2130 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2131 {
2132 	IOCFacts_t		 get_facts;
2133 	IOCFactsReply_t		*facts;
2134 	int			 r;
2135 	int			 req_sz;
2136 	int			 reply_sz;
2137 	int			 sz;
2138 	u32			 status, vv;
2139 	u8			 shiftFactor=1;
2140 
2141 	/* IOC *must* NOT be in RESET state! */
2142 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2143 		printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2144 				ioc->name,
2145 				ioc->last_state );
2146 		return -44;
2147 	}
2148 
2149 	facts = &ioc->facts;
2150 
2151 	/* Destination (reply area)... */
2152 	reply_sz = sizeof(*facts);
2153 	memset(facts, 0, reply_sz);
2154 
2155 	/* Request area (get_facts on the stack right now!) */
2156 	req_sz = sizeof(get_facts);
2157 	memset(&get_facts, 0, req_sz);
2158 
2159 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2160 	/* Assert: All other get_facts fields are zero! */
2161 
2162 	dinitprintk((MYIOC_s_INFO_FMT
2163 	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2164 	    ioc->name, req_sz, reply_sz));
2165 
2166 	/* No non-zero fields in the get_facts request are greater than
2167 	 * 1 byte in size, so we can just fire it off as is.
2168 	 */
2169 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2170 			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2171 	if (r != 0)
2172 		return r;
2173 
2174 	/*
2175 	 * Now byte swap (GRRR) the necessary fields before any further
2176 	 * inspection of reply contents.
2177 	 *
2178 	 * But need to do some sanity checks on MsgLength (byte) field
2179 	 * to make sure we don't zero IOC's req_sz!
2180 	 */
2181 	/* Did we get a valid reply? */
2182 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2183 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2184 			/*
2185 			 * If not been here, done that, save off first WhoInit value
2186 			 */
2187 			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2188 				ioc->FirstWhoInit = facts->WhoInit;
2189 		}
2190 
2191 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2192 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
2193 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2194 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2195 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2196 		status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2197 		/* CHECKME! IOCStatus, IOCLogInfo */
2198 
2199 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2200 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2201 
2202 		/*
2203 		 * FC f/w version changed between 1.1 and 1.2
2204 		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
2205 		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2206 		 */
2207 		if (facts->MsgVersion < 0x0102) {
2208 			/*
2209 			 *	Handle old FC f/w style, convert to new...
2210 			 */
2211 			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2212 			facts->FWVersion.Word =
2213 					((oldv<<12) & 0xFF000000) |
2214 					((oldv<<8)  & 0x000FFF00);
2215 		} else
2216 			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2217 
2218 		facts->ProductID = le16_to_cpu(facts->ProductID);
2219 		facts->CurrentHostMfaHighAddr =
2220 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
2221 		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2222 		facts->CurrentSenseBufferHighAddr =
2223 				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2224 		facts->CurReplyFrameSize =
2225 				le16_to_cpu(facts->CurReplyFrameSize);
2226 
2227 		/*
2228 		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2229 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2230 		 * to 14 in MPI-1.01.0x.
2231 		 */
2232 		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2233 		    facts->MsgVersion > 0x0100) {
2234 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2235 		}
2236 
2237 		sz = facts->FWImageSize;
2238 		if ( sz & 0x01 )
2239 			sz += 1;
2240 		if ( sz & 0x02 )
2241 			sz += 2;
2242 		facts->FWImageSize = sz;
2243 
2244 		if (!facts->RequestFrameSize) {
2245 			/*  Something is wrong!  */
2246 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2247 					ioc->name);
2248 			return -55;
2249 		}
2250 
2251 		r = sz = facts->BlockSize;
2252 		vv = ((63 / (sz * 4)) + 1) & 0x03;
2253 		ioc->NB_for_64_byte_frame = vv;
2254 		while ( sz )
2255 		{
2256 			shiftFactor++;
2257 			sz = sz >> 1;
2258 		}
2259 		ioc->NBShiftFactor  = shiftFactor;
2260 		dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2261 					ioc->name, vv, shiftFactor, r));
2262 
2263 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2264 			/*
2265 			 * Set values for this IOC's request & reply frame sizes,
2266 			 * and request & reply queue depths...
2267 			 */
2268 			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2269 			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2270 			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2271 			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2272 
2273 			dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2274 				ioc->name, ioc->reply_sz, ioc->reply_depth));
2275 			dinitprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
2276 				ioc->name, ioc->req_sz, ioc->req_depth));
2277 
2278 			/* Get port facts! */
2279 			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2280 				return r;
2281 		}
2282 	} else {
2283 		printk(MYIOC_s_ERR_FMT
2284 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2285 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2286 		     RequestFrameSize)/sizeof(u32)));
2287 		return -66;
2288 	}
2289 
2290 	return 0;
2291 }
2292 
2293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2294 /*
2295  *	GetPortFacts - Send PortFacts request to MPT adapter.
2296  *	@ioc: Pointer to MPT_ADAPTER structure
2297  *	@portnum: Port number
2298  *	@sleepFlag: Specifies whether the process can sleep
2299  *
2300  *	Returns 0 for success, non-zero for failure.
2301  */
2302 static int
2303 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2304 {
2305 	PortFacts_t		 get_pfacts;
2306 	PortFactsReply_t	*pfacts;
2307 	int			 ii;
2308 	int			 req_sz;
2309 	int			 reply_sz;
2310 
2311 	/* IOC *must* NOT be in RESET state! */
2312 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2313 		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2314 				ioc->name,
2315 				ioc->last_state );
2316 		return -4;
2317 	}
2318 
2319 	pfacts = &ioc->pfacts[portnum];
2320 
2321 	/* Destination (reply area)...  */
2322 	reply_sz = sizeof(*pfacts);
2323 	memset(pfacts, 0, reply_sz);
2324 
2325 	/* Request area (get_pfacts on the stack right now!) */
2326 	req_sz = sizeof(get_pfacts);
2327 	memset(&get_pfacts, 0, req_sz);
2328 
2329 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2330 	get_pfacts.PortNumber = portnum;
2331 	/* Assert: All other get_pfacts fields are zero! */
2332 
2333 	dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2334 			ioc->name, portnum));
2335 
2336 	/* No non-zero fields in the get_pfacts request are greater than
2337 	 * 1 byte in size, so we can just fire it off as is.
2338 	 */
2339 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2340 				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2341 	if (ii != 0)
2342 		return ii;
2343 
2344 	/* Did we get a valid reply? */
2345 
2346 	/* Now byte swap the necessary fields in the response. */
2347 	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2348 	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2349 	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2350 	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2351 	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2352 	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2353 	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2354 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2355 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2356 
2357 	return 0;
2358 }
2359 
2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2361 /*
2362  *	SendIocInit - Send IOCInit request to MPT adapter.
2363  *	@ioc: Pointer to MPT_ADAPTER structure
2364  *	@sleepFlag: Specifies whether the process can sleep
2365  *
2366  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2367  *
2368  *	Returns 0 for success, non-zero for failure.
2369  */
2370 static int
2371 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2372 {
2373 	IOCInit_t		 ioc_init;
2374 	MPIDefaultReply_t	 init_reply;
2375 	u32			 state;
2376 	int			 r;
2377 	int			 count;
2378 	int			 cntdn;
2379 
2380 	memset(&ioc_init, 0, sizeof(ioc_init));
2381 	memset(&init_reply, 0, sizeof(init_reply));
2382 
2383 	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2384 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2385 
2386 	/* If we are in a recovery mode and we uploaded the FW image,
2387 	 * then this pointer is not NULL. Skip the upload a second time.
2388 	 * Set this flag if cached_fw set for either IOC.
2389 	 */
2390 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2391 		ioc->upload_fw = 1;
2392 	else
2393 		ioc->upload_fw = 0;
2394 	ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2395 		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
2396 
2397 	if (ioc->bus_type == FC)
2398 		ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2399 	else
2400 		ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2401 
2402 	ioc_init.MaxBuses = MPT_MAX_BUS;
2403 
2404 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
2405 
2406 	if (sizeof(dma_addr_t) == sizeof(u64)) {
2407 		/* Save the upper 32-bits of the request
2408 		 * (reply) and sense buffers.
2409 		 */
2410 		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2411 		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2412 	} else {
2413 		/* Force 32-bit addressing */
2414 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2415 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2416 	}
2417 
2418 	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2419 	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2420 
2421 	dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2422 			ioc->name, &ioc_init));
2423 
2424 	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2425 				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2426 	if (r != 0)
2427 		return r;
2428 
2429 	/* No need to byte swap the multibyte fields in the reply
2430 	 * since we don't even look at it's contents.
2431 	 */
2432 
2433 	dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2434 			ioc->name, &ioc_init));
2435 
2436 	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2437 		return r;
2438 
2439 	/* YIKES!  SUPER IMPORTANT!!!
2440 	 *  Poll IocState until _OPERATIONAL while IOC is doing
2441 	 *  LoopInit and TargetDiscovery!
2442 	 */
2443 	count = 0;
2444 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
2445 	state = mpt_GetIocState(ioc, 1);
2446 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2447 		if (sleepFlag == CAN_SLEEP) {
2448 			msleep_interruptible(1);
2449 		} else {
2450 			mdelay(1);
2451 		}
2452 
2453 		if (!cntdn) {
2454 			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2455 					ioc->name, (int)((count+5)/HZ));
2456 			return -9;
2457 		}
2458 
2459 		state = mpt_GetIocState(ioc, 1);
2460 		count++;
2461 	}
2462 	dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2463 			ioc->name, count));
2464 
2465 	return r;
2466 }
2467 
2468 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2469 /*
2470  *	SendPortEnable - Send PortEnable request to MPT adapter port.
2471  *	@ioc: Pointer to MPT_ADAPTER structure
2472  *	@portnum: Port number to enable
2473  *	@sleepFlag: Specifies whether the process can sleep
2474  *
2475  *	Send PortEnable to bring IOC to OPERATIONAL state.
2476  *
2477  *	Returns 0 for success, non-zero for failure.
2478  */
2479 static int
2480 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2481 {
2482 	PortEnable_t		 port_enable;
2483 	MPIDefaultReply_t	 reply_buf;
2484 	int	 ii;
2485 	int	 req_sz;
2486 	int	 reply_sz;
2487 
2488 	/*  Destination...  */
2489 	reply_sz = sizeof(MPIDefaultReply_t);
2490 	memset(&reply_buf, 0, reply_sz);
2491 
2492 	req_sz = sizeof(PortEnable_t);
2493 	memset(&port_enable, 0, req_sz);
2494 
2495 	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2496 	port_enable.PortNumber = portnum;
2497 /*	port_enable.ChainOffset = 0;		*/
2498 /*	port_enable.MsgFlags = 0;		*/
2499 /*	port_enable.MsgContext = 0;		*/
2500 
2501 	dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2502 			ioc->name, portnum, &port_enable));
2503 
2504 	/* RAID FW may take a long time to enable
2505 	 */
2506 	if (ioc->bus_type == FC) {
2507 		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2508 				reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2509 	} else {
2510 		ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2511 				reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2512 	}
2513 
2514 	if (ii != 0)
2515 		return ii;
2516 
2517 	/* We do not even look at the reply, so we need not
2518 	 * swap the multi-byte fields.
2519 	 */
2520 
2521 	return 0;
2522 }
2523 
2524 /*
2525  *	ioc: Pointer to MPT_ADAPTER structure
2526  *      size - total FW bytes
2527  */
2528 void
2529 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2530 {
2531 	if (ioc->cached_fw)
2532 		return;  /* use already allocated memory */
2533 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2534 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2535 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2536 	} else {
2537 		if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2538 			ioc->alloc_total += size;
2539 	}
2540 }
2541 /*
2542  * If alt_img is NULL, delete from ioc structure.
2543  * Else, delete a secondary image in same format.
2544  */
2545 void
2546 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2547 {
2548 	int sz;
2549 
2550 	sz = ioc->facts.FWImageSize;
2551 	dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2552 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2553 	pci_free_consistent(ioc->pcidev, sz,
2554 			ioc->cached_fw, ioc->cached_fw_dma);
2555 	ioc->cached_fw = NULL;
2556 
2557 	return;
2558 }
2559 
2560 
2561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2562 /*
2563  *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2564  *	@ioc: Pointer to MPT_ADAPTER structure
2565  *	@sleepFlag: Specifies whether the process can sleep
2566  *
2567  *	Returns 0 for success, >0 for handshake failure
2568  *		<0 for fw upload failure.
2569  *
2570  *	Remark: If bound IOC and a successful FWUpload was performed
2571  *	on the bound IOC, the second image is discarded
2572  *	and memory is free'd. Both channels must upload to prevent
2573  *	IOC from running in degraded mode.
2574  */
2575 static int
2576 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2577 {
2578 	u8			 request[ioc->req_sz];
2579 	u8			 reply[sizeof(FWUploadReply_t)];
2580 	FWUpload_t		*prequest;
2581 	FWUploadReply_t		*preply;
2582 	FWUploadTCSGE_t		*ptcsge;
2583 	int			 sgeoffset;
2584 	u32			 flagsLength;
2585 	int			 ii, sz, reply_sz;
2586 	int			 cmdStatus;
2587 
2588 	/* If the image size is 0, we are done.
2589 	 */
2590 	if ((sz = ioc->facts.FWImageSize) == 0)
2591 		return 0;
2592 
2593 	mpt_alloc_fw_memory(ioc, sz);
2594 
2595 	dinitprintk((KERN_WARNING MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2596 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2597 
2598 	if (ioc->cached_fw == NULL) {
2599 		/* Major Failure.
2600 		 */
2601 		return -ENOMEM;
2602 	}
2603 
2604 	prequest = (FWUpload_t *)&request;
2605 	preply = (FWUploadReply_t *)&reply;
2606 
2607 	/*  Destination...  */
2608 	memset(prequest, 0, ioc->req_sz);
2609 
2610 	reply_sz = sizeof(reply);
2611 	memset(preply, 0, reply_sz);
2612 
2613 	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2614 	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2615 
2616 	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2617 	ptcsge->DetailsLength = 12;
2618 	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2619 	ptcsge->ImageSize = cpu_to_le32(sz);
2620 
2621 	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2622 
2623 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2624 	mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2625 
2626 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2627 	dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2628 			prequest, sgeoffset));
2629 	DBG_DUMP_FW_REQUEST_FRAME(prequest)
2630 
2631 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2632 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2633 
2634 	dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2635 
2636 	cmdStatus = -EFAULT;
2637 	if (ii == 0) {
2638 		/* Handshake transfer was complete and successful.
2639 		 * Check the Reply Frame.
2640 		 */
2641 		int status, transfer_sz;
2642 		status = le16_to_cpu(preply->IOCStatus);
2643 		if (status == MPI_IOCSTATUS_SUCCESS) {
2644 			transfer_sz = le32_to_cpu(preply->ActualImageSize);
2645 			if (transfer_sz == sz)
2646 				cmdStatus = 0;
2647 		}
2648 	}
2649 	dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2650 			ioc->name, cmdStatus));
2651 
2652 
2653 	if (cmdStatus) {
2654 
2655 		ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2656 			ioc->name));
2657 		mpt_free_fw_memory(ioc);
2658 	}
2659 
2660 	return cmdStatus;
2661 }
2662 
2663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2664 /*
2665  *	mpt_downloadboot - DownloadBoot code
2666  *	@ioc: Pointer to MPT_ADAPTER structure
2667  *	@flag: Specify which part of IOC memory is to be uploaded.
2668  *	@sleepFlag: Specifies whether the process can sleep
2669  *
2670  *	FwDownloadBoot requires Programmed IO access.
2671  *
2672  *	Returns 0 for success
2673  *		-1 FW Image size is 0
2674  *		-2 No valid cached_fw Pointer
2675  *		<0 for fw upload failure.
2676  */
2677 static int
2678 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2679 {
2680 	MpiFwHeader_t		*pFwHeader;
2681 	MpiExtImageHeader_t	*pExtImage;
2682 	u32			 fwSize;
2683 	u32			 diag0val;
2684 	int			 count;
2685 	u32			*ptrFw;
2686 	u32			 diagRwData;
2687 	u32			 nextImage;
2688 	u32			 load_addr;
2689 	u32 			 ioc_state=0;
2690 
2691 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2692 				ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2693 
2694 	if ( ioc->facts.FWImageSize == 0 )
2695 		return -1;
2696 
2697 	if (ioc->cached_fw == NULL)
2698 		return -2;
2699 
2700 	/* prevent a second downloadboot and memory free with alt_ioc */
2701 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2702 		ioc->alt_ioc->cached_fw = NULL;
2703 
2704 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2705 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2706 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2707 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2708 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2709 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2710 
2711 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2712 
2713 	/* wait 1 msec */
2714 	if (sleepFlag == CAN_SLEEP) {
2715 		msleep_interruptible(1);
2716 	} else {
2717 		mdelay (1);
2718 	}
2719 
2720 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2721 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2722 
2723 	for (count = 0; count < 30; count ++) {
2724 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2725 		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2726 			ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2727 				ioc->name, count));
2728 			break;
2729 		}
2730 		/* wait 1 sec */
2731 		if (sleepFlag == CAN_SLEEP) {
2732 			msleep_interruptible (1000);
2733 		} else {
2734 			mdelay (1000);
2735 		}
2736 	}
2737 
2738 	if ( count == 30 ) {
2739 		ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2740 		ioc->name, diag0val));
2741 		return -3;
2742 	}
2743 
2744 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2745 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2746 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2747 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2748 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2749 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2750 
2751 	/* Set the DiagRwEn and Disable ARM bits */
2752 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2753 
2754 	pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2755 	fwSize = (pFwHeader->ImageSize + 3)/4;
2756 	ptrFw = (u32 *) pFwHeader;
2757 
2758 	/* Write the LoadStartAddress to the DiagRw Address Register
2759 	 * using Programmed IO
2760 	 */
2761 	if (ioc->errata_flag_1064)
2762 		pci_enable_io_access(ioc->pcidev);
2763 
2764 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2765 	ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2766 		ioc->name, pFwHeader->LoadStartAddress));
2767 
2768 	ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2769 				ioc->name, fwSize*4, ptrFw));
2770 	while (fwSize--) {
2771 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2772 	}
2773 
2774 	nextImage = pFwHeader->NextImageHeaderOffset;
2775 	while (nextImage) {
2776 		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2777 
2778 		load_addr = pExtImage->LoadStartAddress;
2779 
2780 		fwSize = (pExtImage->ImageSize + 3) >> 2;
2781 		ptrFw = (u32 *)pExtImage;
2782 
2783 		ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2784 						ioc->name, fwSize*4, ptrFw, load_addr));
2785 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2786 
2787 		while (fwSize--) {
2788 			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2789 		}
2790 		nextImage = pExtImage->NextImageHeaderOffset;
2791 	}
2792 
2793 	/* Write the IopResetVectorRegAddr */
2794 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
2795 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2796 
2797 	/* Write the IopResetVectorValue */
2798 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2799 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2800 
2801 	/* Clear the internal flash bad bit - autoincrementing register,
2802 	 * so must do two writes.
2803 	 */
2804 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2805 	diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2806 	diagRwData |= 0x4000000;
2807 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2808 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2809 
2810 	if (ioc->errata_flag_1064)
2811 		pci_disable_io_access(ioc->pcidev);
2812 
2813 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2814 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2815 		ioc->name, diag0val));
2816 	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2817 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2818 		ioc->name, diag0val));
2819 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2820 
2821 	/* Write 0xFF to reset the sequencer */
2822 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2823 
2824 	for (count=0; count<HZ*20; count++) {
2825 		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2826 			ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2827 					ioc->name, count, ioc_state));
2828 			if ((SendIocInit(ioc, sleepFlag)) != 0) {
2829 				ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2830 					ioc->name));
2831 				return -EFAULT;
2832 			}
2833 			ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2834 					ioc->name));
2835 			return 0;
2836 		}
2837 		if (sleepFlag == CAN_SLEEP) {
2838 			msleep_interruptible (10);
2839 		} else {
2840 			mdelay (10);
2841 		}
2842 	}
2843 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2844 		ioc->name, ioc_state));
2845 	return -EFAULT;
2846 }
2847 
2848 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2849 /*
2850  *	KickStart - Perform hard reset of MPT adapter.
2851  *	@ioc: Pointer to MPT_ADAPTER structure
2852  *	@force: Force hard reset
2853  *	@sleepFlag: Specifies whether the process can sleep
2854  *
2855  *	This routine places MPT adapter in diagnostic mode via the
2856  *	WriteSequence register, and then performs a hard reset of adapter
2857  *	via the Diagnostic register.
2858  *
2859  *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
2860  *			or NO_SLEEP (interrupt thread, use mdelay)
2861  *		  force - 1 if doorbell active, board fault state
2862  *				board operational, IOC_RECOVERY or
2863  *				IOC_BRINGUP and there is an alt_ioc.
2864  *			  0 else
2865  *
2866  *	Returns:
2867  *		 1 - hard reset, READY
2868  *		 0 - no reset due to History bit, READY
2869  *		-1 - no reset due to History bit but not READY
2870  *		     OR reset but failed to come READY
2871  *		-2 - no reset, could not enter DIAG mode
2872  *		-3 - reset but bad FW bit
2873  */
2874 static int
2875 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2876 {
2877 	int hard_reset_done = 0;
2878 	u32 ioc_state=0;
2879 	int cnt,cntdn;
2880 
2881 	dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2882 	if (ioc->bus_type == SCSI) {
2883 		/* Always issue a Msg Unit Reset first. This will clear some
2884 		 * SCSI bus hang conditions.
2885 		 */
2886 		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2887 
2888 		if (sleepFlag == CAN_SLEEP) {
2889 			msleep_interruptible (1000);
2890 		} else {
2891 			mdelay (1000);
2892 		}
2893 	}
2894 
2895 	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2896 	if (hard_reset_done < 0)
2897 		return hard_reset_done;
2898 
2899 	dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2900 			ioc->name));
2901 
2902 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;	/* 2 seconds */
2903 	for (cnt=0; cnt<cntdn; cnt++) {
2904 		ioc_state = mpt_GetIocState(ioc, 1);
2905 		if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2906 			dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2907  					ioc->name, cnt));
2908 			return hard_reset_done;
2909 		}
2910 		if (sleepFlag == CAN_SLEEP) {
2911 			msleep_interruptible (10);
2912 		} else {
2913 			mdelay (10);
2914 		}
2915 	}
2916 
2917 	printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2918 			ioc->name, ioc_state);
2919 	return -1;
2920 }
2921 
2922 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2923 /*
2924  *	mpt_diag_reset - Perform hard reset of the adapter.
2925  *	@ioc: Pointer to MPT_ADAPTER structure
2926  *	@ignore: Set if to honor and clear to ignore
2927  *		the reset history bit
2928  *	@sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2929  *		else set to NO_SLEEP (use mdelay instead)
2930  *
2931  *	This routine places the adapter in diagnostic mode via the
2932  *	WriteSequence register and then performs a hard reset of adapter
2933  *	via the Diagnostic register. Adapter should be in ready state
2934  *	upon successful completion.
2935  *
2936  *	Returns:  1  hard reset successful
2937  *		  0  no reset performed because reset history bit set
2938  *		 -2  enabling diagnostic mode failed
2939  *		 -3  diagnostic reset failed
2940  */
2941 static int
2942 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2943 {
2944 	u32 diag0val;
2945 	u32 doorbell;
2946 	int hard_reset_done = 0;
2947 	int count = 0;
2948 #ifdef MPT_DEBUG
2949 	u32 diag1val = 0;
2950 #endif
2951 
2952 	/* Clear any existing interrupts */
2953 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2954 
2955 	/* Use "Diagnostic reset" method! (only thing available!) */
2956 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2957 
2958 #ifdef MPT_DEBUG
2959 	if (ioc->alt_ioc)
2960 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2961 	dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2962 			ioc->name, diag0val, diag1val));
2963 #endif
2964 
2965 	/* Do the reset if we are told to ignore the reset history
2966 	 * or if the reset history is 0
2967 	 */
2968 	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2969 		while ((diag0val & MPI_DIAG_DRWE) == 0) {
2970 			/* Write magic sequence to WriteSequence register
2971 			 * Loop until in diagnostic mode
2972 			 */
2973 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2974 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2975 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2976 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2977 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2978 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2979 
2980 			/* wait 100 msec */
2981 			if (sleepFlag == CAN_SLEEP) {
2982 				msleep_interruptible (100);
2983 			} else {
2984 				mdelay (100);
2985 			}
2986 
2987 			count++;
2988 			if (count > 20) {
2989 				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2990 						ioc->name, diag0val);
2991 				return -2;
2992 
2993 			}
2994 
2995 			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2996 
2997 			dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2998 					ioc->name, diag0val));
2999 		}
3000 
3001 #ifdef MPT_DEBUG
3002 		if (ioc->alt_ioc)
3003 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3004 		dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3005 				ioc->name, diag0val, diag1val));
3006 #endif
3007 		/*
3008 		 * Disable the ARM (Bug fix)
3009 		 *
3010 		 */
3011 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3012 		mdelay (1);
3013 
3014 		/*
3015 		 * Now hit the reset bit in the Diagnostic register
3016 		 * (THE BIG HAMMER!) (Clears DRWE bit).
3017 		 */
3018 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3019 		hard_reset_done = 1;
3020 		dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3021 				ioc->name));
3022 
3023 		/*
3024 		 * Call each currently registered protocol IOC reset handler
3025 		 * with pre-reset indication.
3026 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3027 		 * MptResetHandlers[] registered yet.
3028 		 */
3029 		{
3030 			int	 ii;
3031 			int	 r = 0;
3032 
3033 			for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3034 				if (MptResetHandlers[ii]) {
3035 					dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3036 							ioc->name, ii));
3037 					r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3038 					if (ioc->alt_ioc) {
3039 						dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3040 								ioc->name, ioc->alt_ioc->name, ii));
3041 						r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3042 					}
3043 				}
3044 			}
3045 			/* FIXME?  Examine results here? */
3046 		}
3047 
3048 		if (ioc->cached_fw) {
3049 			/* If the DownloadBoot operation fails, the
3050 			 * IOC will be left unusable. This is a fatal error
3051 			 * case.  _diag_reset will return < 0
3052 			 */
3053 			for (count = 0; count < 30; count ++) {
3054 				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3055 				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3056 					break;
3057 				}
3058 
3059 				/* wait 1 sec */
3060 				if (sleepFlag == CAN_SLEEP) {
3061 					ssleep(1);
3062 				} else {
3063 					mdelay (1000);
3064 				}
3065 			}
3066 			if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3067 				printk(KERN_WARNING MYNAM
3068 					": firmware downloadboot failure (%d)!\n", count);
3069 			}
3070 
3071 		} else {
3072 			/* Wait for FW to reload and for board
3073 			 * to go to the READY state.
3074 			 * Maximum wait is 60 seconds.
3075 			 * If fail, no error will check again
3076 			 * with calling program.
3077 			 */
3078 			for (count = 0; count < 60; count ++) {
3079 				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3080 				doorbell &= MPI_IOC_STATE_MASK;
3081 
3082 				if (doorbell == MPI_IOC_STATE_READY) {
3083 					break;
3084 				}
3085 
3086 				/* wait 1 sec */
3087 				if (sleepFlag == CAN_SLEEP) {
3088 					msleep_interruptible (1000);
3089 				} else {
3090 					mdelay (1000);
3091 				}
3092 			}
3093 		}
3094 	}
3095 
3096 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3097 #ifdef MPT_DEBUG
3098 	if (ioc->alt_ioc)
3099 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3100 	dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3101 		ioc->name, diag0val, diag1val));
3102 #endif
3103 
3104 	/* Clear RESET_HISTORY bit!  Place board in the
3105 	 * diagnostic mode to update the diag register.
3106 	 */
3107 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3108 	count = 0;
3109 	while ((diag0val & MPI_DIAG_DRWE) == 0) {
3110 		/* Write magic sequence to WriteSequence register
3111 		 * Loop until in diagnostic mode
3112 		 */
3113 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3114 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3115 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3116 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3117 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3118 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3119 
3120 		/* wait 100 msec */
3121 		if (sleepFlag == CAN_SLEEP) {
3122 			msleep_interruptible (100);
3123 		} else {
3124 			mdelay (100);
3125 		}
3126 
3127 		count++;
3128 		if (count > 20) {
3129 			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3130 					ioc->name, diag0val);
3131 			break;
3132 		}
3133 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3134 	}
3135 	diag0val &= ~MPI_DIAG_RESET_HISTORY;
3136 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3137 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3138 	if (diag0val & MPI_DIAG_RESET_HISTORY) {
3139 		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3140 				ioc->name);
3141 	}
3142 
3143 	/* Disable Diagnostic Mode
3144 	 */
3145 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3146 
3147 	/* Check FW reload status flags.
3148 	 */
3149 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3150 	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3151 		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3152 				ioc->name, diag0val);
3153 		return -3;
3154 	}
3155 
3156 #ifdef MPT_DEBUG
3157 	if (ioc->alt_ioc)
3158 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3159 	dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3160 			ioc->name, diag0val, diag1val));
3161 #endif
3162 
3163 	/*
3164 	 * Reset flag that says we've enabled event notification
3165 	 */
3166 	ioc->facts.EventState = 0;
3167 
3168 	if (ioc->alt_ioc)
3169 		ioc->alt_ioc->facts.EventState = 0;
3170 
3171 	return hard_reset_done;
3172 }
3173 
3174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3175 /*
3176  *	SendIocReset - Send IOCReset request to MPT adapter.
3177  *	@ioc: Pointer to MPT_ADAPTER structure
3178  *	@reset_type: reset type, expected values are
3179  *	%MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3180  *
3181  *	Send IOCReset request to the MPT adapter.
3182  *
3183  *	Returns 0 for success, non-zero for failure.
3184  */
3185 static int
3186 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3187 {
3188 	int r;
3189 	u32 state;
3190 	int cntdn, count;
3191 
3192 	drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3193 			ioc->name, reset_type));
3194 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3195 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3196 		return r;
3197 
3198 	/* FW ACK'd request, wait for READY state
3199 	 */
3200 	count = 0;
3201 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
3202 
3203 	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3204 		cntdn--;
3205 		count++;
3206 		if (!cntdn) {
3207 			if (sleepFlag != CAN_SLEEP)
3208 				count *= 10;
3209 
3210 			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3211 					ioc->name, (int)((count+5)/HZ));
3212 			return -ETIME;
3213 		}
3214 
3215 		if (sleepFlag == CAN_SLEEP) {
3216 			msleep_interruptible(1);
3217 		} else {
3218 			mdelay (1);	/* 1 msec delay */
3219 		}
3220 	}
3221 
3222 	/* TODO!
3223 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
3224 	 *  request if needed.
3225 	 */
3226 	if (ioc->facts.Function)
3227 		ioc->facts.EventState = 0;
3228 
3229 	return 0;
3230 }
3231 
3232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3233 /*
3234  *	initChainBuffers - Allocate memory for and initialize
3235  *	chain buffers, chain buffer control arrays and spinlock.
3236  *	@hd: Pointer to MPT_SCSI_HOST structure
3237  *	@init: If set, initialize the spin lock.
3238  */
3239 static int
3240 initChainBuffers(MPT_ADAPTER *ioc)
3241 {
3242 	u8		*mem;
3243 	int		sz, ii, num_chain;
3244 	int 		scale, num_sge, numSGE;
3245 
3246 	/* ReqToChain size must equal the req_depth
3247 	 * index = req_idx
3248 	 */
3249 	if (ioc->ReqToChain == NULL) {
3250 		sz = ioc->req_depth * sizeof(int);
3251 		mem = kmalloc(sz, GFP_ATOMIC);
3252 		if (mem == NULL)
3253 			return -1;
3254 
3255 		ioc->ReqToChain = (int *) mem;
3256 		dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc  @ %p, sz=%d bytes\n",
3257 			 	ioc->name, mem, sz));
3258 		mem = kmalloc(sz, GFP_ATOMIC);
3259 		if (mem == NULL)
3260 			return -1;
3261 
3262 		ioc->RequestNB = (int *) mem;
3263 		dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc  @ %p, sz=%d bytes\n",
3264 			 	ioc->name, mem, sz));
3265 	}
3266 	for (ii = 0; ii < ioc->req_depth; ii++) {
3267 		ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3268 	}
3269 
3270 	/* ChainToChain size must equal the total number
3271 	 * of chain buffers to be allocated.
3272 	 * index = chain_idx
3273 	 *
3274 	 * Calculate the number of chain buffers needed(plus 1) per I/O
3275 	 * then multiply the the maximum number of simultaneous cmds
3276 	 *
3277 	 * num_sge = num sge in request frame + last chain buffer
3278 	 * scale = num sge per chain buffer if no chain element
3279 	 */
3280 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3281 	if (sizeof(dma_addr_t) == sizeof(u64))
3282 		num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3283 	else
3284 		num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3285 
3286 	if (sizeof(dma_addr_t) == sizeof(u64)) {
3287 		numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3288 			(ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3289 	} else {
3290 		numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3291 			(ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3292 	}
3293 	dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3294 		ioc->name, num_sge, numSGE));
3295 
3296 	if ( numSGE > MPT_SCSI_SG_DEPTH	)
3297 		numSGE = MPT_SCSI_SG_DEPTH;
3298 
3299 	num_chain = 1;
3300 	while (numSGE - num_sge > 0) {
3301 		num_chain++;
3302 		num_sge += (scale - 1);
3303 	}
3304 	num_chain++;
3305 
3306 	dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3307 		ioc->name, numSGE, num_sge, num_chain));
3308 
3309 	if (ioc->bus_type == SCSI)
3310 		num_chain *= MPT_SCSI_CAN_QUEUE;
3311 	else
3312 		num_chain *= MPT_FC_CAN_QUEUE;
3313 
3314 	ioc->num_chain = num_chain;
3315 
3316 	sz = num_chain * sizeof(int);
3317 	if (ioc->ChainToChain == NULL) {
3318 		mem = kmalloc(sz, GFP_ATOMIC);
3319 		if (mem == NULL)
3320 			return -1;
3321 
3322 		ioc->ChainToChain = (int *) mem;
3323 		dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3324 			 	ioc->name, mem, sz));
3325 	} else {
3326 		mem = (u8 *) ioc->ChainToChain;
3327 	}
3328 	memset(mem, 0xFF, sz);
3329 	return num_chain;
3330 }
3331 
3332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3333 /*
3334  *	PrimeIocFifos - Initialize IOC request and reply FIFOs.
3335  *	@ioc: Pointer to MPT_ADAPTER structure
3336  *
3337  *	This routine allocates memory for the MPT reply and request frame
3338  *	pools (if necessary), and primes the IOC reply FIFO with
3339  *	reply frames.
3340  *
3341  *	Returns 0 for success, non-zero for failure.
3342  */
3343 static int
3344 PrimeIocFifos(MPT_ADAPTER *ioc)
3345 {
3346 	MPT_FRAME_HDR *mf;
3347 	unsigned long flags;
3348 	dma_addr_t alloc_dma;
3349 	u8 *mem;
3350 	int i, reply_sz, sz, total_size, num_chain;
3351 
3352 	/*  Prime reply FIFO...  */
3353 
3354 	if (ioc->reply_frames == NULL) {
3355 		if ( (num_chain = initChainBuffers(ioc)) < 0)
3356 			return -1;
3357 
3358 		total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3359 		dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3360 			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
3361 		dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3362 			 	ioc->name, reply_sz, reply_sz));
3363 
3364 		sz = (ioc->req_sz * ioc->req_depth);
3365 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3366 			 	ioc->name, ioc->req_sz, ioc->req_depth));
3367 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3368 			 	ioc->name, sz, sz));
3369 		total_size += sz;
3370 
3371 		sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3372 		dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3373 			 	ioc->name, ioc->req_sz, num_chain));
3374 		dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3375 			 	ioc->name, sz, sz, num_chain));
3376 
3377 		total_size += sz;
3378 		mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3379 		if (mem == NULL) {
3380 			printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3381 				ioc->name);
3382 			goto out_fail;
3383 		}
3384 
3385 		dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3386 			 	ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3387 
3388 		memset(mem, 0, total_size);
3389 		ioc->alloc_total += total_size;
3390 		ioc->alloc = mem;
3391 		ioc->alloc_dma = alloc_dma;
3392 		ioc->alloc_sz = total_size;
3393 		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3394 		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3395 
3396 		alloc_dma += reply_sz;
3397 		mem += reply_sz;
3398 
3399 		/*  Request FIFO - WE manage this!  */
3400 
3401 		ioc->req_frames = (MPT_FRAME_HDR *) mem;
3402 		ioc->req_frames_dma = alloc_dma;
3403 
3404 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3405 			 	ioc->name, mem, (void *)(ulong)alloc_dma));
3406 
3407 		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3408 
3409 #if defined(CONFIG_MTRR) && 0
3410 		/*
3411 		 *  Enable Write Combining MTRR for IOC's memory region.
3412 		 *  (at least as much as we can; "size and base must be
3413 		 *  multiples of 4 kiB"
3414 		 */
3415 		ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3416 					 sz,
3417 					 MTRR_TYPE_WRCOMB, 1);
3418 		dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3419 				ioc->name, ioc->req_frames_dma, sz));
3420 #endif
3421 
3422 		for (i = 0; i < ioc->req_depth; i++) {
3423 			alloc_dma += ioc->req_sz;
3424 			mem += ioc->req_sz;
3425 		}
3426 
3427 		ioc->ChainBuffer = mem;
3428 		ioc->ChainBufferDMA = alloc_dma;
3429 
3430 		dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3431 			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3432 
3433 		/* Initialize the free chain Q.
3434 	 	*/
3435 
3436 		INIT_LIST_HEAD(&ioc->FreeChainQ);
3437 
3438 		/* Post the chain buffers to the FreeChainQ.
3439 	 	*/
3440 		mem = (u8 *)ioc->ChainBuffer;
3441 		for (i=0; i < num_chain; i++) {
3442 			mf = (MPT_FRAME_HDR *) mem;
3443 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3444 			mem += ioc->req_sz;
3445 		}
3446 
3447 		/* Initialize Request frames linked list
3448 		 */
3449 		alloc_dma = ioc->req_frames_dma;
3450 		mem = (u8 *) ioc->req_frames;
3451 
3452 		spin_lock_irqsave(&ioc->FreeQlock, flags);
3453 		INIT_LIST_HEAD(&ioc->FreeQ);
3454 		for (i = 0; i < ioc->req_depth; i++) {
3455 			mf = (MPT_FRAME_HDR *) mem;
3456 
3457 			/*  Queue REQUESTs *internally*!  */
3458 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3459 
3460 			mem += ioc->req_sz;
3461 		}
3462 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3463 
3464 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3465 		ioc->sense_buf_pool =
3466 			pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3467 		if (ioc->sense_buf_pool == NULL) {
3468 			printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3469 				ioc->name);
3470 			goto out_fail;
3471 		}
3472 
3473 		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3474 		ioc->alloc_total += sz;
3475 		dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3476  			ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3477 
3478 	}
3479 
3480 	/* Post Reply frames to FIFO
3481 	 */
3482 	alloc_dma = ioc->alloc_dma;
3483 	dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3484 	 	ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3485 
3486 	for (i = 0; i < ioc->reply_depth; i++) {
3487 		/*  Write each address to the IOC!  */
3488 		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3489 		alloc_dma += ioc->reply_sz;
3490 	}
3491 
3492 	return 0;
3493 
3494 out_fail:
3495 	if (ioc->alloc != NULL) {
3496 		sz = ioc->alloc_sz;
3497 		pci_free_consistent(ioc->pcidev,
3498 				sz,
3499 				ioc->alloc, ioc->alloc_dma);
3500 		ioc->reply_frames = NULL;
3501 		ioc->req_frames = NULL;
3502 		ioc->alloc_total -= sz;
3503 	}
3504 	if (ioc->sense_buf_pool != NULL) {
3505 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3506 		pci_free_consistent(ioc->pcidev,
3507 				sz,
3508 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3509 		ioc->sense_buf_pool = NULL;
3510 	}
3511 	return -1;
3512 }
3513 
3514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3515 /**
3516  *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3517  *	from IOC via doorbell handshake method.
3518  *	@ioc: Pointer to MPT_ADAPTER structure
3519  *	@reqBytes: Size of the request in bytes
3520  *	@req: Pointer to MPT request frame
3521  *	@replyBytes: Expected size of the reply in bytes
3522  *	@u16reply: Pointer to area where reply should be written
3523  *	@maxwait: Max wait time for a reply (in seconds)
3524  *	@sleepFlag: Specifies whether the process can sleep
3525  *
3526  *	NOTES: It is the callers responsibility to byte-swap fields in the
3527  *	request which are greater than 1 byte in size.  It is also the
3528  *	callers responsibility to byte-swap response fields which are
3529  *	greater than 1 byte in size.
3530  *
3531  *	Returns 0 for success, non-zero for failure.
3532  */
3533 static int
3534 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3535 				int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3536 {
3537 	MPIDefaultReply_t *mptReply;
3538 	int failcnt = 0;
3539 	int t;
3540 
3541 	/*
3542 	 * Get ready to cache a handshake reply
3543 	 */
3544 	ioc->hs_reply_idx = 0;
3545 	mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3546 	mptReply->MsgLength = 0;
3547 
3548 	/*
3549 	 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3550 	 * then tell IOC that we want to handshake a request of N words.
3551 	 * (WRITE u32val to Doorbell reg).
3552 	 */
3553 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3554 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
3555 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3556 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3557 
3558 	/*
3559 	 * Wait for IOC's doorbell handshake int
3560 	 */
3561 	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3562 		failcnt++;
3563 
3564 	dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3565 			ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3566 
3567 	/* Read doorbell and check for active bit */
3568 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3569 			return -1;
3570 
3571 	/*
3572 	 * Clear doorbell int (WRITE 0 to IntStatus reg),
3573 	 * then wait for IOC to ACKnowledge that it's ready for
3574 	 * our handshake request.
3575 	 */
3576 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3577 	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3578 		failcnt++;
3579 
3580 	if (!failcnt) {
3581 		int	 ii;
3582 		u8	*req_as_bytes = (u8 *) req;
3583 
3584 		/*
3585 		 * Stuff request words via doorbell handshake,
3586 		 * with ACK from IOC for each.
3587 		 */
3588 		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3589 			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
3590 				    (req_as_bytes[(ii*4) + 1] <<  8) |
3591 				    (req_as_bytes[(ii*4) + 2] << 16) |
3592 				    (req_as_bytes[(ii*4) + 3] << 24));
3593 
3594 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3595 			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3596 				failcnt++;
3597 		}
3598 
3599 		dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3600 		DBG_DUMP_REQUEST_FRAME_HDR(req)
3601 
3602 		dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3603 				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3604 
3605 		/*
3606 		 * Wait for completion of doorbell handshake reply from the IOC
3607 		 */
3608 		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3609 			failcnt++;
3610 
3611 		dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3612 				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3613 
3614 		/*
3615 		 * Copy out the cached reply...
3616 		 */
3617 		for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3618 			u16reply[ii] = ioc->hs_reply[ii];
3619 	} else {
3620 		return -99;
3621 	}
3622 
3623 	return -failcnt;
3624 }
3625 
3626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3627 /*
3628  *	WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3629  *	in it's IntStatus register.
3630  *	@ioc: Pointer to MPT_ADAPTER structure
3631  *	@howlong: How long to wait (in seconds)
3632  *	@sleepFlag: Specifies whether the process can sleep
3633  *
3634  *	This routine waits (up to ~2 seconds max) for IOC doorbell
3635  *	handshake ACKnowledge.
3636  *
3637  *	Returns a negative value on failure, else wait loop count.
3638  */
3639 static int
3640 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3641 {
3642 	int cntdn;
3643 	int count = 0;
3644 	u32 intstat=0;
3645 
3646 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3647 
3648 	if (sleepFlag == CAN_SLEEP) {
3649 		while (--cntdn) {
3650 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3651 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3652 				break;
3653 			msleep_interruptible (1);
3654 			count++;
3655 		}
3656 	} else {
3657 		while (--cntdn) {
3658 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3659 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3660 				break;
3661 			mdelay (1);
3662 			count++;
3663 		}
3664 	}
3665 
3666 	if (cntdn) {
3667 		dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3668 				ioc->name, count));
3669 		return count;
3670 	}
3671 
3672 	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3673 			ioc->name, count, intstat);
3674 	return -1;
3675 }
3676 
3677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3678 /*
3679  *	WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3680  *	in it's IntStatus register.
3681  *	@ioc: Pointer to MPT_ADAPTER structure
3682  *	@howlong: How long to wait (in seconds)
3683  *	@sleepFlag: Specifies whether the process can sleep
3684  *
3685  *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3686  *
3687  *	Returns a negative value on failure, else wait loop count.
3688  */
3689 static int
3690 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3691 {
3692 	int cntdn;
3693 	int count = 0;
3694 	u32 intstat=0;
3695 
3696 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3697 	if (sleepFlag == CAN_SLEEP) {
3698 		while (--cntdn) {
3699 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3700 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3701 				break;
3702 			msleep_interruptible(1);
3703 			count++;
3704 		}
3705 	} else {
3706 		while (--cntdn) {
3707 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3708 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3709 				break;
3710 			mdelay(1);
3711 			count++;
3712 		}
3713 	}
3714 
3715 	if (cntdn) {
3716 		dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3717 				ioc->name, count, howlong));
3718 		return count;
3719 	}
3720 
3721 	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3722 			ioc->name, count, intstat);
3723 	return -1;
3724 }
3725 
3726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3727 /*
3728  *	WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3729  *	@ioc: Pointer to MPT_ADAPTER structure
3730  *	@howlong: How long to wait (in seconds)
3731  *	@sleepFlag: Specifies whether the process can sleep
3732  *
3733  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
3734  *	Reply is cached to IOC private area large enough to hold a maximum
3735  *	of 128 bytes of reply data.
3736  *
3737  *	Returns a negative value on failure, else size of reply in WORDS.
3738  */
3739 static int
3740 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3741 {
3742 	int u16cnt = 0;
3743 	int failcnt = 0;
3744 	int t;
3745 	u16 *hs_reply = ioc->hs_reply;
3746 	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3747 	u16 hword;
3748 
3749 	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3750 
3751 	/*
3752 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
3753 	 */
3754 	u16cnt=0;
3755 	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3756 		failcnt++;
3757 	} else {
3758 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3759 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3760 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3761 			failcnt++;
3762 		else {
3763 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3764 			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3765 		}
3766 	}
3767 
3768 	dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3769 			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3770 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3771 
3772 	/*
3773 	 * If no error (and IOC said MsgLength is > 0), piece together
3774 	 * reply 16 bits at a time.
3775 	 */
3776 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3777 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3778 			failcnt++;
3779 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3780 		/* don't overflow our IOC hs_reply[] buffer! */
3781 		if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3782 			hs_reply[u16cnt] = hword;
3783 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3784 	}
3785 
3786 	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3787 		failcnt++;
3788 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3789 
3790 	if (failcnt) {
3791 		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3792 				ioc->name);
3793 		return -failcnt;
3794 	}
3795 #if 0
3796 	else if (u16cnt != (2 * mptReply->MsgLength)) {
3797 		return -101;
3798 	}
3799 	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3800 		return -102;
3801 	}
3802 #endif
3803 
3804 	dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3805 	DBG_DUMP_REPLY_FRAME(mptReply)
3806 
3807 	dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3808 			ioc->name, t, u16cnt/2));
3809 	return u16cnt/2;
3810 }
3811 
3812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3813 /*
3814  *	GetLanConfigPages - Fetch LANConfig pages.
3815  *	@ioc: Pointer to MPT_ADAPTER structure
3816  *
3817  *	Return: 0 for success
3818  *	-ENOMEM if no memory available
3819  *		-EPERM if not allowed due to ISR context
3820  *		-EAGAIN if no msg frames currently available
3821  *		-EFAULT for non-successful reply or no reply (timeout)
3822  */
3823 static int
3824 GetLanConfigPages(MPT_ADAPTER *ioc)
3825 {
3826 	ConfigPageHeader_t	 hdr;
3827 	CONFIGPARMS		 cfg;
3828 	LANPage0_t		*ppage0_alloc;
3829 	dma_addr_t		 page0_dma;
3830 	LANPage1_t		*ppage1_alloc;
3831 	dma_addr_t		 page1_dma;
3832 	int			 rc = 0;
3833 	int			 data_sz;
3834 	int			 copy_sz;
3835 
3836 	/* Get LAN Page 0 header */
3837 	hdr.PageVersion = 0;
3838 	hdr.PageLength = 0;
3839 	hdr.PageNumber = 0;
3840 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3841 	cfg.hdr = &hdr;
3842 	cfg.physAddr = -1;
3843 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3844 	cfg.dir = 0;
3845 	cfg.pageAddr = 0;
3846 	cfg.timeout = 0;
3847 
3848 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3849 		return rc;
3850 
3851 	if (hdr.PageLength > 0) {
3852 		data_sz = hdr.PageLength * 4;
3853 		ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3854 		rc = -ENOMEM;
3855 		if (ppage0_alloc) {
3856 			memset((u8 *)ppage0_alloc, 0, data_sz);
3857 			cfg.physAddr = page0_dma;
3858 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3859 
3860 			if ((rc = mpt_config(ioc, &cfg)) == 0) {
3861 				/* save the data */
3862 				copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3863 				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
3864 
3865 			}
3866 
3867 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3868 
3869 			/* FIXME!
3870 			 *	Normalize endianness of structure data,
3871 			 *	by byte-swapping all > 1 byte fields!
3872 			 */
3873 
3874 		}
3875 
3876 		if (rc)
3877 			return rc;
3878 	}
3879 
3880 	/* Get LAN Page 1 header */
3881 	hdr.PageVersion = 0;
3882 	hdr.PageLength = 0;
3883 	hdr.PageNumber = 1;
3884 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3885 	cfg.hdr = &hdr;
3886 	cfg.physAddr = -1;
3887 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3888 	cfg.dir = 0;
3889 	cfg.pageAddr = 0;
3890 
3891 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3892 		return rc;
3893 
3894 	if (hdr.PageLength == 0)
3895 		return 0;
3896 
3897 	data_sz = hdr.PageLength * 4;
3898 	rc = -ENOMEM;
3899 	ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
3900 	if (ppage1_alloc) {
3901 		memset((u8 *)ppage1_alloc, 0, data_sz);
3902 		cfg.physAddr = page1_dma;
3903 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3904 
3905 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
3906 			/* save the data */
3907 			copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
3908 			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
3909 		}
3910 
3911 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
3912 
3913 		/* FIXME!
3914 		 *	Normalize endianness of structure data,
3915 		 *	by byte-swapping all > 1 byte fields!
3916 		 */
3917 
3918 	}
3919 
3920 	return rc;
3921 }
3922 
3923 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3924 /*
3925  *	GetFcPortPage0 - Fetch FCPort config Page0.
3926  *	@ioc: Pointer to MPT_ADAPTER structure
3927  *	@portnum: IOC Port number
3928  *
3929  *	Return: 0 for success
3930  *	-ENOMEM if no memory available
3931  *		-EPERM if not allowed due to ISR context
3932  *		-EAGAIN if no msg frames currently available
3933  *		-EFAULT for non-successful reply or no reply (timeout)
3934  */
3935 static int
3936 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
3937 {
3938 	ConfigPageHeader_t	 hdr;
3939 	CONFIGPARMS		 cfg;
3940 	FCPortPage0_t		*ppage0_alloc;
3941 	FCPortPage0_t		*pp0dest;
3942 	dma_addr_t		 page0_dma;
3943 	int			 data_sz;
3944 	int			 copy_sz;
3945 	int			 rc;
3946 
3947 	/* Get FCPort Page 0 header */
3948 	hdr.PageVersion = 0;
3949 	hdr.PageLength = 0;
3950 	hdr.PageNumber = 0;
3951 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
3952 	cfg.hdr = &hdr;
3953 	cfg.physAddr = -1;
3954 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3955 	cfg.dir = 0;
3956 	cfg.pageAddr = portnum;
3957 	cfg.timeout = 0;
3958 
3959 	if ((rc = mpt_config(ioc, &cfg)) != 0)
3960 		return rc;
3961 
3962 	if (hdr.PageLength == 0)
3963 		return 0;
3964 
3965 	data_sz = hdr.PageLength * 4;
3966 	rc = -ENOMEM;
3967 	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3968 	if (ppage0_alloc) {
3969 		memset((u8 *)ppage0_alloc, 0, data_sz);
3970 		cfg.physAddr = page0_dma;
3971 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3972 
3973 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
3974 			/* save the data */
3975 			pp0dest = &ioc->fc_port_page0[portnum];
3976 			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
3977 			memcpy(pp0dest, ppage0_alloc, copy_sz);
3978 
3979 			/*
3980 			 *	Normalize endianness of structure data,
3981 			 *	by byte-swapping all > 1 byte fields!
3982 			 */
3983 			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
3984 			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
3985 			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
3986 			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
3987 			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
3988 			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
3989 			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
3990 			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
3991 			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
3992 			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
3993 			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
3994 			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
3995 			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
3996 			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
3997 			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
3998 			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
3999 
4000 		}
4001 
4002 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4003 	}
4004 
4005 	return rc;
4006 }
4007 
4008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4009 /*
4010  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4011  *	@ioc: Pointer to MPT_ADAPTER structure
4012  *
4013  *	Returns: 0 for success
4014  *	-ENOMEM if no memory available
4015  *		-EPERM if not allowed due to ISR context
4016  *		-EAGAIN if no msg frames currently available
4017  *		-EFAULT for non-successful reply or no reply (timeout)
4018  */
4019 static int
4020 GetIoUnitPage2(MPT_ADAPTER *ioc)
4021 {
4022 	ConfigPageHeader_t	 hdr;
4023 	CONFIGPARMS		 cfg;
4024 	IOUnitPage2_t		*ppage_alloc;
4025 	dma_addr_t		 page_dma;
4026 	int			 data_sz;
4027 	int			 rc;
4028 
4029 	/* Get the page header */
4030 	hdr.PageVersion = 0;
4031 	hdr.PageLength = 0;
4032 	hdr.PageNumber = 2;
4033 	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4034 	cfg.hdr = &hdr;
4035 	cfg.physAddr = -1;
4036 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4037 	cfg.dir = 0;
4038 	cfg.pageAddr = 0;
4039 	cfg.timeout = 0;
4040 
4041 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4042 		return rc;
4043 
4044 	if (hdr.PageLength == 0)
4045 		return 0;
4046 
4047 	/* Read the config page */
4048 	data_sz = hdr.PageLength * 4;
4049 	rc = -ENOMEM;
4050 	ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4051 	if (ppage_alloc) {
4052 		memset((u8 *)ppage_alloc, 0, data_sz);
4053 		cfg.physAddr = page_dma;
4054 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4055 
4056 		/* If Good, save data */
4057 		if ((rc = mpt_config(ioc, &cfg)) == 0)
4058 			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4059 
4060 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4061 	}
4062 
4063 	return rc;
4064 }
4065 
4066 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4067 /*	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4068  *	@ioc: Pointer to a Adapter Strucutre
4069  *	@portnum: IOC port number
4070  *
4071  *	Return: -EFAULT if read of config page header fails
4072  *			or if no nvram
4073  *	If read of SCSI Port Page 0 fails,
4074  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4075  *		Adapter settings: async, narrow
4076  *		Return 1
4077  *	If read of SCSI Port Page 2 fails,
4078  *		Adapter settings valid
4079  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4080  *		Return 1
4081  *	Else
4082  *		Both valid
4083  *		Return 0
4084  *	CHECK - what type of locking mechanisms should be used????
4085  */
4086 static int
4087 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4088 {
4089 	u8			*pbuf;
4090 	dma_addr_t		 buf_dma;
4091 	CONFIGPARMS		 cfg;
4092 	ConfigPageHeader_t	 header;
4093 	int			 ii;
4094 	int			 data, rc = 0;
4095 
4096 	/* Allocate memory
4097 	 */
4098 	if (!ioc->spi_data.nvram) {
4099 		int	 sz;
4100 		u8	*mem;
4101 		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4102 		mem = kmalloc(sz, GFP_ATOMIC);
4103 		if (mem == NULL)
4104 			return -EFAULT;
4105 
4106 		ioc->spi_data.nvram = (int *) mem;
4107 
4108 		dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4109 			ioc->name, ioc->spi_data.nvram, sz));
4110 	}
4111 
4112 	/* Invalidate NVRAM information
4113 	 */
4114 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4115 		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4116 	}
4117 
4118 	/* Read SPP0 header, allocate memory, then read page.
4119 	 */
4120 	header.PageVersion = 0;
4121 	header.PageLength = 0;
4122 	header.PageNumber = 0;
4123 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4124 	cfg.hdr = &header;
4125 	cfg.physAddr = -1;
4126 	cfg.pageAddr = portnum;
4127 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4128 	cfg.dir = 0;
4129 	cfg.timeout = 0;	/* use default */
4130 	if (mpt_config(ioc, &cfg) != 0)
4131 		 return -EFAULT;
4132 
4133 	if (header.PageLength > 0) {
4134 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4135 		if (pbuf) {
4136 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4137 			cfg.physAddr = buf_dma;
4138 			if (mpt_config(ioc, &cfg) != 0) {
4139 				ioc->spi_data.maxBusWidth = MPT_NARROW;
4140 				ioc->spi_data.maxSyncOffset = 0;
4141 				ioc->spi_data.minSyncFactor = MPT_ASYNC;
4142 				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4143 				rc = 1;
4144 			} else {
4145 				/* Save the Port Page 0 data
4146 				 */
4147 				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4148 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4149 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4150 
4151 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4152 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4153 					dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4154 						ioc->name, pPP0->Capabilities));
4155 				}
4156 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4157 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4158 				if (data) {
4159 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4160 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4161 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4162 				} else {
4163 					ioc->spi_data.maxSyncOffset = 0;
4164 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
4165 				}
4166 
4167 				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4168 
4169 				/* Update the minSyncFactor based on bus type.
4170 				 */
4171 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4172 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4173 
4174 				if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4175 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
4176 				}
4177 			}
4178 			if (pbuf) {
4179 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4180 			}
4181 		}
4182 	}
4183 
4184 	/* SCSI Port Page 2 - Read the header then the page.
4185 	 */
4186 	header.PageVersion = 0;
4187 	header.PageLength = 0;
4188 	header.PageNumber = 2;
4189 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4190 	cfg.hdr = &header;
4191 	cfg.physAddr = -1;
4192 	cfg.pageAddr = portnum;
4193 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4194 	cfg.dir = 0;
4195 	if (mpt_config(ioc, &cfg) != 0)
4196 		return -EFAULT;
4197 
4198 	if (header.PageLength > 0) {
4199 		/* Allocate memory and read SCSI Port Page 2
4200 		 */
4201 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4202 		if (pbuf) {
4203 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4204 			cfg.physAddr = buf_dma;
4205 			if (mpt_config(ioc, &cfg) != 0) {
4206 				/* Nvram data is left with INVALID mark
4207 				 */
4208 				rc = 1;
4209 			} else {
4210 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4211 				MpiDeviceInfo_t	*pdevice = NULL;
4212 
4213 				/* Save the Port Page 2 data
4214 				 * (reformat into a 32bit quantity)
4215 				 */
4216 				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4217 				ioc->spi_data.PortFlags = data;
4218 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4219 					pdevice = &pPP2->DeviceSettings[ii];
4220 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4221 						(pdevice->SyncFactor << 8) | pdevice->Timeout;
4222 					ioc->spi_data.nvram[ii] = data;
4223 				}
4224 			}
4225 
4226 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4227 		}
4228 	}
4229 
4230 	/* Update Adapter limits with those from NVRAM
4231 	 * Comment: Don't need to do this. Target performance
4232 	 * parameters will never exceed the adapters limits.
4233 	 */
4234 
4235 	return rc;
4236 }
4237 
4238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4239 /*	mpt_readScsiDevicePageHeaders - save version and length of SDP1
4240  *	@ioc: Pointer to a Adapter Strucutre
4241  *	@portnum: IOC port number
4242  *
4243  *	Return: -EFAULT if read of config page header fails
4244  *		or 0 if success.
4245  */
4246 static int
4247 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4248 {
4249 	CONFIGPARMS		 cfg;
4250 	ConfigPageHeader_t	 header;
4251 
4252 	/* Read the SCSI Device Page 1 header
4253 	 */
4254 	header.PageVersion = 0;
4255 	header.PageLength = 0;
4256 	header.PageNumber = 1;
4257 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4258 	cfg.hdr = &header;
4259 	cfg.physAddr = -1;
4260 	cfg.pageAddr = portnum;
4261 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4262 	cfg.dir = 0;
4263 	cfg.timeout = 0;
4264 	if (mpt_config(ioc, &cfg) != 0)
4265 		 return -EFAULT;
4266 
4267 	ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4268 	ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4269 
4270 	header.PageVersion = 0;
4271 	header.PageLength = 0;
4272 	header.PageNumber = 0;
4273 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4274 	if (mpt_config(ioc, &cfg) != 0)
4275 		 return -EFAULT;
4276 
4277 	ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4278 	ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4279 
4280 	dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4281 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4282 
4283 	dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4284 			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4285 	return 0;
4286 }
4287 
4288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4289 /**
4290  *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4291  *	@ioc: Pointer to a Adapter Strucutre
4292  *	@portnum: IOC port number
4293  *
4294  *	Return:
4295  *	0 on success
4296  *	-EFAULT if read of config page header fails or data pointer not NULL
4297  *	-ENOMEM if pci_alloc failed
4298  */
4299 int
4300 mpt_findImVolumes(MPT_ADAPTER *ioc)
4301 {
4302 	IOCPage2_t		*pIoc2;
4303 	u8			*mem;
4304 	ConfigPageIoc2RaidVol_t	*pIocRv;
4305 	dma_addr_t		 ioc2_dma;
4306 	CONFIGPARMS		 cfg;
4307 	ConfigPageHeader_t	 header;
4308 	int			 jj;
4309 	int			 rc = 0;
4310 	int			 iocpage2sz;
4311 	u8			 nVols, nPhys;
4312 	u8			 vid, vbus, vioc;
4313 
4314 	/* Read IOCP2 header then the page.
4315 	 */
4316 	header.PageVersion = 0;
4317 	header.PageLength = 0;
4318 	header.PageNumber = 2;
4319 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4320 	cfg.hdr = &header;
4321 	cfg.physAddr = -1;
4322 	cfg.pageAddr = 0;
4323 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4324 	cfg.dir = 0;
4325 	cfg.timeout = 0;
4326 	if (mpt_config(ioc, &cfg) != 0)
4327 		 return -EFAULT;
4328 
4329 	if (header.PageLength == 0)
4330 		return -EFAULT;
4331 
4332 	iocpage2sz = header.PageLength * 4;
4333 	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4334 	if (!pIoc2)
4335 		return -ENOMEM;
4336 
4337 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4338 	cfg.physAddr = ioc2_dma;
4339 	if (mpt_config(ioc, &cfg) != 0)
4340 		goto done_and_free;
4341 
4342 	if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4343 		mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4344 		if (mem) {
4345 			ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4346 		} else {
4347 			goto done_and_free;
4348 		}
4349 	}
4350 	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4351 
4352 	/* Identify RAID Volume Id's */
4353 	nVols = pIoc2->NumActiveVolumes;
4354 	if ( nVols == 0) {
4355 		/* No RAID Volume.
4356 		 */
4357 		goto done_and_free;
4358 	} else {
4359 		/* At least 1 RAID Volume
4360 		 */
4361 		pIocRv = pIoc2->RaidVolume;
4362 		ioc->spi_data.isRaid = 0;
4363 		for (jj = 0; jj < nVols; jj++, pIocRv++) {
4364 			vid = pIocRv->VolumeID;
4365 			vbus = pIocRv->VolumeBus;
4366 			vioc = pIocRv->VolumeIOC;
4367 
4368 			/* find the match
4369 			 */
4370 			if (vbus == 0) {
4371 				ioc->spi_data.isRaid |= (1 << vid);
4372 			} else {
4373 				/* Error! Always bus 0
4374 				 */
4375 			}
4376 		}
4377 	}
4378 
4379 	/* Identify Hidden Physical Disk Id's */
4380 	nPhys = pIoc2->NumActivePhysDisks;
4381 	if (nPhys == 0) {
4382 		/* No physical disks.
4383 		 */
4384 	} else {
4385 		mpt_read_ioc_pg_3(ioc);
4386 	}
4387 
4388 done_and_free:
4389 	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4390 
4391 	return rc;
4392 }
4393 
4394 int
4395 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4396 {
4397 	IOCPage3_t		*pIoc3;
4398 	u8			*mem;
4399 	CONFIGPARMS		 cfg;
4400 	ConfigPageHeader_t	 header;
4401 	dma_addr_t		 ioc3_dma;
4402 	int			 iocpage3sz = 0;
4403 
4404 	/* Free the old page
4405 	 */
4406 	if (ioc->spi_data.pIocPg3) {
4407 		kfree(ioc->spi_data.pIocPg3);
4408 		ioc->spi_data.pIocPg3 = NULL;
4409 	}
4410 
4411 	/* There is at least one physical disk.
4412 	 * Read and save IOC Page 3
4413 	 */
4414 	header.PageVersion = 0;
4415 	header.PageLength = 0;
4416 	header.PageNumber = 3;
4417 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4418 	cfg.hdr = &header;
4419 	cfg.physAddr = -1;
4420 	cfg.pageAddr = 0;
4421 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4422 	cfg.dir = 0;
4423 	cfg.timeout = 0;
4424 	if (mpt_config(ioc, &cfg) != 0)
4425 		return 0;
4426 
4427 	if (header.PageLength == 0)
4428 		return 0;
4429 
4430 	/* Read Header good, alloc memory
4431 	 */
4432 	iocpage3sz = header.PageLength * 4;
4433 	pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4434 	if (!pIoc3)
4435 		return 0;
4436 
4437 	/* Read the Page and save the data
4438 	 * into malloc'd memory.
4439 	 */
4440 	cfg.physAddr = ioc3_dma;
4441 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4442 	if (mpt_config(ioc, &cfg) == 0) {
4443 		mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4444 		if (mem) {
4445 			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4446 			ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4447 		}
4448 	}
4449 
4450 	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4451 
4452 	return 0;
4453 }
4454 
4455 static void
4456 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4457 {
4458 	IOCPage4_t		*pIoc4;
4459 	CONFIGPARMS		 cfg;
4460 	ConfigPageHeader_t	 header;
4461 	dma_addr_t		 ioc4_dma;
4462 	int			 iocpage4sz;
4463 
4464 	/* Read and save IOC Page 4
4465 	 */
4466 	header.PageVersion = 0;
4467 	header.PageLength = 0;
4468 	header.PageNumber = 4;
4469 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4470 	cfg.hdr = &header;
4471 	cfg.physAddr = -1;
4472 	cfg.pageAddr = 0;
4473 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4474 	cfg.dir = 0;
4475 	cfg.timeout = 0;
4476 	if (mpt_config(ioc, &cfg) != 0)
4477 		return;
4478 
4479 	if (header.PageLength == 0)
4480 		return;
4481 
4482 	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4483 		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4484 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4485 		if (!pIoc4)
4486 			return;
4487 	} else {
4488 		ioc4_dma = ioc->spi_data.IocPg4_dma;
4489 		iocpage4sz = ioc->spi_data.IocPg4Sz;
4490 	}
4491 
4492 	/* Read the Page into dma memory.
4493 	 */
4494 	cfg.physAddr = ioc4_dma;
4495 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4496 	if (mpt_config(ioc, &cfg) == 0) {
4497 		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4498 		ioc->spi_data.IocPg4_dma = ioc4_dma;
4499 		ioc->spi_data.IocPg4Sz = iocpage4sz;
4500 	} else {
4501 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4502 		ioc->spi_data.pIocPg4 = NULL;
4503 	}
4504 }
4505 
4506 static void
4507 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4508 {
4509 	IOCPage1_t		*pIoc1;
4510 	CONFIGPARMS		 cfg;
4511 	ConfigPageHeader_t	 header;
4512 	dma_addr_t		 ioc1_dma;
4513 	int			 iocpage1sz = 0;
4514 	u32			 tmp;
4515 
4516 	/* Check the Coalescing Timeout in IOC Page 1
4517 	 */
4518 	header.PageVersion = 0;
4519 	header.PageLength = 0;
4520 	header.PageNumber = 1;
4521 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4522 	cfg.hdr = &header;
4523 	cfg.physAddr = -1;
4524 	cfg.pageAddr = 0;
4525 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4526 	cfg.dir = 0;
4527 	cfg.timeout = 0;
4528 	if (mpt_config(ioc, &cfg) != 0)
4529 		return;
4530 
4531 	if (header.PageLength == 0)
4532 		return;
4533 
4534 	/* Read Header good, alloc memory
4535 	 */
4536 	iocpage1sz = header.PageLength * 4;
4537 	pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4538 	if (!pIoc1)
4539 		return;
4540 
4541 	/* Read the Page and check coalescing timeout
4542 	 */
4543 	cfg.physAddr = ioc1_dma;
4544 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4545 	if (mpt_config(ioc, &cfg) == 0) {
4546 
4547 		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4548 		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4549 			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4550 
4551 			dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4552 					ioc->name, tmp));
4553 
4554 			if (tmp > MPT_COALESCING_TIMEOUT) {
4555 				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4556 
4557 				/* Write NVRAM and current
4558 				 */
4559 				cfg.dir = 1;
4560 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4561 				if (mpt_config(ioc, &cfg) == 0) {
4562 					dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4563 							ioc->name, MPT_COALESCING_TIMEOUT));
4564 
4565 					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4566 					if (mpt_config(ioc, &cfg) == 0) {
4567 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4568 								ioc->name, MPT_COALESCING_TIMEOUT));
4569 					} else {
4570 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4571 									ioc->name));
4572 					}
4573 
4574 				} else {
4575 					dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4576 								ioc->name));
4577 				}
4578 			}
4579 
4580 		} else {
4581 			dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4582 		}
4583 	}
4584 
4585 	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4586 
4587 	return;
4588 }
4589 
4590 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4591 /*
4592  *	SendEventNotification - Send EventNotification (on or off) request
4593  *	to MPT adapter.
4594  *	@ioc: Pointer to MPT_ADAPTER structure
4595  *	@EvSwitch: Event switch flags
4596  */
4597 static int
4598 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4599 {
4600 	EventNotification_t	*evnp;
4601 
4602 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4603 	if (evnp == NULL) {
4604 		dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4605 				ioc->name));
4606 		return 0;
4607 	}
4608 	memset(evnp, 0, sizeof(*evnp));
4609 
4610 	dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4611 
4612 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4613 	evnp->ChainOffset = 0;
4614 	evnp->MsgFlags = 0;
4615 	evnp->Switch = EvSwitch;
4616 
4617 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4618 
4619 	return 0;
4620 }
4621 
4622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4623 /**
4624  *	SendEventAck - Send EventAck request to MPT adapter.
4625  *	@ioc: Pointer to MPT_ADAPTER structure
4626  *	@evnp: Pointer to original EventNotification request
4627  */
4628 static int
4629 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4630 {
4631 	EventAck_t	*pAck;
4632 
4633 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4634 		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4635 				ioc->name);
4636 		return -1;
4637 	}
4638 	memset(pAck, 0, sizeof(*pAck));
4639 
4640 	dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4641 
4642 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
4643 	pAck->ChainOffset  = 0;
4644 	pAck->MsgFlags     = 0;
4645 	pAck->Event        = evnp->Event;
4646 	pAck->EventContext = evnp->EventContext;
4647 
4648 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4649 
4650 	return 0;
4651 }
4652 
4653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4654 /**
4655  *	mpt_config - Generic function to issue config message
4656  *	@ioc - Pointer to an adapter structure
4657  *	@cfg - Pointer to a configuration structure. Struct contains
4658  *		action, page address, direction, physical address
4659  *		and pointer to a configuration page header
4660  *		Page header is updated.
4661  *
4662  *	Returns 0 for success
4663  *	-EPERM if not allowed due to ISR context
4664  *	-EAGAIN if no msg frames currently available
4665  *	-EFAULT for non-successful reply or no reply (timeout)
4666  */
4667 int
4668 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4669 {
4670 	Config_t	*pReq;
4671 	MPT_FRAME_HDR	*mf;
4672 	unsigned long	 flags;
4673 	int		 ii, rc;
4674 	u32		 flagsLength;
4675 	int		 in_isr;
4676 
4677 	/*	Prevent calling wait_event() (below), if caller happens
4678 	 *	to be in ISR context, because that is fatal!
4679 	 */
4680 	in_isr = in_interrupt();
4681 	if (in_isr) {
4682 		dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4683 				ioc->name));
4684 		return -EPERM;
4685 	}
4686 
4687 	/* Get and Populate a free Frame
4688 	 */
4689 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4690 		dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4691 				ioc->name));
4692 		return -EAGAIN;
4693 	}
4694 	pReq = (Config_t *)mf;
4695 	pReq->Action = pCfg->action;
4696 	pReq->Reserved = 0;
4697 	pReq->ChainOffset = 0;
4698 	pReq->Function = MPI_FUNCTION_CONFIG;
4699 	pReq->ExtPageLength = 0;
4700 	pReq->ExtPageType = 0;
4701 	pReq->MsgFlags = 0;
4702 	for (ii=0; ii < 8; ii++)
4703 		pReq->Reserved2[ii] = 0;
4704 
4705 	pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4706 	pReq->Header.PageLength = pCfg->hdr->PageLength;
4707 	pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4708 	pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4709 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4710 
4711 	/* Add a SGE to the config request.
4712 	 */
4713 	if (pCfg->dir)
4714 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4715 	else
4716 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4717 
4718 	flagsLength |= pCfg->hdr->PageLength * 4;
4719 
4720 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4721 
4722 	dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4723 		ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4724 
4725 	/* Append pCfg pointer to end of mf
4726 	 */
4727 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
4728 
4729 	/* Initalize the timer
4730 	 */
4731 	init_timer(&pCfg->timer);
4732 	pCfg->timer.data = (unsigned long) ioc;
4733 	pCfg->timer.function = mpt_timer_expired;
4734 	pCfg->wait_done = 0;
4735 
4736 	/* Set the timer; ensure 10 second minimum */
4737 	if (pCfg->timeout < 10)
4738 		pCfg->timer.expires = jiffies + HZ*10;
4739 	else
4740 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4741 
4742 	/* Add to end of Q, set timer and then issue this command */
4743 	spin_lock_irqsave(&ioc->FreeQlock, flags);
4744 	list_add_tail(&pCfg->linkage, &ioc->configQ);
4745 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4746 
4747 	add_timer(&pCfg->timer);
4748 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4749 	wait_event(mpt_waitq, pCfg->wait_done);
4750 
4751 	/* mf has been freed - do not access */
4752 
4753 	rc = pCfg->status;
4754 
4755 	return rc;
4756 }
4757 
4758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4759 /**
4760  *	mpt_toolbox - Generic function to issue toolbox message
4761  *	@ioc - Pointer to an adapter structure
4762  *	@cfg - Pointer to a toolbox structure. Struct contains
4763  *		action, page address, direction, physical address
4764  *		and pointer to a configuration page header
4765  *		Page header is updated.
4766  *
4767  *	Returns 0 for success
4768  *	-EPERM if not allowed due to ISR context
4769  *	-EAGAIN if no msg frames currently available
4770  *	-EFAULT for non-successful reply or no reply (timeout)
4771  */
4772 int
4773 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4774 {
4775 	ToolboxIstwiReadWriteRequest_t	*pReq;
4776 	MPT_FRAME_HDR	*mf;
4777 	struct pci_dev	*pdev;
4778 	unsigned long	 flags;
4779 	int		 rc;
4780 	u32		 flagsLength;
4781 	int		 in_isr;
4782 
4783 	/*	Prevent calling wait_event() (below), if caller happens
4784 	 *	to be in ISR context, because that is fatal!
4785 	 */
4786 	in_isr = in_interrupt();
4787 	if (in_isr) {
4788 		dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4789 				ioc->name));
4790 		return -EPERM;
4791 	}
4792 
4793 	/* Get and Populate a free Frame
4794 	 */
4795 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4796 		dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4797 				ioc->name));
4798 		return -EAGAIN;
4799 	}
4800 	pReq = (ToolboxIstwiReadWriteRequest_t	*)mf;
4801 	pReq->Tool = pCfg->action;
4802 	pReq->Reserved = 0;
4803 	pReq->ChainOffset = 0;
4804 	pReq->Function = MPI_FUNCTION_TOOLBOX;
4805 	pReq->Reserved1 = 0;
4806 	pReq->Reserved2 = 0;
4807 	pReq->MsgFlags = 0;
4808 	pReq->Flags = pCfg->dir;
4809 	pReq->BusNum = 0;
4810 	pReq->Reserved3 = 0;
4811 	pReq->NumAddressBytes = 0x01;
4812 	pReq->Reserved4 = 0;
4813 	pReq->DataLength = 0x04;
4814 	pdev = (struct pci_dev *) ioc->pcidev;
4815 	if (pdev->devfn & 1)
4816 		pReq->DeviceAddr = 0xB2;
4817 	else
4818 		pReq->DeviceAddr = 0xB0;
4819 	pReq->Addr1 = 0;
4820 	pReq->Addr2 = 0;
4821 	pReq->Addr3 = 0;
4822 	pReq->Reserved5 = 0;
4823 
4824 	/* Add a SGE to the config request.
4825 	 */
4826 
4827 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4828 
4829 	mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4830 
4831 	dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4832 		ioc->name, pReq->Tool));
4833 
4834 	/* Append pCfg pointer to end of mf
4835 	 */
4836 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
4837 
4838 	/* Initalize the timer
4839 	 */
4840 	init_timer(&pCfg->timer);
4841 	pCfg->timer.data = (unsigned long) ioc;
4842 	pCfg->timer.function = mpt_timer_expired;
4843 	pCfg->wait_done = 0;
4844 
4845 	/* Set the timer; ensure 10 second minimum */
4846 	if (pCfg->timeout < 10)
4847 		pCfg->timer.expires = jiffies + HZ*10;
4848 	else
4849 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4850 
4851 	/* Add to end of Q, set timer and then issue this command */
4852 	spin_lock_irqsave(&ioc->FreeQlock, flags);
4853 	list_add_tail(&pCfg->linkage, &ioc->configQ);
4854 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4855 
4856 	add_timer(&pCfg->timer);
4857 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4858 	wait_event(mpt_waitq, pCfg->wait_done);
4859 
4860 	/* mf has been freed - do not access */
4861 
4862 	rc = pCfg->status;
4863 
4864 	return rc;
4865 }
4866 
4867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4868 /*
4869  *	mpt_timer_expired - Call back for timer process.
4870  *	Used only internal config functionality.
4871  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4872  */
4873 static void
4874 mpt_timer_expired(unsigned long data)
4875 {
4876 	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
4877 
4878 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
4879 
4880 	/* Perform a FW reload */
4881 	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
4882 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
4883 
4884 	/* No more processing.
4885 	 * Hard reset clean-up will wake up
4886 	 * process and free all resources.
4887 	 */
4888 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
4889 
4890 	return;
4891 }
4892 
4893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4894 /*
4895  *	mpt_ioc_reset - Base cleanup for hard reset
4896  *	@ioc: Pointer to the adapter structure
4897  *	@reset_phase: Indicates pre- or post-reset functionality
4898  *
4899  *	Remark: Free's resources with internally generated commands.
4900  */
4901 static int
4902 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
4903 {
4904 	CONFIGPARMS *pCfg;
4905 	unsigned long flags;
4906 
4907 	dprintk((KERN_WARNING MYNAM
4908 			": IOC %s_reset routed to MPT base driver!\n",
4909 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
4910 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
4911 
4912 	if (reset_phase == MPT_IOC_SETUP_RESET) {
4913 		;
4914 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
4915 		/* If the internal config Q is not empty -
4916 		 * delete timer. MF resources will be freed when
4917 		 * the FIFO's are primed.
4918 		 */
4919 		spin_lock_irqsave(&ioc->FreeQlock, flags);
4920 		list_for_each_entry(pCfg, &ioc->configQ, linkage)
4921 			del_timer(&pCfg->timer);
4922 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4923 
4924 	} else {
4925 		CONFIGPARMS *pNext;
4926 
4927 		/* Search the configQ for internal commands.
4928 		 * Flush the Q, and wake up all suspended threads.
4929 		 */
4930 		spin_lock_irqsave(&ioc->FreeQlock, flags);
4931 		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
4932 			list_del(&pCfg->linkage);
4933 
4934 			pCfg->status = MPT_CONFIG_ERROR;
4935 			pCfg->wait_done = 1;
4936 			wake_up(&mpt_waitq);
4937 		}
4938 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4939 	}
4940 
4941 	return 1;		/* currently means nothing really */
4942 }
4943 
4944 
4945 #ifdef CONFIG_PROC_FS		/* { */
4946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4947 /*
4948  *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
4949  */
4950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4951 /*
4952  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
4953  *
4954  *	Returns 0 for success, non-zero for failure.
4955  */
4956 static int
4957 procmpt_create(void)
4958 {
4959 	struct proc_dir_entry	*ent;
4960 
4961 	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
4962 	if (mpt_proc_root_dir == NULL)
4963 		return -ENOTDIR;
4964 
4965 	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4966 	if (ent)
4967 		ent->read_proc = procmpt_summary_read;
4968 
4969 	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4970 	if (ent)
4971 		ent->read_proc = procmpt_version_read;
4972 
4973 	return 0;
4974 }
4975 
4976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4977 /*
4978  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
4979  *
4980  *	Returns 0 for success, non-zero for failure.
4981  */
4982 static void
4983 procmpt_destroy(void)
4984 {
4985 	remove_proc_entry("version", mpt_proc_root_dir);
4986 	remove_proc_entry("summary", mpt_proc_root_dir);
4987 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
4988 }
4989 
4990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4991 /*
4992  *	procmpt_summary_read - Handle read request from /proc/mpt/summary
4993  *	or from /proc/mpt/iocN/summary.
4994  *	@buf: Pointer to area to write information
4995  *	@start: Pointer to start pointer
4996  *	@offset: Offset to start writing
4997  *	@request:
4998  *	@eof: Pointer to EOF integer
4999  *	@data: Pointer
5000  *
5001  *	Returns number of characters written to process performing the read.
5002  */
5003 static int
5004 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5005 {
5006 	MPT_ADAPTER *ioc;
5007 	char *out = buf;
5008 	int len;
5009 
5010 	if (data) {
5011 		int more = 0;
5012 
5013 		ioc = data;
5014 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5015 
5016 		out += more;
5017 	} else {
5018 		list_for_each_entry(ioc, &ioc_list, list) {
5019 			int	more = 0;
5020 
5021 			mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5022 
5023 			out += more;
5024 			if ((out-buf) >= request)
5025 				break;
5026 		}
5027 	}
5028 
5029 	len = out - buf;
5030 
5031 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5032 }
5033 
5034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5035 /*
5036  *	procmpt_version_read - Handle read request from /proc/mpt/version.
5037  *	@buf: Pointer to area to write information
5038  *	@start: Pointer to start pointer
5039  *	@offset: Offset to start writing
5040  *	@request:
5041  *	@eof: Pointer to EOF integer
5042  *	@data: Pointer
5043  *
5044  *	Returns number of characters written to process performing the read.
5045  */
5046 static int
5047 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5048 {
5049 	int	 ii;
5050 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
5051 	char	*drvname;
5052 	int	 len;
5053 
5054 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5055 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
5056 
5057 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
5058 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5059 		drvname = NULL;
5060 		if (MptCallbacks[ii]) {
5061 			switch (MptDriverClass[ii]) {
5062 			case MPTSPI_DRIVER:
5063 				if (!scsi++) drvname = "SPI host";
5064 				break;
5065 			case MPTFC_DRIVER:
5066 				if (!fc++) drvname = "FC host";
5067 				break;
5068 			case MPTSAS_DRIVER:
5069 				if (!sas++) drvname = "SAS host";
5070 				break;
5071 			case MPTLAN_DRIVER:
5072 				if (!lan++) drvname = "LAN";
5073 				break;
5074 			case MPTSTM_DRIVER:
5075 				if (!targ++) drvname = "SCSI target";
5076 				break;
5077 			case MPTCTL_DRIVER:
5078 				if (!ctl++) drvname = "ioctl";
5079 				break;
5080 			}
5081 
5082 			if (drvname)
5083 				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5084 		}
5085 	}
5086 
5087 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5088 }
5089 
5090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5091 /*
5092  *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5093  *	@buf: Pointer to area to write information
5094  *	@start: Pointer to start pointer
5095  *	@offset: Offset to start writing
5096  *	@request:
5097  *	@eof: Pointer to EOF integer
5098  *	@data: Pointer
5099  *
5100  *	Returns number of characters written to process performing the read.
5101  */
5102 static int
5103 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5104 {
5105 	MPT_ADAPTER	*ioc = data;
5106 	int		 len;
5107 	char		 expVer[32];
5108 	int		 sz;
5109 	int		 p;
5110 
5111 	mpt_get_fw_exp_ver(expVer, ioc);
5112 
5113 	len = sprintf(buf, "%s:", ioc->name);
5114 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5115 		len += sprintf(buf+len, "  (f/w download boot flag set)");
5116 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5117 //		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
5118 
5119 	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
5120 			ioc->facts.ProductID,
5121 			ioc->prod_name);
5122 	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5123 	if (ioc->facts.FWImageSize)
5124 		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5125 	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5126 	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5127 	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
5128 
5129 	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
5130 			ioc->facts.CurrentHostMfaHighAddr);
5131 	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
5132 			ioc->facts.CurrentSenseBufferHighAddr);
5133 
5134 	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5135 	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5136 
5137 	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5138 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5139 	/*
5140 	 *  Rounding UP to nearest 4-kB boundary here...
5141 	 */
5142 	sz = (ioc->req_sz * ioc->req_depth) + 128;
5143 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5144 	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5145 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5146 	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
5147 					4*ioc->facts.RequestFrameSize,
5148 					ioc->facts.GlobalCredits);
5149 
5150 	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
5151 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5152 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5153 	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5154 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5155 	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
5156 					ioc->facts.CurReplyFrameSize,
5157 					ioc->facts.ReplyQueueDepth);
5158 
5159 	len += sprintf(buf+len, "  MaxDevices = %d\n",
5160 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5161 	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
5162 
5163 	/* per-port info */
5164 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5165 		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
5166 				p+1,
5167 				ioc->facts.NumberOfPorts);
5168 		if (ioc->bus_type == FC) {
5169 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5170 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5171 				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5172 						a[5], a[4], a[3], a[2], a[1], a[0]);
5173 			}
5174 			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
5175 					ioc->fc_port_page0[p].WWNN.High,
5176 					ioc->fc_port_page0[p].WWNN.Low,
5177 					ioc->fc_port_page0[p].WWPN.High,
5178 					ioc->fc_port_page0[p].WWPN.Low);
5179 		}
5180 	}
5181 
5182 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5183 }
5184 
5185 #endif		/* CONFIG_PROC_FS } */
5186 
5187 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5188 static void
5189 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5190 {
5191 	buf[0] ='\0';
5192 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5193 		sprintf(buf, " (Exp %02d%02d)",
5194 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
5195 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
5196 
5197 		/* insider hack! */
5198 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5199 			strcat(buf, " [MDBG]");
5200 	}
5201 }
5202 
5203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5204 /**
5205  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5206  *	@ioc: Pointer to MPT_ADAPTER structure
5207  *	@buffer: Pointer to buffer where IOC summary info should be written
5208  *	@size: Pointer to number of bytes we wrote (set by this routine)
5209  *	@len: Offset at which to start writing in buffer
5210  *	@showlan: Display LAN stuff?
5211  *
5212  *	This routine writes (english readable) ASCII text, which represents
5213  *	a summary of IOC information, to a buffer.
5214  */
5215 void
5216 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5217 {
5218 	char expVer[32];
5219 	int y;
5220 
5221 	mpt_get_fw_exp_ver(expVer, ioc);
5222 
5223 	/*
5224 	 *  Shorter summary of attached ioc's...
5225 	 */
5226 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5227 			ioc->name,
5228 			ioc->prod_name,
5229 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
5230 			ioc->facts.FWVersion.Word,
5231 			expVer,
5232 			ioc->facts.NumberOfPorts,
5233 			ioc->req_depth);
5234 
5235 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5236 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5237 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5238 			a[5], a[4], a[3], a[2], a[1], a[0]);
5239 	}
5240 
5241 #ifndef __sparc__
5242 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5243 #else
5244 	y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5245 #endif
5246 
5247 	if (!ioc->active)
5248 		y += sprintf(buffer+len+y, " (disabled)");
5249 
5250 	y += sprintf(buffer+len+y, "\n");
5251 
5252 	*size = y;
5253 }
5254 
5255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5256 /*
5257  *	Reset Handling
5258  */
5259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5260 /**
5261  *	mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5262  *	Management call based on input arg values.  If TaskMgmt fails,
5263  *	return associated SCSI request.
5264  *	@ioc: Pointer to MPT_ADAPTER structure
5265  *	@sleepFlag: Indicates if sleep or schedule must be called.
5266  *
5267  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5268  *	or a non-interrupt thread.  In the former, must not call schedule().
5269  *
5270  *	Remark: A return of -1 is a FATAL error case, as it means a
5271  *	FW reload/initialization failed.
5272  *
5273  *	Returns 0 for SUCCESS or -1 if FAILED.
5274  */
5275 int
5276 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5277 {
5278 	int		 rc;
5279 	unsigned long	 flags;
5280 
5281 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5282 #ifdef MFCNT
5283 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5284 	printk("MF count 0x%x !\n", ioc->mfcnt);
5285 #endif
5286 
5287 	/* Reset the adapter. Prevent more than 1 call to
5288 	 * mpt_do_ioc_recovery at any instant in time.
5289 	 */
5290 	spin_lock_irqsave(&ioc->diagLock, flags);
5291 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5292 		spin_unlock_irqrestore(&ioc->diagLock, flags);
5293 		return 0;
5294 	} else {
5295 		ioc->diagPending = 1;
5296 	}
5297 	spin_unlock_irqrestore(&ioc->diagLock, flags);
5298 
5299 	/* FIXME: If do_ioc_recovery fails, repeat....
5300 	 */
5301 
5302 	/* The SCSI driver needs to adjust timeouts on all current
5303 	 * commands prior to the diagnostic reset being issued.
5304 	 * Prevents timeouts occuring during a diagnostic reset...very bad.
5305 	 * For all other protocol drivers, this is a no-op.
5306 	 */
5307 	{
5308 		int	 ii;
5309 		int	 r = 0;
5310 
5311 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5312 			if (MptResetHandlers[ii]) {
5313 				dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5314 						ioc->name, ii));
5315 				r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5316 				if (ioc->alt_ioc) {
5317 					dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5318 							ioc->name, ioc->alt_ioc->name, ii));
5319 					r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5320 				}
5321 			}
5322 		}
5323 	}
5324 
5325 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5326 		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5327 			rc, ioc->name);
5328 	}
5329 	ioc->reload_fw = 0;
5330 	if (ioc->alt_ioc)
5331 		ioc->alt_ioc->reload_fw = 0;
5332 
5333 	spin_lock_irqsave(&ioc->diagLock, flags);
5334 	ioc->diagPending = 0;
5335 	if (ioc->alt_ioc)
5336 		ioc->alt_ioc->diagPending = 0;
5337 	spin_unlock_irqrestore(&ioc->diagLock, flags);
5338 
5339 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5340 
5341 	return rc;
5342 }
5343 
5344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5345 static char *
5346 EventDescriptionStr(u8 event, u32 evData0)
5347 {
5348 	char *ds;
5349 
5350 	switch(event) {
5351 	case MPI_EVENT_NONE:
5352 		ds = "None";
5353 		break;
5354 	case MPI_EVENT_LOG_DATA:
5355 		ds = "Log Data";
5356 		break;
5357 	case MPI_EVENT_STATE_CHANGE:
5358 		ds = "State Change";
5359 		break;
5360 	case MPI_EVENT_UNIT_ATTENTION:
5361 		ds = "Unit Attention";
5362 		break;
5363 	case MPI_EVENT_IOC_BUS_RESET:
5364 		ds = "IOC Bus Reset";
5365 		break;
5366 	case MPI_EVENT_EXT_BUS_RESET:
5367 		ds = "External Bus Reset";
5368 		break;
5369 	case MPI_EVENT_RESCAN:
5370 		ds = "Bus Rescan Event";
5371 		/* Ok, do we need to do anything here? As far as
5372 		   I can tell, this is when a new device gets added
5373 		   to the loop. */
5374 		break;
5375 	case MPI_EVENT_LINK_STATUS_CHANGE:
5376 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5377 			ds = "Link Status(FAILURE) Change";
5378 		else
5379 			ds = "Link Status(ACTIVE) Change";
5380 		break;
5381 	case MPI_EVENT_LOOP_STATE_CHANGE:
5382 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5383 			ds = "Loop State(LIP) Change";
5384 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5385 			ds = "Loop State(LPE) Change";			/* ??? */
5386 		else
5387 			ds = "Loop State(LPB) Change";			/* ??? */
5388 		break;
5389 	case MPI_EVENT_LOGOUT:
5390 		ds = "Logout";
5391 		break;
5392 	case MPI_EVENT_EVENT_CHANGE:
5393 		if (evData0)
5394 			ds = "Events(ON) Change";
5395 		else
5396 			ds = "Events(OFF) Change";
5397 		break;
5398 	case MPI_EVENT_INTEGRATED_RAID:
5399 		ds = "Integrated Raid";
5400 		break;
5401 	/*
5402 	 *  MPT base "custom" events may be added here...
5403 	 */
5404 	default:
5405 		ds = "Unknown";
5406 		break;
5407 	}
5408 	return ds;
5409 }
5410 
5411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5412 /*
5413  *	ProcessEventNotification - Route a received EventNotificationReply to
5414  *	all currently regeistered event handlers.
5415  *	@ioc: Pointer to MPT_ADAPTER structure
5416  *	@pEventReply: Pointer to EventNotification reply frame
5417  *	@evHandlers: Pointer to integer, number of event handlers
5418  *
5419  *	Returns sum of event handlers return values.
5420  */
5421 static int
5422 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5423 {
5424 	u16 evDataLen;
5425 	u32 evData0 = 0;
5426 //	u32 evCtx;
5427 	int ii;
5428 	int r = 0;
5429 	int handlers = 0;
5430 	char *evStr;
5431 	u8 event;
5432 
5433 	/*
5434 	 *  Do platform normalization of values
5435 	 */
5436 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
5437 //	evCtx = le32_to_cpu(pEventReply->EventContext);
5438 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5439 	if (evDataLen) {
5440 		evData0 = le32_to_cpu(pEventReply->Data[0]);
5441 	}
5442 
5443 	evStr = EventDescriptionStr(event, evData0);
5444 	devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5445 			ioc->name,
5446 			evStr,
5447 			event));
5448 
5449 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5450 	printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5451 	for (ii = 0; ii < evDataLen; ii++)
5452 		printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5453 	printk("\n");
5454 #endif
5455 
5456 	/*
5457 	 *  Do general / base driver event processing
5458 	 */
5459 	switch(event) {
5460 	case MPI_EVENT_NONE:			/* 00 */
5461 	case MPI_EVENT_LOG_DATA:		/* 01 */
5462 	case MPI_EVENT_STATE_CHANGE:		/* 02 */
5463 	case MPI_EVENT_UNIT_ATTENTION:		/* 03 */
5464 	case MPI_EVENT_IOC_BUS_RESET:		/* 04 */
5465 	case MPI_EVENT_EXT_BUS_RESET:		/* 05 */
5466 	case MPI_EVENT_RESCAN:			/* 06 */
5467 	case MPI_EVENT_LINK_STATUS_CHANGE:	/* 07 */
5468 	case MPI_EVENT_LOOP_STATE_CHANGE:	/* 08 */
5469 	case MPI_EVENT_LOGOUT:			/* 09 */
5470 	case MPI_EVENT_INTEGRATED_RAID:		/* 0B */
5471 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:	/* 0C */
5472 	default:
5473 		break;
5474 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
5475 		if (evDataLen) {
5476 			u8 evState = evData0 & 0xFF;
5477 
5478 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
5479 
5480 			/* Update EventState field in cached IocFacts */
5481 			if (ioc->facts.Function) {
5482 				ioc->facts.EventState = evState;
5483 			}
5484 		}
5485 		break;
5486 	}
5487 
5488 	/*
5489 	 * Should this event be logged? Events are written sequentially.
5490 	 * When buffer is full, start again at the top.
5491 	 */
5492 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5493 		int idx;
5494 
5495 		idx = ioc->eventContext % ioc->eventLogSize;
5496 
5497 		ioc->events[idx].event = event;
5498 		ioc->events[idx].eventContext = ioc->eventContext;
5499 
5500 		for (ii = 0; ii < 2; ii++) {
5501 			if (ii < evDataLen)
5502 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5503 			else
5504 				ioc->events[idx].data[ii] =  0;
5505 		}
5506 
5507 		ioc->eventContext++;
5508 	}
5509 
5510 
5511 	/*
5512 	 *  Call each currently registered protocol event handler.
5513 	 */
5514 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5515 		if (MptEvHandlers[ii]) {
5516 			devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5517 					ioc->name, ii));
5518 			r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5519 			handlers++;
5520 		}
5521 	}
5522 	/* FIXME?  Examine results here? */
5523 
5524 	/*
5525 	 *  If needed, send (a single) EventAck.
5526 	 */
5527 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5528 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5529 			devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5530 					ioc->name, ii));
5531 		}
5532 	}
5533 
5534 	*evHandlers = handlers;
5535 	return r;
5536 }
5537 
5538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5539 /*
5540  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5541  *	@ioc: Pointer to MPT_ADAPTER structure
5542  *	@log_info: U32 LogInfo reply word from the IOC
5543  *
5544  *	Refer to lsi/fc_log.h.
5545  */
5546 static void
5547 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5548 {
5549 	static char *subcl_str[8] = {
5550 		"FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5551 		"FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5552 	};
5553 	u8 subcl = (log_info >> 24) & 0x7;
5554 
5555 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5556 			ioc->name, log_info, subcl_str[subcl]);
5557 }
5558 
5559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5560 /*
5561  *	mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5562  *	@ioc: Pointer to MPT_ADAPTER structure
5563  *	@mr: Pointer to MPT reply frame
5564  *	@log_info: U32 LogInfo word from the IOC
5565  *
5566  *	Refer to lsi/sp_log.h.
5567  */
5568 static void
5569 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5570 {
5571 	u32 info = log_info & 0x00FF0000;
5572 	char *desc = "unknown";
5573 
5574 	switch (info) {
5575 	case 0x00010000:
5576 		desc = "bug! MID not found";
5577 		if (ioc->reload_fw == 0)
5578 			ioc->reload_fw++;
5579 		break;
5580 
5581 	case 0x00020000:
5582 		desc = "Parity Error";
5583 		break;
5584 
5585 	case 0x00030000:
5586 		desc = "ASYNC Outbound Overrun";
5587 		break;
5588 
5589 	case 0x00040000:
5590 		desc = "SYNC Offset Error";
5591 		break;
5592 
5593 	case 0x00050000:
5594 		desc = "BM Change";
5595 		break;
5596 
5597 	case 0x00060000:
5598 		desc = "Msg In Overflow";
5599 		break;
5600 
5601 	case 0x00070000:
5602 		desc = "DMA Error";
5603 		break;
5604 
5605 	case 0x00080000:
5606 		desc = "Outbound DMA Overrun";
5607 		break;
5608 
5609 	case 0x00090000:
5610 		desc = "Task Management";
5611 		break;
5612 
5613 	case 0x000A0000:
5614 		desc = "Device Problem";
5615 		break;
5616 
5617 	case 0x000B0000:
5618 		desc = "Invalid Phase Change";
5619 		break;
5620 
5621 	case 0x000C0000:
5622 		desc = "Untagged Table Size";
5623 		break;
5624 
5625 	}
5626 
5627 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5628 }
5629 
5630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5631 /*
5632  *	mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5633  *	@ioc: Pointer to MPT_ADAPTER structure
5634  *	@ioc_status: U32 IOCStatus word from IOC
5635  *	@mf: Pointer to MPT request frame
5636  *
5637  *	Refer to lsi/mpi.h.
5638  */
5639 static void
5640 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5641 {
5642 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5643 	char *desc = "";
5644 
5645 	switch (status) {
5646 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5647 		desc = "Invalid Function";
5648 		break;
5649 
5650 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5651 		desc = "Busy";
5652 		break;
5653 
5654 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5655 		desc = "Invalid SGL";
5656 		break;
5657 
5658 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5659 		desc = "Internal Error";
5660 		break;
5661 
5662 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5663 		desc = "Reserved";
5664 		break;
5665 
5666 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5667 		desc = "Insufficient Resources";
5668 		break;
5669 
5670 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5671 		desc = "Invalid Field";
5672 		break;
5673 
5674 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5675 		desc = "Invalid State";
5676 		break;
5677 
5678 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5679 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
5680 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
5681 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
5682 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
5683 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
5684 		/* No message for Config IOCStatus values */
5685 		break;
5686 
5687 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5688 		/* No message for recovered error
5689 		desc = "SCSI Recovered Error";
5690 		*/
5691 		break;
5692 
5693 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5694 		desc = "SCSI Invalid Bus";
5695 		break;
5696 
5697 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5698 		desc = "SCSI Invalid TargetID";
5699 		break;
5700 
5701 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5702 	  {
5703 		SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5704 		U8 cdb = pScsiReq->CDB[0];
5705 		if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5706 			desc = "SCSI Device Not There";
5707 		}
5708 		break;
5709 	  }
5710 
5711 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5712 		desc = "SCSI Data Overrun";
5713 		break;
5714 
5715 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5716 		/* This error is checked in scsi_io_done(). Skip.
5717 		desc = "SCSI Data Underrun";
5718 		*/
5719 		break;
5720 
5721 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5722 		desc = "SCSI I/O Data Error";
5723 		break;
5724 
5725 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5726 		desc = "SCSI Protocol Error";
5727 		break;
5728 
5729 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5730 		desc = "SCSI Task Terminated";
5731 		break;
5732 
5733 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5734 		desc = "SCSI Residual Mismatch";
5735 		break;
5736 
5737 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5738 		desc = "SCSI Task Management Failed";
5739 		break;
5740 
5741 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5742 		desc = "SCSI IOC Terminated";
5743 		break;
5744 
5745 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5746 		desc = "SCSI Ext Terminated";
5747 		break;
5748 
5749 	default:
5750 		desc = "Others";
5751 		break;
5752 	}
5753 	if (desc != "")
5754 		printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5755 }
5756 
5757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5758 EXPORT_SYMBOL(mpt_attach);
5759 EXPORT_SYMBOL(mpt_detach);
5760 #ifdef CONFIG_PM
5761 EXPORT_SYMBOL(mpt_resume);
5762 EXPORT_SYMBOL(mpt_suspend);
5763 #endif
5764 EXPORT_SYMBOL(ioc_list);
5765 EXPORT_SYMBOL(mpt_proc_root_dir);
5766 EXPORT_SYMBOL(mpt_register);
5767 EXPORT_SYMBOL(mpt_deregister);
5768 EXPORT_SYMBOL(mpt_event_register);
5769 EXPORT_SYMBOL(mpt_event_deregister);
5770 EXPORT_SYMBOL(mpt_reset_register);
5771 EXPORT_SYMBOL(mpt_reset_deregister);
5772 EXPORT_SYMBOL(mpt_device_driver_register);
5773 EXPORT_SYMBOL(mpt_device_driver_deregister);
5774 EXPORT_SYMBOL(mpt_get_msg_frame);
5775 EXPORT_SYMBOL(mpt_put_msg_frame);
5776 EXPORT_SYMBOL(mpt_free_msg_frame);
5777 EXPORT_SYMBOL(mpt_add_sge);
5778 EXPORT_SYMBOL(mpt_send_handshake_request);
5779 EXPORT_SYMBOL(mpt_verify_adapter);
5780 EXPORT_SYMBOL(mpt_GetIocState);
5781 EXPORT_SYMBOL(mpt_print_ioc_summary);
5782 EXPORT_SYMBOL(mpt_lan_index);
5783 EXPORT_SYMBOL(mpt_stm_index);
5784 EXPORT_SYMBOL(mpt_HardResetHandler);
5785 EXPORT_SYMBOL(mpt_config);
5786 EXPORT_SYMBOL(mpt_toolbox);
5787 EXPORT_SYMBOL(mpt_findImVolumes);
5788 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5789 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5790 EXPORT_SYMBOL(mpt_free_fw_memory);
5791 
5792 
5793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5794 /*
5795  *	fusion_init - Fusion MPT base driver initialization routine.
5796  *
5797  *	Returns 0 for success, non-zero for failure.
5798  */
5799 static int __init
5800 fusion_init(void)
5801 {
5802 	int i;
5803 
5804 	show_mptmod_ver(my_NAME, my_VERSION);
5805 	printk(KERN_INFO COPYRIGHT "\n");
5806 
5807 	for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5808 		MptCallbacks[i] = NULL;
5809 		MptDriverClass[i] = MPTUNKNOWN_DRIVER;
5810 		MptEvHandlers[i] = NULL;
5811 		MptResetHandlers[i] = NULL;
5812 	}
5813 
5814 	/*  Register ourselves (mptbase) in order to facilitate
5815 	 *  EventNotification handling.
5816 	 */
5817 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
5818 
5819 	/* Register for hard reset handling callbacks.
5820 	 */
5821 	if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
5822 		dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
5823 	} else {
5824 		/* FIXME! */
5825 	}
5826 
5827 #ifdef CONFIG_PROC_FS
5828 	(void) procmpt_create();
5829 #endif
5830 	return 0;
5831 }
5832 
5833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5834 /*
5835  *	fusion_exit - Perform driver unload cleanup.
5836  *
5837  *	This routine frees all resources associated with each MPT adapter
5838  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
5839  */
5840 static void __exit
5841 fusion_exit(void)
5842 {
5843 
5844 	dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
5845 
5846 	mpt_reset_deregister(mpt_base_index);
5847 
5848 #ifdef CONFIG_PROC_FS
5849 	procmpt_destroy();
5850 #endif
5851 }
5852 
5853 module_init(fusion_init);
5854 module_exit(fusion_exit);
5855