xref: /openbmc/linux/drivers/message/fusion/mptbase.c (revision c21b37f6)
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-2007 LSI Logic Corporation
9  *  (mailto:DL-MPTFusionLinux@lsi.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/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h>		/* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
61 #include <asm/io.h>
62 #ifdef CONFIG_MTRR
63 #include <asm/mtrr.h>
64 #endif
65 
66 #include "mptbase.h"
67 #include "lsi/mpi_log_fc.h"
68 
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME		"Fusion MPT base driver"
71 #define my_VERSION	MPT_LINUX_VERSION_COMMON
72 #define MYNAM		"mptbase"
73 
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
78 
79 /*
80  *  cmd line parameters
81  */
82 static int mpt_msi_enable;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
85 
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
89 
90 static int mpt_debug_level;
91 module_param(mpt_debug_level, int, 0);
92 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
93 
94 #ifdef MFCNT
95 static int mfcounter = 0;
96 #define PRINT_MF_COUNT 20000
97 #endif
98 
99 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
100 /*
101  *  Public data...
102  */
103 int mpt_lan_index = -1;
104 int mpt_stm_index = -1;
105 
106 struct proc_dir_entry *mpt_proc_root_dir;
107 
108 #define WHOINIT_UNKNOWN		0xAA
109 
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
111 /*
112  *  Private data...
113  */
114 					/* Adapter link list */
115 LIST_HEAD(ioc_list);
116 					/* Callback lookup table */
117 static MPT_CALLBACK		 MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 					/* Protocol driver class lookup table */
119 static int			 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 					/* Event handler lookup table */
121 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 					/* Reset handler lookup table */
123 static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
125 
126 static int	mpt_base_index = -1;
127 static int	last_drv_idx = -1;
128 
129 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
130 
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
132 /*
133  *  Forward protos...
134  */
135 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
136 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
137 static int	mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
138 			u32 *req, int replyBytes, u16 *u16reply, int maxwait,
139 			int sleepFlag);
140 static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
141 static void	mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
142 static void	mpt_adapter_disable(MPT_ADAPTER *ioc);
143 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
144 
145 static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
146 static int	MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
147 static int	GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
148 static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
149 static int	SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
150 static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
151 static int	mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
152 static int	mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
153 static int	mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
154 static int	KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
155 static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
156 static int	PrimeIocFifos(MPT_ADAPTER *ioc);
157 static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
158 static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
159 static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
160 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
161 static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
162 int		mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
163 static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
164 static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
165 static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
166 static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
167 static void	mpt_timer_expired(unsigned long data);
168 static void	mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
169 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
170 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
171 static int	mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
172 static int	mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
173 
174 #ifdef CONFIG_PROC_FS
175 static int	procmpt_summary_read(char *buf, char **start, off_t offset,
176 				int request, int *eof, void *data);
177 static int	procmpt_version_read(char *buf, char **start, off_t offset,
178 				int request, int *eof, void *data);
179 static int	procmpt_iocinfo_read(char *buf, char **start, off_t offset,
180 				int request, int *eof, void *data);
181 #endif
182 static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
183 
184 //int		mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
185 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
186 static void	mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
187 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
188 static void	mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
189 static void	mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
190 static int	mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
191 static void	mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
192 
193 /* module entry point */
194 static int  __init    fusion_init  (void);
195 static void __exit    fusion_exit  (void);
196 
197 #define CHIPREG_READ32(addr) 		readl_relaxed(addr)
198 #define CHIPREG_READ32_dmasync(addr)	readl(addr)
199 #define CHIPREG_WRITE32(addr,val) 	writel(val, addr)
200 #define CHIPREG_PIO_WRITE32(addr,val)	outl(val, (unsigned long)addr)
201 #define CHIPREG_PIO_READ32(addr) 	inl((unsigned long)addr)
202 
203 static void
204 pci_disable_io_access(struct pci_dev *pdev)
205 {
206 	u16 command_reg;
207 
208 	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
209 	command_reg &= ~1;
210 	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
211 }
212 
213 static void
214 pci_enable_io_access(struct pci_dev *pdev)
215 {
216 	u16 command_reg;
217 
218 	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
219 	command_reg |= 1;
220 	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
221 }
222 
223 /*
224  *  Process turbo (context) reply...
225  */
226 static void
227 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
228 {
229 	MPT_FRAME_HDR *mf = NULL;
230 	MPT_FRAME_HDR *mr = NULL;
231 	int req_idx = 0;
232 	int cb_idx;
233 
234 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
235 				ioc->name, pa));
236 
237 	switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
238 	case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
239 		req_idx = pa & 0x0000FFFF;
240 		cb_idx = (pa & 0x00FF0000) >> 16;
241 		mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
242 		break;
243 	case MPI_CONTEXT_REPLY_TYPE_LAN:
244 		cb_idx = mpt_lan_index;
245 		/*
246 		 *  Blind set of mf to NULL here was fatal
247 		 *  after lan_reply says "freeme"
248 		 *  Fix sort of combined with an optimization here;
249 		 *  added explicit check for case where lan_reply
250 		 *  was just returning 1 and doing nothing else.
251 		 *  For this case skip the callback, but set up
252 		 *  proper mf value first here:-)
253 		 */
254 		if ((pa & 0x58000000) == 0x58000000) {
255 			req_idx = pa & 0x0000FFFF;
256 			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
257 			mpt_free_msg_frame(ioc, mf);
258 			mb();
259 			return;
260 			break;
261 		}
262 		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
263 		break;
264 	case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
265 		cb_idx = mpt_stm_index;
266 		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
267 		break;
268 	default:
269 		cb_idx = 0;
270 		BUG();
271 	}
272 
273 	/*  Check for (valid) IO callback!  */
274 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
275 			MptCallbacks[cb_idx] == NULL) {
276 		printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
277 				__FUNCTION__, ioc->name, cb_idx);
278 		goto out;
279 	}
280 
281 	if (MptCallbacks[cb_idx](ioc, mf, mr))
282 		mpt_free_msg_frame(ioc, mf);
283  out:
284 	mb();
285 }
286 
287 static void
288 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
289 {
290 	MPT_FRAME_HDR	*mf;
291 	MPT_FRAME_HDR	*mr;
292 	int		 req_idx;
293 	int		 cb_idx;
294 	int		 freeme;
295 
296 	u32 reply_dma_low;
297 	u16 ioc_stat;
298 
299 	/* non-TURBO reply!  Hmmm, something may be up...
300 	 *  Newest turbo reply mechanism; get address
301 	 *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
302 	 */
303 
304 	/* Map DMA address of reply header to cpu address.
305 	 * pa is 32 bits - but the dma address may be 32 or 64 bits
306 	 * get offset based only only the low addresses
307 	 */
308 
309 	reply_dma_low = (pa <<= 1);
310 	mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
311 			 (reply_dma_low - ioc->reply_frames_low_dma));
312 
313 	req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
314 	cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
315 	mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
316 
317 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
318 			ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
319 	DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr)
320 
321 	 /*  Check/log IOC log info
322 	 */
323 	ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
324 	if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
325 		u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
326 		if (ioc->bus_type == FC)
327 			mpt_fc_log_info(ioc, log_info);
328 		else if (ioc->bus_type == SPI)
329 			mpt_spi_log_info(ioc, log_info);
330 		else if (ioc->bus_type == SAS)
331 			mpt_sas_log_info(ioc, log_info);
332 	}
333 
334 	if (ioc_stat & MPI_IOCSTATUS_MASK)
335 		mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
336 
337 	/*  Check for (valid) IO callback!  */
338 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
339 			MptCallbacks[cb_idx] == NULL) {
340 		printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
341 				__FUNCTION__, ioc->name, cb_idx);
342 		freeme = 0;
343 		goto out;
344 	}
345 
346 	freeme = MptCallbacks[cb_idx](ioc, mf, mr);
347 
348  out:
349 	/*  Flush (non-TURBO) reply with a WRITE!  */
350 	CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
351 
352 	if (freeme)
353 		mpt_free_msg_frame(ioc, mf);
354 	mb();
355 }
356 
357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
358 /**
359  *	mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
360  *	@irq: irq number (not used)
361  *	@bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
362  *
363  *	This routine is registered via the request_irq() kernel API call,
364  *	and handles all interrupts generated from a specific MPT adapter
365  *	(also referred to as a IO Controller or IOC).
366  *	This routine must clear the interrupt from the adapter and does
367  *	so by reading the reply FIFO.  Multiple replies may be processed
368  *	per single call to this routine.
369  *
370  *	This routine handles register-level access of the adapter but
371  *	dispatches (calls) a protocol-specific callback routine to handle
372  *	the protocol-specific details of the MPT request completion.
373  */
374 static irqreturn_t
375 mpt_interrupt(int irq, void *bus_id)
376 {
377 	MPT_ADAPTER *ioc = bus_id;
378 	u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
379 
380 	if (pa == 0xFFFFFFFF)
381 		return IRQ_NONE;
382 
383 	/*
384 	 *  Drain the reply FIFO!
385 	 */
386 	do {
387 		if (pa & MPI_ADDRESS_REPLY_A_BIT)
388 			mpt_reply(ioc, pa);
389 		else
390 			mpt_turbo_reply(ioc, pa);
391 		pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
392 	} while (pa != 0xFFFFFFFF);
393 
394 	return IRQ_HANDLED;
395 }
396 
397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
398 /**
399  *	mpt_base_reply - MPT base driver's callback routine
400  *	@ioc: Pointer to MPT_ADAPTER structure
401  *	@mf: Pointer to original MPT request frame
402  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
403  *
404  *	MPT base driver's callback routine; all base driver
405  *	"internal" request/reply processing is routed here.
406  *	Currently used for EventNotification and EventAck handling.
407  *
408  *	Returns 1 indicating original alloc'd request frame ptr
409  *	should be freed, or 0 if it shouldn't.
410  */
411 static int
412 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
413 {
414 	int freereq = 1;
415 	u8 func;
416 
417 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
418 #ifdef CONFIG_FUSION_LOGGING
419 	if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
420 			!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
421 		dmfprintk(ioc, printk(KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
422 		DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf)
423 	}
424 #endif
425 
426 	func = reply->u.hdr.Function;
427 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
428 			ioc->name, func));
429 
430 	if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
431 		EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
432 		int evHandlers = 0;
433 		int results;
434 
435 		results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
436 		if (results != evHandlers) {
437 			/* CHECKME! Any special handling needed here? */
438 			devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
439 					ioc->name, evHandlers, results));
440 		}
441 
442 		/*
443 		 *	Hmmm...  It seems that EventNotificationReply is an exception
444 		 *	to the rule of one reply per request.
445 		 */
446 		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
447 			freereq = 0;
448 		} else {
449 			devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
450 				ioc->name, pEvReply));
451 		}
452 
453 #ifdef CONFIG_PROC_FS
454 //		LogEvent(ioc, pEvReply);
455 #endif
456 
457 	} else if (func == MPI_FUNCTION_EVENT_ACK) {
458 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
459 				ioc->name));
460 	} else if (func == MPI_FUNCTION_CONFIG) {
461 		CONFIGPARMS *pCfg;
462 		unsigned long flags;
463 
464 		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
465 				ioc->name, mf, reply));
466 
467 		pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
468 
469 		if (pCfg) {
470 			/* disable timer and remove from linked list */
471 			del_timer(&pCfg->timer);
472 
473 			spin_lock_irqsave(&ioc->FreeQlock, flags);
474 			list_del(&pCfg->linkage);
475 			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
476 
477 			/*
478 			 *	If IOC Status is SUCCESS, save the header
479 			 *	and set the status code to GOOD.
480 			 */
481 			pCfg->status = MPT_CONFIG_ERROR;
482 			if (reply) {
483 				ConfigReply_t	*pReply = (ConfigReply_t *)reply;
484 				u16		 status;
485 
486 				status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
487 				dcprintk(ioc, printk(KERN_NOTICE "  IOCStatus=%04xh, IOCLogInfo=%08xh\n",
488 				     status, le32_to_cpu(pReply->IOCLogInfo)));
489 
490 				pCfg->status = status;
491 				if (status == MPI_IOCSTATUS_SUCCESS) {
492 					if ((pReply->Header.PageType &
493 					    MPI_CONFIG_PAGETYPE_MASK) ==
494 					    MPI_CONFIG_PAGETYPE_EXTENDED) {
495 						pCfg->cfghdr.ehdr->ExtPageLength =
496 						    le16_to_cpu(pReply->ExtPageLength);
497 						pCfg->cfghdr.ehdr->ExtPageType =
498 						    pReply->ExtPageType;
499 					}
500 					pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
501 
502 					/* If this is a regular header, save PageLength. */
503 					/* LMP Do this better so not using a reserved field! */
504 					pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
505 					pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
506 					pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
507 				}
508 			}
509 
510 			/*
511 			 *	Wake up the original calling thread
512 			 */
513 			pCfg->wait_done = 1;
514 			wake_up(&mpt_waitq);
515 		}
516 	} else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
517 		/* we should be always getting a reply frame */
518 		memcpy(ioc->persist_reply_frame, reply,
519 		    min(MPT_DEFAULT_FRAME_SIZE,
520 		    4*reply->u.reply.MsgLength));
521 		del_timer(&ioc->persist_timer);
522 		ioc->persist_wait_done = 1;
523 		wake_up(&mpt_waitq);
524 	} else {
525 		printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
526 				ioc->name, func);
527 	}
528 
529 	/*
530 	 *	Conditionally tell caller to free the original
531 	 *	EventNotification/EventAck/unexpected request frame!
532 	 */
533 	return freereq;
534 }
535 
536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
537 /**
538  *	mpt_register - Register protocol-specific main callback handler.
539  *	@cbfunc: callback function pointer
540  *	@dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
541  *
542  *	This routine is called by a protocol-specific driver (SCSI host,
543  *	LAN, SCSI target) to register its reply callback routine.  Each
544  *	protocol-specific driver must do this before it will be able to
545  *	use any IOC resources, such as obtaining request frames.
546  *
547  *	NOTES: The SCSI protocol driver currently calls this routine thrice
548  *	in order to register separate callbacks; one for "normal" SCSI IO;
549  *	one for MptScsiTaskMgmt requests; one for Scan/DV requests.
550  *
551  *	Returns a positive integer valued "handle" in the
552  *	range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
553  *	Any non-positive return value (including zero!) should be considered
554  *	an error by the caller.
555  */
556 int
557 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
558 {
559 	int i;
560 
561 	last_drv_idx = -1;
562 
563 	/*
564 	 *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
565 	 *  (slot/handle 0 is reserved!)
566 	 */
567 	for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
568 		if (MptCallbacks[i] == NULL) {
569 			MptCallbacks[i] = cbfunc;
570 			MptDriverClass[i] = dclass;
571 			MptEvHandlers[i] = NULL;
572 			last_drv_idx = i;
573 			break;
574 		}
575 	}
576 
577 	return last_drv_idx;
578 }
579 
580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
581 /**
582  *	mpt_deregister - Deregister a protocol drivers resources.
583  *	@cb_idx: previously registered callback handle
584  *
585  *	Each protocol-specific driver should call this routine when its
586  *	module is unloaded.
587  */
588 void
589 mpt_deregister(int cb_idx)
590 {
591 	if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
592 		MptCallbacks[cb_idx] = NULL;
593 		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
594 		MptEvHandlers[cb_idx] = NULL;
595 
596 		last_drv_idx++;
597 	}
598 }
599 
600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
601 /**
602  *	mpt_event_register - Register protocol-specific event callback
603  *	handler.
604  *	@cb_idx: previously registered (via mpt_register) callback handle
605  *	@ev_cbfunc: callback function
606  *
607  *	This routine can be called by one or more protocol-specific drivers
608  *	if/when they choose to be notified of MPT events.
609  *
610  *	Returns 0 for success.
611  */
612 int
613 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
614 {
615 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
616 		return -1;
617 
618 	MptEvHandlers[cb_idx] = ev_cbfunc;
619 	return 0;
620 }
621 
622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
623 /**
624  *	mpt_event_deregister - Deregister protocol-specific event callback
625  *	handler.
626  *	@cb_idx: previously registered callback handle
627  *
628  *	Each protocol-specific driver should call this routine
629  *	when it does not (or can no longer) handle events,
630  *	or when its module is unloaded.
631  */
632 void
633 mpt_event_deregister(int cb_idx)
634 {
635 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
636 		return;
637 
638 	MptEvHandlers[cb_idx] = NULL;
639 }
640 
641 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
642 /**
643  *	mpt_reset_register - Register protocol-specific IOC reset handler.
644  *	@cb_idx: previously registered (via mpt_register) callback handle
645  *	@reset_func: reset function
646  *
647  *	This routine can be called by one or more protocol-specific drivers
648  *	if/when they choose to be notified of IOC resets.
649  *
650  *	Returns 0 for success.
651  */
652 int
653 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
654 {
655 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
656 		return -1;
657 
658 	MptResetHandlers[cb_idx] = reset_func;
659 	return 0;
660 }
661 
662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
663 /**
664  *	mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
665  *	@cb_idx: previously registered callback handle
666  *
667  *	Each protocol-specific driver should call this routine
668  *	when it does not (or can no longer) handle IOC reset handling,
669  *	or when its module is unloaded.
670  */
671 void
672 mpt_reset_deregister(int cb_idx)
673 {
674 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
675 		return;
676 
677 	MptResetHandlers[cb_idx] = NULL;
678 }
679 
680 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
681 /**
682  *	mpt_device_driver_register - Register device driver hooks
683  *	@dd_cbfunc: driver callbacks struct
684  *	@cb_idx: MPT protocol driver index
685  */
686 int
687 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
688 {
689 	MPT_ADAPTER	*ioc;
690 	const struct pci_device_id *id;
691 
692 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
693 		return -EINVAL;
694 
695 	MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
696 
697 	/* call per pci device probe entry point */
698 	list_for_each_entry(ioc, &ioc_list, list) {
699 		id = ioc->pcidev->driver ?
700 		    ioc->pcidev->driver->id_table : NULL;
701 		if (dd_cbfunc->probe)
702 			dd_cbfunc->probe(ioc->pcidev, id);
703 	 }
704 
705 	return 0;
706 }
707 
708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
709 /**
710  *	mpt_device_driver_deregister - DeRegister device driver hooks
711  *	@cb_idx: MPT protocol driver index
712  */
713 void
714 mpt_device_driver_deregister(int cb_idx)
715 {
716 	struct mpt_pci_driver *dd_cbfunc;
717 	MPT_ADAPTER	*ioc;
718 
719 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
720 		return;
721 
722 	dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
723 
724 	list_for_each_entry(ioc, &ioc_list, list) {
725 		if (dd_cbfunc->remove)
726 			dd_cbfunc->remove(ioc->pcidev);
727 	}
728 
729 	MptDeviceDriverHandlers[cb_idx] = NULL;
730 }
731 
732 
733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
734 /**
735  *	mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
736  *	allocated per MPT adapter.
737  *	@handle: Handle of registered MPT protocol driver
738  *	@ioc: Pointer to MPT adapter structure
739  *
740  *	Returns pointer to a MPT request frame or %NULL if none are available
741  *	or IOC is not active.
742  */
743 MPT_FRAME_HDR*
744 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
745 {
746 	MPT_FRAME_HDR *mf;
747 	unsigned long flags;
748 	u16	 req_idx;	/* Request index */
749 
750 	/* validate handle and ioc identifier */
751 
752 #ifdef MFCNT
753 	if (!ioc->active)
754 		printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
755 #endif
756 
757 	/* If interrupts are not attached, do not return a request frame */
758 	if (!ioc->active)
759 		return NULL;
760 
761 	spin_lock_irqsave(&ioc->FreeQlock, flags);
762 	if (!list_empty(&ioc->FreeQ)) {
763 		int req_offset;
764 
765 		mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
766 				u.frame.linkage.list);
767 		list_del(&mf->u.frame.linkage.list);
768 		mf->u.frame.linkage.arg1 = 0;
769 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;	/* byte */
770 		req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
771 								/* u16! */
772 		req_idx = req_offset / ioc->req_sz;
773 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
774 		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
775 		ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
776 #ifdef MFCNT
777 		ioc->mfcnt++;
778 #endif
779 	}
780 	else
781 		mf = NULL;
782 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
783 
784 #ifdef MFCNT
785 	if (mf == NULL)
786 		printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
787 	mfcounter++;
788 	if (mfcounter == PRINT_MF_COUNT)
789 		printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
790 #endif
791 
792 	dmfprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
793 			ioc->name, handle, ioc->id, mf));
794 	return mf;
795 }
796 
797 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
798 /**
799  *	mpt_put_msg_frame - Send a protocol specific MPT request frame
800  *	to a IOC.
801  *	@handle: Handle of registered MPT protocol driver
802  *	@ioc: Pointer to MPT adapter structure
803  *	@mf: Pointer to MPT request frame
804  *
805  *	This routine posts a MPT request frame to the request post FIFO of a
806  *	specific MPT adapter.
807  */
808 void
809 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
810 {
811 	u32 mf_dma_addr;
812 	int req_offset;
813 	u16	 req_idx;	/* Request index */
814 
815 	/* ensure values are reset properly! */
816 	mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		/* byte */
817 	req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
818 								/* u16! */
819 	req_idx = req_offset / ioc->req_sz;
820 	mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
821 	mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
822 
823 	DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
824 
825 	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
826 	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
827 	CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
828 }
829 
830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
831 /**
832  *	mpt_free_msg_frame - Place MPT request frame back on FreeQ.
833  *	@handle: Handle of registered MPT protocol driver
834  *	@ioc: Pointer to MPT adapter structure
835  *	@mf: Pointer to MPT request frame
836  *
837  *	This routine places a MPT request frame back on the MPT adapter's
838  *	FreeQ.
839  */
840 void
841 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
842 {
843 	unsigned long flags;
844 
845 	/*  Put Request back on FreeQ!  */
846 	spin_lock_irqsave(&ioc->FreeQlock, flags);
847 	mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
848 	list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
849 #ifdef MFCNT
850 	ioc->mfcnt--;
851 #endif
852 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
853 }
854 
855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
856 /**
857  *	mpt_add_sge - Place a simple SGE at address pAddr.
858  *	@pAddr: virtual address for SGE
859  *	@flagslength: SGE flags and data transfer length
860  *	@dma_addr: Physical address
861  *
862  *	This routine places a MPT request frame back on the MPT adapter's
863  *	FreeQ.
864  */
865 void
866 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
867 {
868 	if (sizeof(dma_addr_t) == sizeof(u64)) {
869 		SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
870 		u32 tmp = dma_addr & 0xFFFFFFFF;
871 
872 		pSge->FlagsLength = cpu_to_le32(flagslength);
873 		pSge->Address.Low = cpu_to_le32(tmp);
874 		tmp = (u32) ((u64)dma_addr >> 32);
875 		pSge->Address.High = cpu_to_le32(tmp);
876 
877 	} else {
878 		SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
879 		pSge->FlagsLength = cpu_to_le32(flagslength);
880 		pSge->Address = cpu_to_le32(dma_addr);
881 	}
882 }
883 
884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
885 /**
886  *	mpt_send_handshake_request - Send MPT request via doorbell handshake method.
887  *	@handle: Handle of registered MPT protocol driver
888  *	@ioc: Pointer to MPT adapter structure
889  *	@reqBytes: Size of the request in bytes
890  *	@req: Pointer to MPT request frame
891  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
892  *
893  *	This routine is used exclusively to send MptScsiTaskMgmt
894  *	requests since they are required to be sent via doorbell handshake.
895  *
896  *	NOTE: It is the callers responsibility to byte-swap fields in the
897  *	request which are greater than 1 byte in size.
898  *
899  *	Returns 0 for success, non-zero for failure.
900  */
901 int
902 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
903 {
904 	int	r = 0;
905 	u8	*req_as_bytes;
906 	int	 ii;
907 
908 	/* State is known to be good upon entering
909 	 * this function so issue the bus reset
910 	 * request.
911 	 */
912 
913 	/*
914 	 * Emulate what mpt_put_msg_frame() does /wrt to sanity
915 	 * setting cb_idx/req_idx.  But ONLY if this request
916 	 * is in proper (pre-alloc'd) request buffer range...
917 	 */
918 	ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
919 	if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
920 		MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
921 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
922 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
923 	}
924 
925 	/* Make sure there are no doorbells */
926 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
927 
928 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
929 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
930 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
931 
932 	/* Wait for IOC doorbell int */
933 	if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
934 		return ii;
935 	}
936 
937 	/* Read doorbell and check for active bit */
938 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
939 		return -5;
940 
941 	dhsprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
942 		ioc->name, ii));
943 
944 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
945 
946 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
947 		return -2;
948 	}
949 
950 	/* Send request via doorbell handshake */
951 	req_as_bytes = (u8 *) req;
952 	for (ii = 0; ii < reqBytes/4; ii++) {
953 		u32 word;
954 
955 		word = ((req_as_bytes[(ii*4) + 0] <<  0) |
956 			(req_as_bytes[(ii*4) + 1] <<  8) |
957 			(req_as_bytes[(ii*4) + 2] << 16) |
958 			(req_as_bytes[(ii*4) + 3] << 24));
959 		CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
960 		if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
961 			r = -3;
962 			break;
963 		}
964 	}
965 
966 	if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
967 		r = 0;
968 	else
969 		r = -4;
970 
971 	/* Make sure there are no doorbells */
972 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
973 
974 	return r;
975 }
976 
977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
978 /**
979  * mpt_host_page_access_control - control the IOC's Host Page Buffer access
980  * @ioc: Pointer to MPT adapter structure
981  * @access_control_value: define bits below
982  * @sleepFlag: Specifies whether the process can sleep
983  *
984  * Provides mechanism for the host driver to control the IOC's
985  * Host Page Buffer access.
986  *
987  * Access Control Value - bits[15:12]
988  * 0h Reserved
989  * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
990  * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
991  * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
992  *
993  * Returns 0 for success, non-zero for failure.
994  */
995 
996 static int
997 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
998 {
999 	int	 r = 0;
1000 
1001 	/* return if in use */
1002 	if (CHIPREG_READ32(&ioc->chip->Doorbell)
1003 	    & MPI_DOORBELL_ACTIVE)
1004 	    return -1;
1005 
1006 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1007 
1008 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1009 		((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1010 		 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1011 		 (access_control_value<<12)));
1012 
1013 	/* Wait for IOC to clear Doorbell Status bit */
1014 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1015 		return -2;
1016 	}else
1017 		return 0;
1018 }
1019 
1020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1021 /**
1022  *	mpt_host_page_alloc - allocate system memory for the fw
1023  *	@ioc: Pointer to pointer to IOC adapter
1024  *	@ioc_init: Pointer to ioc init config page
1025  *
1026  *	If we already allocated memory in past, then resend the same pointer.
1027  *	Returns 0 for success, non-zero for failure.
1028  */
1029 static int
1030 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1031 {
1032 	char	*psge;
1033 	int	flags_length;
1034 	u32	host_page_buffer_sz=0;
1035 
1036 	if(!ioc->HostPageBuffer) {
1037 
1038 		host_page_buffer_sz =
1039 		    le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1040 
1041 		if(!host_page_buffer_sz)
1042 			return 0; /* fw doesn't need any host buffers */
1043 
1044 		/* spin till we get enough memory */
1045 		while(host_page_buffer_sz > 0) {
1046 
1047 			if((ioc->HostPageBuffer = pci_alloc_consistent(
1048 			    ioc->pcidev,
1049 			    host_page_buffer_sz,
1050 			    &ioc->HostPageBuffer_dma)) != NULL) {
1051 
1052 				dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1053 				    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1054 				    ioc->name, ioc->HostPageBuffer,
1055 				    (u32)ioc->HostPageBuffer_dma,
1056 				    host_page_buffer_sz));
1057 				ioc->alloc_total += host_page_buffer_sz;
1058 				ioc->HostPageBuffer_sz = host_page_buffer_sz;
1059 				break;
1060 			}
1061 
1062 			host_page_buffer_sz -= (4*1024);
1063 		}
1064 	}
1065 
1066 	if(!ioc->HostPageBuffer) {
1067 		printk(MYIOC_s_ERR_FMT
1068 		    "Failed to alloc memory for host_page_buffer!\n",
1069 		    ioc->name);
1070 		return -999;
1071 	}
1072 
1073 	psge = (char *)&ioc_init->HostPageBufferSGE;
1074 	flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1075 	    MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1076 	    MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1077 	    MPI_SGE_FLAGS_HOST_TO_IOC |
1078 	    MPI_SGE_FLAGS_END_OF_BUFFER;
1079 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1080 	    flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1081 	}
1082 	flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1083 	flags_length |= ioc->HostPageBuffer_sz;
1084 	mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1085 	ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1086 
1087 return 0;
1088 }
1089 
1090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1091 /**
1092  *	mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1093  *	@iocid: IOC unique identifier (integer)
1094  *	@iocpp: Pointer to pointer to IOC adapter
1095  *
1096  *	Given a unique IOC identifier, set pointer to the associated MPT
1097  *	adapter structure.
1098  *
1099  *	Returns iocid and sets iocpp if iocid is found.
1100  *	Returns -1 if iocid is not found.
1101  */
1102 int
1103 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1104 {
1105 	MPT_ADAPTER *ioc;
1106 
1107 	list_for_each_entry(ioc,&ioc_list,list) {
1108 		if (ioc->id == iocid) {
1109 			*iocpp =ioc;
1110 			return iocid;
1111 		}
1112 	}
1113 
1114 	*iocpp = NULL;
1115 	return -1;
1116 }
1117 
1118 /**
1119  *	mpt_get_product_name - returns product string
1120  *	@vendor: pci vendor id
1121  *	@device: pci device id
1122  *	@revision: pci revision id
1123  *	@prod_name: string returned
1124  *
1125  *	Returns product string displayed when driver loads,
1126  *	in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1127  *
1128  **/
1129 static void
1130 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1131 {
1132 	char *product_str = NULL;
1133 
1134 	if (vendor == PCI_VENDOR_ID_BROCADE) {
1135 		switch (device)
1136 		{
1137 		case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1138 			switch (revision)
1139 			{
1140 			case 0x00:
1141 				product_str = "BRE040 A0";
1142 				break;
1143 			case 0x01:
1144 				product_str = "BRE040 A1";
1145 				break;
1146 			default:
1147 				product_str = "BRE040";
1148 				break;
1149 			}
1150 			break;
1151 		}
1152 		goto out;
1153 	}
1154 
1155 	switch (device)
1156 	{
1157 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1158 		product_str = "LSIFC909 B1";
1159 		break;
1160 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1161 		product_str = "LSIFC919 B0";
1162 		break;
1163 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1164 		product_str = "LSIFC929 B0";
1165 		break;
1166 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1167 		if (revision < 0x80)
1168 			product_str = "LSIFC919X A0";
1169 		else
1170 			product_str = "LSIFC919XL A1";
1171 		break;
1172 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1173 		if (revision < 0x80)
1174 			product_str = "LSIFC929X A0";
1175 		else
1176 			product_str = "LSIFC929XL A1";
1177 		break;
1178 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1179 		product_str = "LSIFC939X A1";
1180 		break;
1181 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1182 		product_str = "LSIFC949X A1";
1183 		break;
1184 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1185 		switch (revision)
1186 		{
1187 		case 0x00:
1188 			product_str = "LSIFC949E A0";
1189 			break;
1190 		case 0x01:
1191 			product_str = "LSIFC949E A1";
1192 			break;
1193 		default:
1194 			product_str = "LSIFC949E";
1195 			break;
1196 		}
1197 		break;
1198 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1199 		switch (revision)
1200 		{
1201 		case 0x00:
1202 			product_str = "LSI53C1030 A0";
1203 			break;
1204 		case 0x01:
1205 			product_str = "LSI53C1030 B0";
1206 			break;
1207 		case 0x03:
1208 			product_str = "LSI53C1030 B1";
1209 			break;
1210 		case 0x07:
1211 			product_str = "LSI53C1030 B2";
1212 			break;
1213 		case 0x08:
1214 			product_str = "LSI53C1030 C0";
1215 			break;
1216 		case 0x80:
1217 			product_str = "LSI53C1030T A0";
1218 			break;
1219 		case 0x83:
1220 			product_str = "LSI53C1030T A2";
1221 			break;
1222 		case 0x87:
1223 			product_str = "LSI53C1030T A3";
1224 			break;
1225 		case 0xc1:
1226 			product_str = "LSI53C1020A A1";
1227 			break;
1228 		default:
1229 			product_str = "LSI53C1030";
1230 			break;
1231 		}
1232 		break;
1233 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1234 		switch (revision)
1235 		{
1236 		case 0x03:
1237 			product_str = "LSI53C1035 A2";
1238 			break;
1239 		case 0x04:
1240 			product_str = "LSI53C1035 B0";
1241 			break;
1242 		default:
1243 			product_str = "LSI53C1035";
1244 			break;
1245 		}
1246 		break;
1247 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1248 		switch (revision)
1249 		{
1250 		case 0x00:
1251 			product_str = "LSISAS1064 A1";
1252 			break;
1253 		case 0x01:
1254 			product_str = "LSISAS1064 A2";
1255 			break;
1256 		case 0x02:
1257 			product_str = "LSISAS1064 A3";
1258 			break;
1259 		case 0x03:
1260 			product_str = "LSISAS1064 A4";
1261 			break;
1262 		default:
1263 			product_str = "LSISAS1064";
1264 			break;
1265 		}
1266 		break;
1267 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1268 		switch (revision)
1269 		{
1270 		case 0x00:
1271 			product_str = "LSISAS1064E A0";
1272 			break;
1273 		case 0x01:
1274 			product_str = "LSISAS1064E B0";
1275 			break;
1276 		case 0x02:
1277 			product_str = "LSISAS1064E B1";
1278 			break;
1279 		case 0x04:
1280 			product_str = "LSISAS1064E B2";
1281 			break;
1282 		case 0x08:
1283 			product_str = "LSISAS1064E B3";
1284 			break;
1285 		default:
1286 			product_str = "LSISAS1064E";
1287 			break;
1288 		}
1289 		break;
1290 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1291 		switch (revision)
1292 		{
1293 		case 0x00:
1294 			product_str = "LSISAS1068 A0";
1295 			break;
1296 		case 0x01:
1297 			product_str = "LSISAS1068 B0";
1298 			break;
1299 		case 0x02:
1300 			product_str = "LSISAS1068 B1";
1301 			break;
1302 		default:
1303 			product_str = "LSISAS1068";
1304 			break;
1305 		}
1306 		break;
1307 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1308 		switch (revision)
1309 		{
1310 		case 0x00:
1311 			product_str = "LSISAS1068E A0";
1312 			break;
1313 		case 0x01:
1314 			product_str = "LSISAS1068E B0";
1315 			break;
1316 		case 0x02:
1317 			product_str = "LSISAS1068E B1";
1318 			break;
1319 		case 0x04:
1320 			product_str = "LSISAS1068E B2";
1321 			break;
1322 		case 0x08:
1323 			product_str = "LSISAS1068E B3";
1324 			break;
1325 		default:
1326 			product_str = "LSISAS1068E";
1327 			break;
1328 		}
1329 		break;
1330 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1331 		switch (revision)
1332 		{
1333 		case 0x00:
1334 			product_str = "LSISAS1078 A0";
1335 			break;
1336 		case 0x01:
1337 			product_str = "LSISAS1078 B0";
1338 			break;
1339 		case 0x02:
1340 			product_str = "LSISAS1078 C0";
1341 			break;
1342 		case 0x03:
1343 			product_str = "LSISAS1078 C1";
1344 			break;
1345 		case 0x04:
1346 			product_str = "LSISAS1078 C2";
1347 			break;
1348 		default:
1349 			product_str = "LSISAS1078";
1350 			break;
1351 		}
1352 		break;
1353 	}
1354 
1355  out:
1356 	if (product_str)
1357 		sprintf(prod_name, "%s", product_str);
1358 }
1359 
1360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1361 /**
1362  *	mpt_attach - Install a PCI intelligent MPT adapter.
1363  *	@pdev: Pointer to pci_dev structure
1364  *	@id: PCI device ID information
1365  *
1366  *	This routine performs all the steps necessary to bring the IOC of
1367  *	a MPT adapter to a OPERATIONAL state.  This includes registering
1368  *	memory regions, registering the interrupt, and allocating request
1369  *	and reply memory pools.
1370  *
1371  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1372  *	MPT adapter.
1373  *
1374  *	Returns 0 for success, non-zero for failure.
1375  *
1376  *	TODO: Add support for polled controllers
1377  */
1378 int
1379 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1380 {
1381 	MPT_ADAPTER	*ioc;
1382 	u8		__iomem *mem;
1383 	unsigned long	 mem_phys;
1384 	unsigned long	 port;
1385 	u32		 msize;
1386 	u32		 psize;
1387 	int		 ii;
1388 	int		 r = -ENODEV;
1389 	u8		 revision;
1390 	u8		 pcixcmd;
1391 	static int	 mpt_ids = 0;
1392 #ifdef CONFIG_PROC_FS
1393 	struct proc_dir_entry *dent, *ent;
1394 #endif
1395 
1396 	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1397 	if (ioc == NULL) {
1398 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1399 		return -ENOMEM;
1400 	}
1401 
1402 	ioc->debug_level = mpt_debug_level;
1403 	if (mpt_debug_level)
1404 		printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1405 
1406 	if (pci_enable_device(pdev))
1407 		return r;
1408 
1409 	dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1410 
1411 	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1412 		dprintk(ioc, printk(KERN_INFO MYNAM
1413 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1414 	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1415 		printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1416 		return r;
1417 	}
1418 
1419 	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1420 		dprintk(ioc, printk(KERN_INFO MYNAM
1421 			": Using 64 bit consistent mask\n"));
1422 	} else {
1423 		dprintk(ioc, printk(KERN_INFO MYNAM
1424 			": Not using 64 bit consistent mask\n"));
1425 	}
1426 
1427 	ioc->alloc_total = sizeof(MPT_ADAPTER);
1428 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
1429 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1430 
1431 	ioc->pcidev = pdev;
1432 	ioc->diagPending = 0;
1433 	spin_lock_init(&ioc->diagLock);
1434 	spin_lock_init(&ioc->initializing_hba_lock);
1435 
1436 	/* Initialize the event logging.
1437 	 */
1438 	ioc->eventTypes = 0;	/* None */
1439 	ioc->eventContext = 0;
1440 	ioc->eventLogSize = 0;
1441 	ioc->events = NULL;
1442 
1443 #ifdef MFCNT
1444 	ioc->mfcnt = 0;
1445 #endif
1446 
1447 	ioc->cached_fw = NULL;
1448 
1449 	/* Initilize SCSI Config Data structure
1450 	 */
1451 	memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1452 
1453 	/* Initialize the running configQ head.
1454 	 */
1455 	INIT_LIST_HEAD(&ioc->configQ);
1456 
1457 	/* Initialize the fc rport list head.
1458 	 */
1459 	INIT_LIST_HEAD(&ioc->fc_rports);
1460 
1461 	/* Find lookup slot. */
1462 	INIT_LIST_HEAD(&ioc->list);
1463 	ioc->id = mpt_ids++;
1464 
1465 	mem_phys = msize = 0;
1466 	port = psize = 0;
1467 	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1468 		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1469 			if (psize)
1470 				continue;
1471 			/* Get I/O space! */
1472 			port = pci_resource_start(pdev, ii);
1473 			psize = pci_resource_len(pdev,ii);
1474 		} else {
1475 			if (msize)
1476 				continue;
1477 			/* Get memmap */
1478 			mem_phys = pci_resource_start(pdev, ii);
1479 			msize = pci_resource_len(pdev,ii);
1480 		}
1481 	}
1482 	ioc->mem_size = msize;
1483 
1484 	mem = NULL;
1485 	/* Get logical ptr for PciMem0 space */
1486 	/*mem = ioremap(mem_phys, msize);*/
1487 	mem = ioremap(mem_phys, msize);
1488 	if (mem == NULL) {
1489 		printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1490 		kfree(ioc);
1491 		return -EINVAL;
1492 	}
1493 	ioc->memmap = mem;
1494 	dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1495 
1496 	dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1497 			&ioc->facts, &ioc->pfacts[0]));
1498 
1499 	ioc->mem_phys = mem_phys;
1500 	ioc->chip = (SYSIF_REGS __iomem *)mem;
1501 
1502 	/* Save Port IO values in case we need to do downloadboot */
1503 	{
1504 		u8 *pmem = (u8*)port;
1505 		ioc->pio_mem_phys = port;
1506 		ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1507 	}
1508 
1509 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1510 	mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1511 
1512 	switch (pdev->device)
1513 	{
1514 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1515 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1516 		ioc->errata_flag_1064 = 1;
1517 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1518 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1519 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1520 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1521 		ioc->bus_type = FC;
1522 		break;
1523 
1524 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1525 		if (revision < XL_929) {
1526 			/* 929X Chip Fix. Set Split transactions level
1527 		 	* for PCIX. Set MOST bits to zero.
1528 		 	*/
1529 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1530 			pcixcmd &= 0x8F;
1531 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1532 		} else {
1533 			/* 929XL Chip Fix. Set MMRBC to 0x08.
1534 		 	*/
1535 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1536 			pcixcmd |= 0x08;
1537 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1538 		}
1539 		ioc->bus_type = FC;
1540 		break;
1541 
1542 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1543 		/* 919X Chip Fix. Set Split transactions level
1544 		 * for PCIX. Set MOST bits to zero.
1545 		 */
1546 		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1547 		pcixcmd &= 0x8F;
1548 		pci_write_config_byte(pdev, 0x6a, pcixcmd);
1549 		ioc->bus_type = FC;
1550 		break;
1551 
1552 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1553 		/* 1030 Chip Fix. Disable Split transactions
1554 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1555 		 */
1556 		if (revision < C0_1030) {
1557 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1558 			pcixcmd &= 0x8F;
1559 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1560 		}
1561 
1562 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1563 		ioc->bus_type = SPI;
1564 		break;
1565 
1566 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1567 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1568 		ioc->errata_flag_1064 = 1;
1569 
1570 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1571 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1572 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1573 		ioc->bus_type = SAS;
1574 	}
1575 
1576 	if (ioc->errata_flag_1064)
1577 		pci_disable_io_access(pdev);
1578 
1579 	sprintf(ioc->name, "ioc%d", ioc->id);
1580 
1581 	spin_lock_init(&ioc->FreeQlock);
1582 
1583 	/* Disable all! */
1584 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1585 	ioc->active = 0;
1586 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1587 
1588 	/* Set lookup ptr. */
1589 	list_add_tail(&ioc->list, &ioc_list);
1590 
1591 	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1592 	 */
1593 	mpt_detect_bound_ports(ioc, pdev);
1594 
1595 	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1596 	    CAN_SLEEP)) != 0){
1597 		printk(KERN_WARNING MYNAM
1598 		  ": WARNING - %s did not initialize properly! (%d)\n",
1599 		  ioc->name, r);
1600 
1601 		list_del(&ioc->list);
1602 		if (ioc->alt_ioc)
1603 			ioc->alt_ioc->alt_ioc = NULL;
1604 		iounmap(mem);
1605 		kfree(ioc);
1606 		pci_set_drvdata(pdev, NULL);
1607 		return r;
1608 	}
1609 
1610 	/* call per device driver probe entry point */
1611 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1612 		if(MptDeviceDriverHandlers[ii] &&
1613 		  MptDeviceDriverHandlers[ii]->probe) {
1614 			MptDeviceDriverHandlers[ii]->probe(pdev,id);
1615 		}
1616 	}
1617 
1618 #ifdef CONFIG_PROC_FS
1619 	/*
1620 	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1621 	 */
1622 	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1623 	if (dent) {
1624 		ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1625 		if (ent) {
1626 			ent->read_proc = procmpt_iocinfo_read;
1627 			ent->data = ioc;
1628 		}
1629 		ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1630 		if (ent) {
1631 			ent->read_proc = procmpt_summary_read;
1632 			ent->data = ioc;
1633 		}
1634 	}
1635 #endif
1636 
1637 	return 0;
1638 }
1639 
1640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1641 /**
1642  *	mpt_detach - Remove a PCI intelligent MPT adapter.
1643  *	@pdev: Pointer to pci_dev structure
1644  */
1645 
1646 void
1647 mpt_detach(struct pci_dev *pdev)
1648 {
1649 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
1650 	char pname[32];
1651 	int ii;
1652 
1653 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1654 	remove_proc_entry(pname, NULL);
1655 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1656 	remove_proc_entry(pname, NULL);
1657 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1658 	remove_proc_entry(pname, NULL);
1659 
1660 	/* call per device driver remove entry point */
1661 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1662 		if(MptDeviceDriverHandlers[ii] &&
1663 		  MptDeviceDriverHandlers[ii]->remove) {
1664 			MptDeviceDriverHandlers[ii]->remove(pdev);
1665 		}
1666 	}
1667 
1668 	/* Disable interrupts! */
1669 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1670 
1671 	ioc->active = 0;
1672 	synchronize_irq(pdev->irq);
1673 
1674 	/* Clear any lingering interrupt */
1675 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1676 
1677 	CHIPREG_READ32(&ioc->chip->IntStatus);
1678 
1679 	mpt_adapter_dispose(ioc);
1680 
1681 	pci_set_drvdata(pdev, NULL);
1682 }
1683 
1684 /**************************************************************************
1685  * Power Management
1686  */
1687 #ifdef CONFIG_PM
1688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1689 /**
1690  *	mpt_suspend - Fusion MPT base driver suspend routine.
1691  *	@pdev: Pointer to pci_dev structure
1692  *	@state: new state to enter
1693  */
1694 int
1695 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1696 {
1697 	u32 device_state;
1698 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1699 
1700 	device_state=pci_choose_state(pdev, state);
1701 
1702 	printk(MYIOC_s_INFO_FMT
1703 	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1704 		ioc->name, pdev, pci_name(pdev), device_state);
1705 
1706 	pci_save_state(pdev);
1707 
1708 	/* put ioc into READY_STATE */
1709 	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1710 		printk(MYIOC_s_ERR_FMT
1711 		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
1712 	}
1713 
1714 	/* disable interrupts */
1715 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1716 	ioc->active = 0;
1717 
1718 	/* Clear any lingering interrupt */
1719 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1720 
1721 	pci_disable_device(pdev);
1722 	pci_set_power_state(pdev, device_state);
1723 
1724 	return 0;
1725 }
1726 
1727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1728 /**
1729  *	mpt_resume - Fusion MPT base driver resume routine.
1730  *	@pdev: Pointer to pci_dev structure
1731  */
1732 int
1733 mpt_resume(struct pci_dev *pdev)
1734 {
1735 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1736 	u32 device_state = pdev->current_state;
1737 	int recovery_state;
1738 	int err;
1739 
1740 	printk(MYIOC_s_INFO_FMT
1741 	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1742 		ioc->name, pdev, pci_name(pdev), device_state);
1743 
1744 	pci_set_power_state(pdev, 0);
1745 	pci_restore_state(pdev);
1746 	err = pci_enable_device(pdev);
1747 	if (err)
1748 		return err;
1749 
1750 	/* enable interrupts */
1751 	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1752 	ioc->active = 1;
1753 
1754 	printk(MYIOC_s_INFO_FMT
1755 		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1756 		ioc->name,
1757 		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1758 		CHIPREG_READ32(&ioc->chip->Doorbell));
1759 
1760 	/* bring ioc to operational state */
1761 	if ((recovery_state = mpt_do_ioc_recovery(ioc,
1762 	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1763 		printk(MYIOC_s_INFO_FMT
1764 			"pci-resume: Cannot recover, error:[%x]\n",
1765 			ioc->name, recovery_state);
1766 	} else {
1767 		printk(MYIOC_s_INFO_FMT
1768 			"pci-resume: success\n", ioc->name);
1769 	}
1770 
1771 	return 0;
1772 }
1773 #endif
1774 
1775 static int
1776 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1777 {
1778 	if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1779 	     ioc->bus_type != SPI) ||
1780 	    (MptDriverClass[index] == MPTFC_DRIVER &&
1781 	     ioc->bus_type != FC) ||
1782 	    (MptDriverClass[index] == MPTSAS_DRIVER &&
1783 	     ioc->bus_type != SAS))
1784 		/* make sure we only call the relevant reset handler
1785 		 * for the bus */
1786 		return 0;
1787 	return (MptResetHandlers[index])(ioc, reset_phase);
1788 }
1789 
1790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1791 /**
1792  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1793  *	@ioc: Pointer to MPT adapter structure
1794  *	@reason: Event word / reason
1795  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1796  *
1797  *	This routine performs all the steps necessary to bring the IOC
1798  *	to a OPERATIONAL state.
1799  *
1800  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1801  *	MPT adapter.
1802  *
1803  *	Returns:
1804  *		 0 for success
1805  *		-1 if failed to get board READY
1806  *		-2 if READY but IOCFacts Failed
1807  *		-3 if READY but PrimeIOCFifos Failed
1808  *		-4 if READY but IOCInit Failed
1809  */
1810 static int
1811 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1812 {
1813 	int	 hard_reset_done = 0;
1814 	int	 alt_ioc_ready = 0;
1815 	int	 hard;
1816 	int	 rc=0;
1817 	int	 ii;
1818 	int	 handlers;
1819 	int	 ret = 0;
1820 	int	 reset_alt_ioc_active = 0;
1821 	int	 irq_allocated = 0;
1822 	u8	*a;
1823 
1824 	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1825 			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1826 
1827 	/* Disable reply interrupts (also blocks FreeQ) */
1828 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1829 	ioc->active = 0;
1830 
1831 	if (ioc->alt_ioc) {
1832 		if (ioc->alt_ioc->active)
1833 			reset_alt_ioc_active = 1;
1834 
1835 		/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1836 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1837 		ioc->alt_ioc->active = 0;
1838 	}
1839 
1840 	hard = 1;
1841 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1842 		hard = 0;
1843 
1844 	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1845 		if (hard_reset_done == -4) {
1846 			printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1847 					ioc->name);
1848 
1849 			if (reset_alt_ioc_active && ioc->alt_ioc) {
1850 				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1851 				dprintk(ioc, printk(KERN_INFO MYNAM
1852 					": alt-%s reply irq re-enabled\n",
1853 						ioc->alt_ioc->name));
1854 				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1855 				ioc->alt_ioc->active = 1;
1856 			}
1857 
1858 		} else {
1859 			printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1860 					ioc->name);
1861 		}
1862 		return -1;
1863 	}
1864 
1865 	/* hard_reset_done = 0 if a soft reset was performed
1866 	 * and 1 if a hard reset was performed.
1867 	 */
1868 	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1869 		if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1870 			alt_ioc_ready = 1;
1871 		else
1872 			printk(KERN_WARNING MYNAM
1873 					": alt-%s: Not ready WARNING!\n",
1874 					ioc->alt_ioc->name);
1875 	}
1876 
1877 	for (ii=0; ii<5; ii++) {
1878 		/* Get IOC facts! Allow 5 retries */
1879 		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1880 			break;
1881 	}
1882 
1883 
1884 	if (ii == 5) {
1885 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1886 		ret = -2;
1887 	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1888 		MptDisplayIocCapabilities(ioc);
1889 	}
1890 
1891 	if (alt_ioc_ready) {
1892 		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1893 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1894 				"Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1895 			/* Retry - alt IOC was initialized once
1896 			 */
1897 			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1898 		}
1899 		if (rc) {
1900 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1901 				"Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1902 			alt_ioc_ready = 0;
1903 			reset_alt_ioc_active = 0;
1904 		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1905 			MptDisplayIocCapabilities(ioc->alt_ioc);
1906 		}
1907 	}
1908 
1909 	/*
1910 	 * Device is reset now. It must have de-asserted the interrupt line
1911 	 * (if it was asserted) and it should be safe to register for the
1912 	 * interrupt now.
1913 	 */
1914 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1915 		ioc->pci_irq = -1;
1916 		if (ioc->pcidev->irq) {
1917 			if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1918 				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1919 					ioc->name);
1920 			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1921 					IRQF_SHARED, ioc->name, ioc);
1922 			if (rc < 0) {
1923 				printk(MYIOC_s_ERR_FMT "Unable to allocate "
1924 					"interrupt %d!\n", ioc->name,
1925 					ioc->pcidev->irq);
1926 				if (mpt_msi_enable)
1927 					pci_disable_msi(ioc->pcidev);
1928 				return -EBUSY;
1929 			}
1930 			irq_allocated = 1;
1931 			ioc->pci_irq = ioc->pcidev->irq;
1932 			pci_set_master(ioc->pcidev);		/* ?? */
1933 			pci_set_drvdata(ioc->pcidev, ioc);
1934 			dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt "
1935 				"%d\n", ioc->name, ioc->pcidev->irq));
1936 		}
1937 	}
1938 
1939 	/* Prime reply & request queues!
1940 	 * (mucho alloc's) Must be done prior to
1941 	 * init as upper addresses are needed for init.
1942 	 * If fails, continue with alt-ioc processing
1943 	 */
1944 	if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1945 		ret = -3;
1946 
1947 	/* May need to check/upload firmware & data here!
1948 	 * If fails, continue with alt-ioc processing
1949 	 */
1950 	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1951 		ret = -4;
1952 // NEW!
1953 	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1954 		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1955 				ioc->alt_ioc->name, rc);
1956 		alt_ioc_ready = 0;
1957 		reset_alt_ioc_active = 0;
1958 	}
1959 
1960 	if (alt_ioc_ready) {
1961 		if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1962 			alt_ioc_ready = 0;
1963 			reset_alt_ioc_active = 0;
1964 			printk(KERN_WARNING MYNAM
1965 				": alt-%s: (%d) init failure WARNING!\n",
1966 					ioc->alt_ioc->name, rc);
1967 		}
1968 	}
1969 
1970 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1971 		if (ioc->upload_fw) {
1972 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1973 				"firmware upload required!\n", ioc->name));
1974 
1975 			/* Controller is not operational, cannot do upload
1976 			 */
1977 			if (ret == 0) {
1978 				rc = mpt_do_upload(ioc, sleepFlag);
1979 				if (rc == 0) {
1980 					if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1981 						/*
1982 						 * Maintain only one pointer to FW memory
1983 						 * so there will not be two attempt to
1984 						 * downloadboot onboard dual function
1985 						 * chips (mpt_adapter_disable,
1986 						 * mpt_diag_reset)
1987 						 */
1988 						ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1989 							": mpt_upload:  alt_%s has cached_fw=%p \n",
1990 							ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1991 						ioc->alt_ioc->cached_fw = NULL;
1992 					}
1993 				} else {
1994 					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1995 					ret = -5;
1996 				}
1997 			}
1998 		}
1999 	}
2000 
2001 	if (ret == 0) {
2002 		/* Enable! (reply interrupt) */
2003 		CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2004 		ioc->active = 1;
2005 	}
2006 
2007 	if (reset_alt_ioc_active && ioc->alt_ioc) {
2008 		/* (re)Enable alt-IOC! (reply interrupt) */
2009 		dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2010 				ioc->alt_ioc->name));
2011 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2012 		ioc->alt_ioc->active = 1;
2013 	}
2014 
2015 	/*  Enable MPT base driver management of EventNotification
2016 	 *  and EventAck handling.
2017 	 */
2018 	if ((ret == 0) && (!ioc->facts.EventState))
2019 		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
2020 
2021 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2022 		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
2023 
2024 	/*	Add additional "reason" check before call to GetLanConfigPages
2025 	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
2026 	 *	recursive scenario; GetLanConfigPages times out, timer expired
2027 	 *	routine calls HardResetHandler, which calls into here again,
2028 	 *	and we try GetLanConfigPages again...
2029 	 */
2030 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2031 
2032 		/*
2033 		 * Initalize link list for inactive raid volumes.
2034 		 */
2035 		init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2036 		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2037 
2038 		if (ioc->bus_type == SAS) {
2039 
2040 			/* clear persistency table */
2041 			if(ioc->facts.IOCExceptions &
2042 			    MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2043 				ret = mptbase_sas_persist_operation(ioc,
2044 				    MPI_SAS_OP_CLEAR_NOT_PRESENT);
2045 				if(ret != 0)
2046 					goto out;
2047 			}
2048 
2049 			/* Find IM volumes
2050 			 */
2051 			mpt_findImVolumes(ioc);
2052 
2053 		} else if (ioc->bus_type == FC) {
2054 			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2055 			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2056 				/*
2057 				 *  Pre-fetch the ports LAN MAC address!
2058 				 *  (LANPage1_t stuff)
2059 				 */
2060 				(void) GetLanConfigPages(ioc);
2061 				a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2062 				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2063 					"LanAddr = %02X:%02X:%02X:"
2064 					"%02X:%02X:%02X\n",
2065 					ioc->name, a[5], a[4],
2066 					a[3], a[2], a[1], a[0] ));
2067 
2068 			}
2069 		} else {
2070 			/* Get NVRAM and adapter maximums from SPP 0 and 2
2071 			 */
2072 			mpt_GetScsiPortSettings(ioc, 0);
2073 
2074 			/* Get version and length of SDP 1
2075 			 */
2076 			mpt_readScsiDevicePageHeaders(ioc, 0);
2077 
2078 			/* Find IM volumes
2079 			 */
2080 			if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2081 				mpt_findImVolumes(ioc);
2082 
2083 			/* Check, and possibly reset, the coalescing value
2084 			 */
2085 			mpt_read_ioc_pg_1(ioc);
2086 
2087 			mpt_read_ioc_pg_4(ioc);
2088 		}
2089 
2090 		GetIoUnitPage2(ioc);
2091 		mpt_get_manufacturing_pg_0(ioc);
2092 	}
2093 
2094 	/*
2095 	 * Call each currently registered protocol IOC reset handler
2096 	 * with post-reset indication.
2097 	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2098 	 * MptResetHandlers[] registered yet.
2099 	 */
2100 	if (hard_reset_done) {
2101 		rc = handlers = 0;
2102 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2103 			if ((ret == 0) && MptResetHandlers[ii]) {
2104 				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2105 					"Calling IOC post_reset handler #%d\n",
2106 					ioc->name, ii));
2107 				rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
2108 				handlers++;
2109 			}
2110 
2111 			if (alt_ioc_ready && MptResetHandlers[ii]) {
2112 				drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2113 					"Calling alt-%s post_reset handler #%d\n",
2114 					ioc->name, ioc->alt_ioc->name, ii));
2115 				rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
2116 				handlers++;
2117 			}
2118 		}
2119 		/* FIXME?  Examine results here? */
2120 	}
2121 
2122  out:
2123 	if ((ret != 0) && irq_allocated) {
2124 		free_irq(ioc->pci_irq, ioc);
2125 		if (mpt_msi_enable)
2126 			pci_disable_msi(ioc->pcidev);
2127 	}
2128 	return ret;
2129 }
2130 
2131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2132 /**
2133  *	mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2134  *	@ioc: Pointer to MPT adapter structure
2135  *	@pdev: Pointer to (struct pci_dev) structure
2136  *
2137  *	Search for PCI bus/dev_function which matches
2138  *	PCI bus/dev_function (+/-1) for newly discovered 929,
2139  *	929X, 1030 or 1035.
2140  *
2141  *	If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2142  *	using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2143  */
2144 static void
2145 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2146 {
2147 	struct pci_dev *peer=NULL;
2148 	unsigned int slot = PCI_SLOT(pdev->devfn);
2149 	unsigned int func = PCI_FUNC(pdev->devfn);
2150 	MPT_ADAPTER *ioc_srch;
2151 
2152 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2153 	    " searching for devfn match on %x or %x\n",
2154 		ioc->name, pci_name(pdev), pdev->bus->number,
2155 		pdev->devfn, func-1, func+1));
2156 
2157 	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2158 	if (!peer) {
2159 		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2160 		if (!peer)
2161 			return;
2162 	}
2163 
2164 	list_for_each_entry(ioc_srch, &ioc_list, list) {
2165 		struct pci_dev *_pcidev = ioc_srch->pcidev;
2166 		if (_pcidev == peer) {
2167 			/* Paranoia checks */
2168 			if (ioc->alt_ioc != NULL) {
2169 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2170 					ioc->name, ioc->alt_ioc->name);
2171 				break;
2172 			} else if (ioc_srch->alt_ioc != NULL) {
2173 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2174 					ioc_srch->name, ioc_srch->alt_ioc->name);
2175 				break;
2176 			}
2177 			dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2178 				ioc->name, ioc_srch->name));
2179 			ioc_srch->alt_ioc = ioc;
2180 			ioc->alt_ioc = ioc_srch;
2181 		}
2182 	}
2183 	pci_dev_put(peer);
2184 }
2185 
2186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2187 /**
2188  *	mpt_adapter_disable - Disable misbehaving MPT adapter.
2189  *	@ioc: Pointer to MPT adapter structure
2190  */
2191 static void
2192 mpt_adapter_disable(MPT_ADAPTER *ioc)
2193 {
2194 	int sz;
2195 	int ret;
2196 
2197 	if (ioc->cached_fw != NULL) {
2198 		ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2199 		if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2200 			printk(KERN_WARNING MYNAM
2201 				": firmware downloadboot failure (%d)!\n", ret);
2202 		}
2203 	}
2204 
2205 	/* Disable adapter interrupts! */
2206 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2207 	ioc->active = 0;
2208 	/* Clear any lingering interrupt */
2209 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2210 
2211 	if (ioc->alloc != NULL) {
2212 		sz = ioc->alloc_sz;
2213 		dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free  @ %p, sz=%d bytes\n",
2214 		 	ioc->name, ioc->alloc, ioc->alloc_sz));
2215 		pci_free_consistent(ioc->pcidev, sz,
2216 				ioc->alloc, ioc->alloc_dma);
2217 		ioc->reply_frames = NULL;
2218 		ioc->req_frames = NULL;
2219 		ioc->alloc = NULL;
2220 		ioc->alloc_total -= sz;
2221 	}
2222 
2223 	if (ioc->sense_buf_pool != NULL) {
2224 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2225 		pci_free_consistent(ioc->pcidev, sz,
2226 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2227 		ioc->sense_buf_pool = NULL;
2228 		ioc->alloc_total -= sz;
2229 	}
2230 
2231 	if (ioc->events != NULL){
2232 		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2233 		kfree(ioc->events);
2234 		ioc->events = NULL;
2235 		ioc->alloc_total -= sz;
2236 	}
2237 
2238 	if (ioc->cached_fw != NULL) {
2239 		sz = ioc->facts.FWImageSize;
2240 		pci_free_consistent(ioc->pcidev, sz,
2241 			ioc->cached_fw, ioc->cached_fw_dma);
2242 		ioc->cached_fw = NULL;
2243 		ioc->alloc_total -= sz;
2244 	}
2245 
2246 	kfree(ioc->spi_data.nvram);
2247 	mpt_inactive_raid_list_free(ioc);
2248 	kfree(ioc->raid_data.pIocPg2);
2249 	kfree(ioc->raid_data.pIocPg3);
2250 	ioc->spi_data.nvram = NULL;
2251 	ioc->raid_data.pIocPg3 = NULL;
2252 
2253 	if (ioc->spi_data.pIocPg4 != NULL) {
2254 		sz = ioc->spi_data.IocPg4Sz;
2255 		pci_free_consistent(ioc->pcidev, sz,
2256 			ioc->spi_data.pIocPg4,
2257 			ioc->spi_data.IocPg4_dma);
2258 		ioc->spi_data.pIocPg4 = NULL;
2259 		ioc->alloc_total -= sz;
2260 	}
2261 
2262 	if (ioc->ReqToChain != NULL) {
2263 		kfree(ioc->ReqToChain);
2264 		kfree(ioc->RequestNB);
2265 		ioc->ReqToChain = NULL;
2266 	}
2267 
2268 	kfree(ioc->ChainToChain);
2269 	ioc->ChainToChain = NULL;
2270 
2271 	if (ioc->HostPageBuffer != NULL) {
2272 		if((ret = mpt_host_page_access_control(ioc,
2273 		    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2274 			printk(KERN_ERR MYNAM
2275 			   ": %s: host page buffers free failed (%d)!\n",
2276 			    __FUNCTION__, ret);
2277 		}
2278 		dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free  @ %p, sz=%d bytes\n",
2279 		 	ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2280 		pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2281 				ioc->HostPageBuffer,
2282 				ioc->HostPageBuffer_dma);
2283 		ioc->HostPageBuffer = NULL;
2284 		ioc->HostPageBuffer_sz = 0;
2285 		ioc->alloc_total -= ioc->HostPageBuffer_sz;
2286 	}
2287 }
2288 
2289 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2290 /**
2291  *	mpt_adapter_dispose - Free all resources associated with an MPT adapter
2292  *	@ioc: Pointer to MPT adapter structure
2293  *
2294  *	This routine unregisters h/w resources and frees all alloc'd memory
2295  *	associated with a MPT adapter structure.
2296  */
2297 static void
2298 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2299 {
2300 	int sz_first, sz_last;
2301 
2302 	if (ioc == NULL)
2303 		return;
2304 
2305 	sz_first = ioc->alloc_total;
2306 
2307 	mpt_adapter_disable(ioc);
2308 
2309 	if (ioc->pci_irq != -1) {
2310 		free_irq(ioc->pci_irq, ioc);
2311 		if (mpt_msi_enable)
2312 			pci_disable_msi(ioc->pcidev);
2313 		ioc->pci_irq = -1;
2314 	}
2315 
2316 	if (ioc->memmap != NULL) {
2317 		iounmap(ioc->memmap);
2318 		ioc->memmap = NULL;
2319 	}
2320 
2321 #if defined(CONFIG_MTRR) && 0
2322 	if (ioc->mtrr_reg > 0) {
2323 		mtrr_del(ioc->mtrr_reg, 0, 0);
2324 		dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2325 	}
2326 #endif
2327 
2328 	/*  Zap the adapter lookup ptr!  */
2329 	list_del(&ioc->list);
2330 
2331 	sz_last = ioc->alloc_total;
2332 	dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2333 			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2334 
2335 	if (ioc->alt_ioc)
2336 		ioc->alt_ioc->alt_ioc = NULL;
2337 
2338 	kfree(ioc);
2339 }
2340 
2341 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2342 /**
2343  *	MptDisplayIocCapabilities - Disply IOC's capabilities.
2344  *	@ioc: Pointer to MPT adapter structure
2345  */
2346 static void
2347 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2348 {
2349 	int i = 0;
2350 
2351 	printk(KERN_INFO "%s: ", ioc->name);
2352 	if (ioc->prod_name)
2353 		printk("%s: ", ioc->prod_name);
2354 	printk("Capabilities={");
2355 
2356 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2357 		printk("Initiator");
2358 		i++;
2359 	}
2360 
2361 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2362 		printk("%sTarget", i ? "," : "");
2363 		i++;
2364 	}
2365 
2366 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2367 		printk("%sLAN", i ? "," : "");
2368 		i++;
2369 	}
2370 
2371 #if 0
2372 	/*
2373 	 *  This would probably evoke more questions than it's worth
2374 	 */
2375 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2376 		printk("%sLogBusAddr", i ? "," : "");
2377 		i++;
2378 	}
2379 #endif
2380 
2381 	printk("}\n");
2382 }
2383 
2384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2385 /**
2386  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2387  *	@ioc: Pointer to MPT_ADAPTER structure
2388  *	@force: Force hard KickStart of IOC
2389  *	@sleepFlag: Specifies whether the process can sleep
2390  *
2391  *	Returns:
2392  *		 1 - DIAG reset and READY
2393  *		 0 - READY initially OR soft reset and READY
2394  *		-1 - Any failure on KickStart
2395  *		-2 - Msg Unit Reset Failed
2396  *		-3 - IO Unit Reset Failed
2397  *		-4 - IOC owned by a PEER
2398  */
2399 static int
2400 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2401 {
2402 	u32	 ioc_state;
2403 	int	 statefault = 0;
2404 	int	 cntdn;
2405 	int	 hard_reset_done = 0;
2406 	int	 r;
2407 	int	 ii;
2408 	int	 whoinit;
2409 
2410 	/* Get current [raw] IOC state  */
2411 	ioc_state = mpt_GetIocState(ioc, 0);
2412 	dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2413 
2414 	/*
2415 	 *	Check to see if IOC got left/stuck in doorbell handshake
2416 	 *	grip of death.  If so, hard reset the IOC.
2417 	 */
2418 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
2419 		statefault = 1;
2420 		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2421 				ioc->name);
2422 	}
2423 
2424 	/* Is it already READY? */
2425 	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2426 		return 0;
2427 
2428 	/*
2429 	 *	Check to see if IOC is in FAULT state.
2430 	 */
2431 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2432 		statefault = 2;
2433 		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2434 				ioc->name);
2435 		printk(KERN_WARNING "           FAULT code = %04xh\n",
2436 				ioc_state & MPI_DOORBELL_DATA_MASK);
2437 	}
2438 
2439 	/*
2440 	 *	Hmmm...  Did it get left operational?
2441 	 */
2442 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2443 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2444 				ioc->name));
2445 
2446 		/* Check WhoInit.
2447 		 * If PCI Peer, exit.
2448 		 * Else, if no fault conditions are present, issue a MessageUnitReset
2449 		 * Else, fall through to KickStart case
2450 		 */
2451 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2452 		dinitprintk(ioc, printk(KERN_INFO MYNAM
2453 			": whoinit 0x%x statefault %d force %d\n",
2454 			whoinit, statefault, force));
2455 		if (whoinit == MPI_WHOINIT_PCI_PEER)
2456 			return -4;
2457 		else {
2458 			if ((statefault == 0 ) && (force == 0)) {
2459 				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2460 					return 0;
2461 			}
2462 			statefault = 3;
2463 		}
2464 	}
2465 
2466 	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2467 	if (hard_reset_done < 0)
2468 		return -1;
2469 
2470 	/*
2471 	 *  Loop here waiting for IOC to come READY.
2472 	 */
2473 	ii = 0;
2474 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;	/* 5 seconds */
2475 
2476 	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2477 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2478 			/*
2479 			 *  BIOS or previous driver load left IOC in OP state.
2480 			 *  Reset messaging FIFOs.
2481 			 */
2482 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2483 				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2484 				return -2;
2485 			}
2486 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
2487 			/*
2488 			 *  Something is wrong.  Try to get IOC back
2489 			 *  to a known state.
2490 			 */
2491 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2492 				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2493 				return -3;
2494 			}
2495 		}
2496 
2497 		ii++; cntdn--;
2498 		if (!cntdn) {
2499 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2500 					ioc->name, (int)((ii+5)/HZ));
2501 			return -ETIME;
2502 		}
2503 
2504 		if (sleepFlag == CAN_SLEEP) {
2505 			msleep(1);
2506 		} else {
2507 			mdelay (1);	/* 1 msec delay */
2508 		}
2509 
2510 	}
2511 
2512 	if (statefault < 3) {
2513 		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2514 				ioc->name,
2515 				statefault==1 ? "stuck handshake" : "IOC FAULT");
2516 	}
2517 
2518 	return hard_reset_done;
2519 }
2520 
2521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2522 /**
2523  *	mpt_GetIocState - Get the current state of a MPT adapter.
2524  *	@ioc: Pointer to MPT_ADAPTER structure
2525  *	@cooked: Request raw or cooked IOC state
2526  *
2527  *	Returns all IOC Doorbell register bits if cooked==0, else just the
2528  *	Doorbell bits in MPI_IOC_STATE_MASK.
2529  */
2530 u32
2531 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2532 {
2533 	u32 s, sc;
2534 
2535 	/*  Get!  */
2536 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
2537 //	dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2538 	sc = s & MPI_IOC_STATE_MASK;
2539 
2540 	/*  Save!  */
2541 	ioc->last_state = sc;
2542 
2543 	return cooked ? sc : s;
2544 }
2545 
2546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2547 /**
2548  *	GetIocFacts - Send IOCFacts request to MPT adapter.
2549  *	@ioc: Pointer to MPT_ADAPTER structure
2550  *	@sleepFlag: Specifies whether the process can sleep
2551  *	@reason: If recovery, only update facts.
2552  *
2553  *	Returns 0 for success, non-zero for failure.
2554  */
2555 static int
2556 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2557 {
2558 	IOCFacts_t		 get_facts;
2559 	IOCFactsReply_t		*facts;
2560 	int			 r;
2561 	int			 req_sz;
2562 	int			 reply_sz;
2563 	int			 sz;
2564 	u32			 status, vv;
2565 	u8			 shiftFactor=1;
2566 
2567 	/* IOC *must* NOT be in RESET state! */
2568 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2569 		printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2570 				ioc->name,
2571 				ioc->last_state );
2572 		return -44;
2573 	}
2574 
2575 	facts = &ioc->facts;
2576 
2577 	/* Destination (reply area)... */
2578 	reply_sz = sizeof(*facts);
2579 	memset(facts, 0, reply_sz);
2580 
2581 	/* Request area (get_facts on the stack right now!) */
2582 	req_sz = sizeof(get_facts);
2583 	memset(&get_facts, 0, req_sz);
2584 
2585 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2586 	/* Assert: All other get_facts fields are zero! */
2587 
2588 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2589 	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2590 	    ioc->name, req_sz, reply_sz));
2591 
2592 	/* No non-zero fields in the get_facts request are greater than
2593 	 * 1 byte in size, so we can just fire it off as is.
2594 	 */
2595 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2596 			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2597 	if (r != 0)
2598 		return r;
2599 
2600 	/*
2601 	 * Now byte swap (GRRR) the necessary fields before any further
2602 	 * inspection of reply contents.
2603 	 *
2604 	 * But need to do some sanity checks on MsgLength (byte) field
2605 	 * to make sure we don't zero IOC's req_sz!
2606 	 */
2607 	/* Did we get a valid reply? */
2608 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2609 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2610 			/*
2611 			 * If not been here, done that, save off first WhoInit value
2612 			 */
2613 			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2614 				ioc->FirstWhoInit = facts->WhoInit;
2615 		}
2616 
2617 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2618 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
2619 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2620 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2621 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2622 		status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2623 		/* CHECKME! IOCStatus, IOCLogInfo */
2624 
2625 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2626 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2627 
2628 		/*
2629 		 * FC f/w version changed between 1.1 and 1.2
2630 		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
2631 		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2632 		 */
2633 		if (facts->MsgVersion < 0x0102) {
2634 			/*
2635 			 *	Handle old FC f/w style, convert to new...
2636 			 */
2637 			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2638 			facts->FWVersion.Word =
2639 					((oldv<<12) & 0xFF000000) |
2640 					((oldv<<8)  & 0x000FFF00);
2641 		} else
2642 			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2643 
2644 		facts->ProductID = le16_to_cpu(facts->ProductID);
2645 		if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2646 		    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2647 			ioc->ir_firmware = 1;
2648 		facts->CurrentHostMfaHighAddr =
2649 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
2650 		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2651 		facts->CurrentSenseBufferHighAddr =
2652 				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2653 		facts->CurReplyFrameSize =
2654 				le16_to_cpu(facts->CurReplyFrameSize);
2655 		facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2656 
2657 		/*
2658 		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2659 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2660 		 * to 14 in MPI-1.01.0x.
2661 		 */
2662 		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2663 		    facts->MsgVersion > 0x0100) {
2664 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2665 		}
2666 
2667 		sz = facts->FWImageSize;
2668 		if ( sz & 0x01 )
2669 			sz += 1;
2670 		if ( sz & 0x02 )
2671 			sz += 2;
2672 		facts->FWImageSize = sz;
2673 
2674 		if (!facts->RequestFrameSize) {
2675 			/*  Something is wrong!  */
2676 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2677 					ioc->name);
2678 			return -55;
2679 		}
2680 
2681 		r = sz = facts->BlockSize;
2682 		vv = ((63 / (sz * 4)) + 1) & 0x03;
2683 		ioc->NB_for_64_byte_frame = vv;
2684 		while ( sz )
2685 		{
2686 			shiftFactor++;
2687 			sz = sz >> 1;
2688 		}
2689 		ioc->NBShiftFactor  = shiftFactor;
2690 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2691 			"NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2692 			ioc->name, vv, shiftFactor, r));
2693 
2694 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2695 			/*
2696 			 * Set values for this IOC's request & reply frame sizes,
2697 			 * and request & reply queue depths...
2698 			 */
2699 			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2700 			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2701 			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2702 			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2703 
2704 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2705 				ioc->name, ioc->reply_sz, ioc->reply_depth));
2706 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
2707 				ioc->name, ioc->req_sz, ioc->req_depth));
2708 
2709 			/* Get port facts! */
2710 			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2711 				return r;
2712 		}
2713 	} else {
2714 		printk(MYIOC_s_ERR_FMT
2715 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2716 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2717 		     RequestFrameSize)/sizeof(u32)));
2718 		return -66;
2719 	}
2720 
2721 	return 0;
2722 }
2723 
2724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2725 /**
2726  *	GetPortFacts - Send PortFacts request to MPT adapter.
2727  *	@ioc: Pointer to MPT_ADAPTER structure
2728  *	@portnum: Port number
2729  *	@sleepFlag: Specifies whether the process can sleep
2730  *
2731  *	Returns 0 for success, non-zero for failure.
2732  */
2733 static int
2734 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2735 {
2736 	PortFacts_t		 get_pfacts;
2737 	PortFactsReply_t	*pfacts;
2738 	int			 ii;
2739 	int			 req_sz;
2740 	int			 reply_sz;
2741 	int			 max_id;
2742 
2743 	/* IOC *must* NOT be in RESET state! */
2744 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2745 		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2746 				ioc->name,
2747 				ioc->last_state );
2748 		return -4;
2749 	}
2750 
2751 	pfacts = &ioc->pfacts[portnum];
2752 
2753 	/* Destination (reply area)...  */
2754 	reply_sz = sizeof(*pfacts);
2755 	memset(pfacts, 0, reply_sz);
2756 
2757 	/* Request area (get_pfacts on the stack right now!) */
2758 	req_sz = sizeof(get_pfacts);
2759 	memset(&get_pfacts, 0, req_sz);
2760 
2761 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2762 	get_pfacts.PortNumber = portnum;
2763 	/* Assert: All other get_pfacts fields are zero! */
2764 
2765 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2766 			ioc->name, portnum));
2767 
2768 	/* No non-zero fields in the get_pfacts request are greater than
2769 	 * 1 byte in size, so we can just fire it off as is.
2770 	 */
2771 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2772 				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2773 	if (ii != 0)
2774 		return ii;
2775 
2776 	/* Did we get a valid reply? */
2777 
2778 	/* Now byte swap the necessary fields in the response. */
2779 	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2780 	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2781 	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2782 	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2783 	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2784 	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2785 	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2786 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2787 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2788 
2789 	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2790 	    pfacts->MaxDevices;
2791 	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2792 	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2793 
2794 	/*
2795 	 * Place all the devices on channels
2796 	 *
2797 	 * (for debuging)
2798 	 */
2799 	if (mpt_channel_mapping) {
2800 		ioc->devices_per_bus = 1;
2801 		ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2802 	}
2803 
2804 	return 0;
2805 }
2806 
2807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2808 /**
2809  *	SendIocInit - Send IOCInit request to MPT adapter.
2810  *	@ioc: Pointer to MPT_ADAPTER structure
2811  *	@sleepFlag: Specifies whether the process can sleep
2812  *
2813  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2814  *
2815  *	Returns 0 for success, non-zero for failure.
2816  */
2817 static int
2818 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2819 {
2820 	IOCInit_t		 ioc_init;
2821 	MPIDefaultReply_t	 init_reply;
2822 	u32			 state;
2823 	int			 r;
2824 	int			 count;
2825 	int			 cntdn;
2826 
2827 	memset(&ioc_init, 0, sizeof(ioc_init));
2828 	memset(&init_reply, 0, sizeof(init_reply));
2829 
2830 	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2831 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2832 
2833 	/* If we are in a recovery mode and we uploaded the FW image,
2834 	 * then this pointer is not NULL. Skip the upload a second time.
2835 	 * Set this flag if cached_fw set for either IOC.
2836 	 */
2837 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2838 		ioc->upload_fw = 1;
2839 	else
2840 		ioc->upload_fw = 0;
2841 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2842 		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
2843 
2844 	ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2845 	ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2846 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2847 		   ioc->name, ioc->facts.MsgVersion));
2848 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2849 		// set MsgVersion and HeaderVersion host driver was built with
2850 		ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2851 	        ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2852 
2853 		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2854 			ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2855 		} else if(mpt_host_page_alloc(ioc, &ioc_init))
2856 			return -99;
2857 	}
2858 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
2859 
2860 	if (sizeof(dma_addr_t) == sizeof(u64)) {
2861 		/* Save the upper 32-bits of the request
2862 		 * (reply) and sense buffers.
2863 		 */
2864 		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2865 		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2866 	} else {
2867 		/* Force 32-bit addressing */
2868 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2869 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2870 	}
2871 
2872 	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2873 	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2874 	ioc->facts.MaxDevices = ioc_init.MaxDevices;
2875 	ioc->facts.MaxBuses = ioc_init.MaxBuses;
2876 
2877 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2878 			ioc->name, &ioc_init));
2879 
2880 	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2881 				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2882 	if (r != 0) {
2883 		printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2884 		return r;
2885 	}
2886 
2887 	/* No need to byte swap the multibyte fields in the reply
2888 	 * since we don't even look at its contents.
2889 	 */
2890 
2891 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2892 			ioc->name, &ioc_init));
2893 
2894 	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2895 		printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2896 		return r;
2897 	}
2898 
2899 	/* YIKES!  SUPER IMPORTANT!!!
2900 	 *  Poll IocState until _OPERATIONAL while IOC is doing
2901 	 *  LoopInit and TargetDiscovery!
2902 	 */
2903 	count = 0;
2904 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
2905 	state = mpt_GetIocState(ioc, 1);
2906 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2907 		if (sleepFlag == CAN_SLEEP) {
2908 			msleep(1);
2909 		} else {
2910 			mdelay(1);
2911 		}
2912 
2913 		if (!cntdn) {
2914 			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2915 					ioc->name, (int)((count+5)/HZ));
2916 			return -9;
2917 		}
2918 
2919 		state = mpt_GetIocState(ioc, 1);
2920 		count++;
2921 	}
2922 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2923 			ioc->name, count));
2924 
2925 	ioc->aen_event_read_flag=0;
2926 	return r;
2927 }
2928 
2929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2930 /**
2931  *	SendPortEnable - Send PortEnable request to MPT adapter port.
2932  *	@ioc: Pointer to MPT_ADAPTER structure
2933  *	@portnum: Port number to enable
2934  *	@sleepFlag: Specifies whether the process can sleep
2935  *
2936  *	Send PortEnable to bring IOC to OPERATIONAL state.
2937  *
2938  *	Returns 0 for success, non-zero for failure.
2939  */
2940 static int
2941 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2942 {
2943 	PortEnable_t		 port_enable;
2944 	MPIDefaultReply_t	 reply_buf;
2945 	int	 rc;
2946 	int	 req_sz;
2947 	int	 reply_sz;
2948 
2949 	/*  Destination...  */
2950 	reply_sz = sizeof(MPIDefaultReply_t);
2951 	memset(&reply_buf, 0, reply_sz);
2952 
2953 	req_sz = sizeof(PortEnable_t);
2954 	memset(&port_enable, 0, req_sz);
2955 
2956 	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2957 	port_enable.PortNumber = portnum;
2958 /*	port_enable.ChainOffset = 0;		*/
2959 /*	port_enable.MsgFlags = 0;		*/
2960 /*	port_enable.MsgContext = 0;		*/
2961 
2962 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
2963 			ioc->name, portnum, &port_enable));
2964 
2965 	/* RAID FW may take a long time to enable
2966 	 */
2967 	if (ioc->ir_firmware || ioc->bus_type == SAS) {
2968 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2969 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2970 		300 /*seconds*/, sleepFlag);
2971 	} else {
2972 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2973 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2974 		30 /*seconds*/, sleepFlag);
2975 	}
2976 	return rc;
2977 }
2978 
2979 /**
2980  *	mpt_alloc_fw_memory - allocate firmware memory
2981  *	@ioc: Pointer to MPT_ADAPTER structure
2982  *      @size: total FW bytes
2983  *
2984  *	If memory has already been allocated, the same (cached) value
2985  *	is returned.
2986  */
2987 void
2988 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2989 {
2990 	if (ioc->cached_fw)
2991 		return;  /* use already allocated memory */
2992 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2993 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2994 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2995 		ioc->alloc_total += size;
2996 		ioc->alt_ioc->alloc_total -= size;
2997 	} else {
2998 		if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2999 			ioc->alloc_total += size;
3000 	}
3001 }
3002 /**
3003  *	mpt_free_fw_memory - free firmware memory
3004  *	@ioc: Pointer to MPT_ADAPTER structure
3005  *
3006  *	If alt_img is NULL, delete from ioc structure.
3007  *	Else, delete a secondary image in same format.
3008  */
3009 void
3010 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3011 {
3012 	int sz;
3013 
3014 	sz = ioc->facts.FWImageSize;
3015 	dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3016 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3017 	pci_free_consistent(ioc->pcidev, sz,
3018 			ioc->cached_fw, ioc->cached_fw_dma);
3019 	ioc->cached_fw = NULL;
3020 
3021 	return;
3022 }
3023 
3024 
3025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3026 /**
3027  *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3028  *	@ioc: Pointer to MPT_ADAPTER structure
3029  *	@sleepFlag: Specifies whether the process can sleep
3030  *
3031  *	Returns 0 for success, >0 for handshake failure
3032  *		<0 for fw upload failure.
3033  *
3034  *	Remark: If bound IOC and a successful FWUpload was performed
3035  *	on the bound IOC, the second image is discarded
3036  *	and memory is free'd. Both channels must upload to prevent
3037  *	IOC from running in degraded mode.
3038  */
3039 static int
3040 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3041 {
3042 	u8			 request[ioc->req_sz];
3043 	u8			 reply[sizeof(FWUploadReply_t)];
3044 	FWUpload_t		*prequest;
3045 	FWUploadReply_t		*preply;
3046 	FWUploadTCSGE_t		*ptcsge;
3047 	int			 sgeoffset;
3048 	u32			 flagsLength;
3049 	int			 ii, sz, reply_sz;
3050 	int			 cmdStatus;
3051 
3052 	/* If the image size is 0, we are done.
3053 	 */
3054 	if ((sz = ioc->facts.FWImageSize) == 0)
3055 		return 0;
3056 
3057 	mpt_alloc_fw_memory(ioc, sz);
3058 
3059 	dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3060 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3061 
3062 	if (ioc->cached_fw == NULL) {
3063 		/* Major Failure.
3064 		 */
3065 		return -ENOMEM;
3066 	}
3067 
3068 	prequest = (FWUpload_t *)&request;
3069 	preply = (FWUploadReply_t *)&reply;
3070 
3071 	/*  Destination...  */
3072 	memset(prequest, 0, ioc->req_sz);
3073 
3074 	reply_sz = sizeof(reply);
3075 	memset(preply, 0, reply_sz);
3076 
3077 	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3078 	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3079 
3080 	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3081 	ptcsge->DetailsLength = 12;
3082 	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3083 	ptcsge->ImageSize = cpu_to_le32(sz);
3084 
3085 	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3086 
3087 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3088 	mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3089 
3090 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3091 	dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3092 			prequest, sgeoffset));
3093 	DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest)
3094 
3095 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3096 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3097 
3098 	dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3099 
3100 	cmdStatus = -EFAULT;
3101 	if (ii == 0) {
3102 		/* Handshake transfer was complete and successful.
3103 		 * Check the Reply Frame.
3104 		 */
3105 		int status, transfer_sz;
3106 		status = le16_to_cpu(preply->IOCStatus);
3107 		if (status == MPI_IOCSTATUS_SUCCESS) {
3108 			transfer_sz = le32_to_cpu(preply->ActualImageSize);
3109 			if (transfer_sz == sz)
3110 				cmdStatus = 0;
3111 		}
3112 	}
3113 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3114 			ioc->name, cmdStatus));
3115 
3116 
3117 	if (cmdStatus) {
3118 
3119 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3120 			ioc->name));
3121 		mpt_free_fw_memory(ioc);
3122 	}
3123 
3124 	return cmdStatus;
3125 }
3126 
3127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3128 /**
3129  *	mpt_downloadboot - DownloadBoot code
3130  *	@ioc: Pointer to MPT_ADAPTER structure
3131  *	@pFwHeader: Pointer to firmware header info
3132  *	@sleepFlag: Specifies whether the process can sleep
3133  *
3134  *	FwDownloadBoot requires Programmed IO access.
3135  *
3136  *	Returns 0 for success
3137  *		-1 FW Image size is 0
3138  *		-2 No valid cached_fw Pointer
3139  *		<0 for fw upload failure.
3140  */
3141 static int
3142 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3143 {
3144 	MpiExtImageHeader_t	*pExtImage;
3145 	u32			 fwSize;
3146 	u32			 diag0val;
3147 	int			 count;
3148 	u32			*ptrFw;
3149 	u32			 diagRwData;
3150 	u32			 nextImage;
3151 	u32			 load_addr;
3152 	u32 			 ioc_state=0;
3153 
3154 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3155 				ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3156 
3157 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3158 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3159 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3160 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3161 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3162 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3163 
3164 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3165 
3166 	/* wait 1 msec */
3167 	if (sleepFlag == CAN_SLEEP) {
3168 		msleep(1);
3169 	} else {
3170 		mdelay (1);
3171 	}
3172 
3173 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3174 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3175 
3176 	for (count = 0; count < 30; count ++) {
3177 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3178 		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3179 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3180 				ioc->name, count));
3181 			break;
3182 		}
3183 		/* wait .1 sec */
3184 		if (sleepFlag == CAN_SLEEP) {
3185 			msleep (100);
3186 		} else {
3187 			mdelay (100);
3188 		}
3189 	}
3190 
3191 	if ( count == 30 ) {
3192 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3193 		"Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3194 		ioc->name, diag0val));
3195 		return -3;
3196 	}
3197 
3198 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3199 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3200 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3201 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3202 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3203 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3204 
3205 	/* Set the DiagRwEn and Disable ARM bits */
3206 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3207 
3208 	fwSize = (pFwHeader->ImageSize + 3)/4;
3209 	ptrFw = (u32 *) pFwHeader;
3210 
3211 	/* Write the LoadStartAddress to the DiagRw Address Register
3212 	 * using Programmed IO
3213 	 */
3214 	if (ioc->errata_flag_1064)
3215 		pci_enable_io_access(ioc->pcidev);
3216 
3217 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3218 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3219 		ioc->name, pFwHeader->LoadStartAddress));
3220 
3221 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3222 				ioc->name, fwSize*4, ptrFw));
3223 	while (fwSize--) {
3224 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3225 	}
3226 
3227 	nextImage = pFwHeader->NextImageHeaderOffset;
3228 	while (nextImage) {
3229 		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3230 
3231 		load_addr = pExtImage->LoadStartAddress;
3232 
3233 		fwSize = (pExtImage->ImageSize + 3) >> 2;
3234 		ptrFw = (u32 *)pExtImage;
3235 
3236 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3237 						ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3238 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3239 
3240 		while (fwSize--) {
3241 			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3242 		}
3243 		nextImage = pExtImage->NextImageHeaderOffset;
3244 	}
3245 
3246 	/* Write the IopResetVectorRegAddr */
3247 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
3248 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3249 
3250 	/* Write the IopResetVectorValue */
3251 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3252 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3253 
3254 	/* Clear the internal flash bad bit - autoincrementing register,
3255 	 * so must do two writes.
3256 	 */
3257 	if (ioc->bus_type == SPI) {
3258 		/*
3259 		 * 1030 and 1035 H/W errata, workaround to access
3260 		 * the ClearFlashBadSignatureBit
3261 		 */
3262 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3263 		diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3264 		diagRwData |= 0x40000000;
3265 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3266 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3267 
3268 	} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3269 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3270 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3271 		    MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3272 
3273 		/* wait 1 msec */
3274 		if (sleepFlag == CAN_SLEEP) {
3275 			msleep (1);
3276 		} else {
3277 			mdelay (1);
3278 		}
3279 	}
3280 
3281 	if (ioc->errata_flag_1064)
3282 		pci_disable_io_access(ioc->pcidev);
3283 
3284 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3285 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3286 		"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3287 		ioc->name, diag0val));
3288 	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3289 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3290 		ioc->name, diag0val));
3291 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3292 
3293 	/* Write 0xFF to reset the sequencer */
3294 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3295 
3296 	if (ioc->bus_type == SAS) {
3297 		ioc_state = mpt_GetIocState(ioc, 0);
3298 		if ( (GetIocFacts(ioc, sleepFlag,
3299 				MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3300 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3301 					ioc->name, ioc_state));
3302 			return -EFAULT;
3303 		}
3304 	}
3305 
3306 	for (count=0; count<HZ*20; count++) {
3307 		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3308 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3309 				"downloadboot successful! (count=%d) IocState=%x\n",
3310 				ioc->name, count, ioc_state));
3311 			if (ioc->bus_type == SAS) {
3312 				return 0;
3313 			}
3314 			if ((SendIocInit(ioc, sleepFlag)) != 0) {
3315 				ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3316 					"downloadboot: SendIocInit failed\n",
3317 					ioc->name));
3318 				return -EFAULT;
3319 			}
3320 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3321 					"downloadboot: SendIocInit successful\n",
3322 					ioc->name));
3323 			return 0;
3324 		}
3325 		if (sleepFlag == CAN_SLEEP) {
3326 			msleep (10);
3327 		} else {
3328 			mdelay (10);
3329 		}
3330 	}
3331 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3332 		"downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3333 	return -EFAULT;
3334 }
3335 
3336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3337 /**
3338  *	KickStart - Perform hard reset of MPT adapter.
3339  *	@ioc: Pointer to MPT_ADAPTER structure
3340  *	@force: Force hard reset
3341  *	@sleepFlag: Specifies whether the process can sleep
3342  *
3343  *	This routine places MPT adapter in diagnostic mode via the
3344  *	WriteSequence register, and then performs a hard reset of adapter
3345  *	via the Diagnostic register.
3346  *
3347  *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3348  *			or NO_SLEEP (interrupt thread, use mdelay)
3349  *		  force - 1 if doorbell active, board fault state
3350  *				board operational, IOC_RECOVERY or
3351  *				IOC_BRINGUP and there is an alt_ioc.
3352  *			  0 else
3353  *
3354  *	Returns:
3355  *		 1 - hard reset, READY
3356  *		 0 - no reset due to History bit, READY
3357  *		-1 - no reset due to History bit but not READY
3358  *		     OR reset but failed to come READY
3359  *		-2 - no reset, could not enter DIAG mode
3360  *		-3 - reset but bad FW bit
3361  */
3362 static int
3363 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3364 {
3365 	int hard_reset_done = 0;
3366 	u32 ioc_state=0;
3367 	int cnt,cntdn;
3368 
3369 	dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3370 	if (ioc->bus_type == SPI) {
3371 		/* Always issue a Msg Unit Reset first. This will clear some
3372 		 * SCSI bus hang conditions.
3373 		 */
3374 		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3375 
3376 		if (sleepFlag == CAN_SLEEP) {
3377 			msleep (1000);
3378 		} else {
3379 			mdelay (1000);
3380 		}
3381 	}
3382 
3383 	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3384 	if (hard_reset_done < 0)
3385 		return hard_reset_done;
3386 
3387 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3388 			ioc->name));
3389 
3390 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;	/* 2 seconds */
3391 	for (cnt=0; cnt<cntdn; cnt++) {
3392 		ioc_state = mpt_GetIocState(ioc, 1);
3393 		if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3394 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3395  					ioc->name, cnt));
3396 			return hard_reset_done;
3397 		}
3398 		if (sleepFlag == CAN_SLEEP) {
3399 			msleep (10);
3400 		} else {
3401 			mdelay (10);
3402 		}
3403 	}
3404 
3405 	printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3406 			ioc->name, ioc_state);
3407 	return -1;
3408 }
3409 
3410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3411 /**
3412  *	mpt_diag_reset - Perform hard reset of the adapter.
3413  *	@ioc: Pointer to MPT_ADAPTER structure
3414  *	@ignore: Set if to honor and clear to ignore
3415  *		the reset history bit
3416  *	@sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3417  *		else set to NO_SLEEP (use mdelay instead)
3418  *
3419  *	This routine places the adapter in diagnostic mode via the
3420  *	WriteSequence register and then performs a hard reset of adapter
3421  *	via the Diagnostic register. Adapter should be in ready state
3422  *	upon successful completion.
3423  *
3424  *	Returns:  1  hard reset successful
3425  *		  0  no reset performed because reset history bit set
3426  *		 -2  enabling diagnostic mode failed
3427  *		 -3  diagnostic reset failed
3428  */
3429 static int
3430 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3431 {
3432 	MPT_ADAPTER	*iocp=NULL;
3433 	u32 diag0val;
3434 	u32 doorbell;
3435 	int hard_reset_done = 0;
3436 	int count = 0;
3437 	u32 diag1val = 0;
3438 
3439 	/* Clear any existing interrupts */
3440 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3441 
3442 	if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3443 		drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3444 			"address=%p\n",  ioc->name, __FUNCTION__,
3445 			&ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3446 		CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3447 		if (sleepFlag == CAN_SLEEP)
3448 			msleep(1);
3449 		else
3450 			mdelay(1);
3451 
3452 		for (count = 0; count < 60; count ++) {
3453 			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3454 			doorbell &= MPI_IOC_STATE_MASK;
3455 
3456 			drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3457 				"looking for READY STATE: doorbell=%x"
3458 			        " count=%d\n",
3459 				ioc->name, doorbell, count));
3460 			if (doorbell == MPI_IOC_STATE_READY) {
3461 				return 1;
3462 			}
3463 
3464 			/* wait 1 sec */
3465 			if (sleepFlag == CAN_SLEEP)
3466 				msleep(1000);
3467 			else
3468 				mdelay(1000);
3469 		}
3470 		return -1;
3471 	}
3472 
3473 	/* Use "Diagnostic reset" method! (only thing available!) */
3474 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3475 
3476 	if (ioc->debug_level & MPT_DEBUG) {
3477 		if (ioc->alt_ioc)
3478 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3479 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3480 			ioc->name, diag0val, diag1val));
3481 	}
3482 
3483 	/* Do the reset if we are told to ignore the reset history
3484 	 * or if the reset history is 0
3485 	 */
3486 	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3487 		while ((diag0val & MPI_DIAG_DRWE) == 0) {
3488 			/* Write magic sequence to WriteSequence register
3489 			 * Loop until in diagnostic mode
3490 			 */
3491 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3492 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3493 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3494 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3495 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3496 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3497 
3498 			/* wait 100 msec */
3499 			if (sleepFlag == CAN_SLEEP) {
3500 				msleep (100);
3501 			} else {
3502 				mdelay (100);
3503 			}
3504 
3505 			count++;
3506 			if (count > 20) {
3507 				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3508 						ioc->name, diag0val);
3509 				return -2;
3510 
3511 			}
3512 
3513 			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3514 
3515 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3516 					ioc->name, diag0val));
3517 		}
3518 
3519 		if (ioc->debug_level & MPT_DEBUG) {
3520 			if (ioc->alt_ioc)
3521 				diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3522 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3523 				ioc->name, diag0val, diag1val));
3524 		}
3525 		/*
3526 		 * Disable the ARM (Bug fix)
3527 		 *
3528 		 */
3529 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3530 		mdelay(1);
3531 
3532 		/*
3533 		 * Now hit the reset bit in the Diagnostic register
3534 		 * (THE BIG HAMMER!) (Clears DRWE bit).
3535 		 */
3536 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3537 		hard_reset_done = 1;
3538 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3539 				ioc->name));
3540 
3541 		/*
3542 		 * Call each currently registered protocol IOC reset handler
3543 		 * with pre-reset indication.
3544 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3545 		 * MptResetHandlers[] registered yet.
3546 		 */
3547 		{
3548 			int	 ii;
3549 			int	 r = 0;
3550 
3551 			for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3552 				if (MptResetHandlers[ii]) {
3553 					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3554 						"Calling IOC pre_reset handler #%d\n",
3555 						ioc->name, ii));
3556 					r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3557 					if (ioc->alt_ioc) {
3558 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3559 							"Calling alt-%s pre_reset handler #%d\n",
3560 							ioc->name, ioc->alt_ioc->name, ii));
3561 						r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3562 					}
3563 				}
3564 			}
3565 			/* FIXME?  Examine results here? */
3566 		}
3567 
3568 		if (ioc->cached_fw)
3569 			iocp = ioc;
3570 		else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3571 			iocp = ioc->alt_ioc;
3572 		if (iocp) {
3573 			/* If the DownloadBoot operation fails, the
3574 			 * IOC will be left unusable. This is a fatal error
3575 			 * case.  _diag_reset will return < 0
3576 			 */
3577 			for (count = 0; count < 30; count ++) {
3578 				diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3579 				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3580 					break;
3581 				}
3582 
3583 				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3584 					iocp->name, diag0val, count));
3585 				/* wait 1 sec */
3586 				if (sleepFlag == CAN_SLEEP) {
3587 					msleep (1000);
3588 				} else {
3589 					mdelay (1000);
3590 				}
3591 			}
3592 			if ((count = mpt_downloadboot(ioc,
3593 				(MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3594 				printk(KERN_WARNING MYNAM
3595 					": firmware downloadboot failure (%d)!\n", count);
3596 			}
3597 
3598 		} else {
3599 			/* Wait for FW to reload and for board
3600 			 * to go to the READY state.
3601 			 * Maximum wait is 60 seconds.
3602 			 * If fail, no error will check again
3603 			 * with calling program.
3604 			 */
3605 			for (count = 0; count < 60; count ++) {
3606 				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3607 				doorbell &= MPI_IOC_STATE_MASK;
3608 
3609 				if (doorbell == MPI_IOC_STATE_READY) {
3610 					break;
3611 				}
3612 
3613 				/* wait 1 sec */
3614 				if (sleepFlag == CAN_SLEEP) {
3615 					msleep (1000);
3616 				} else {
3617 					mdelay (1000);
3618 				}
3619 			}
3620 		}
3621 	}
3622 
3623 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3624 	if (ioc->debug_level & MPT_DEBUG) {
3625 		if (ioc->alt_ioc)
3626 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3627 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3628 			ioc->name, diag0val, diag1val));
3629 	}
3630 
3631 	/* Clear RESET_HISTORY bit!  Place board in the
3632 	 * diagnostic mode to update the diag register.
3633 	 */
3634 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3635 	count = 0;
3636 	while ((diag0val & MPI_DIAG_DRWE) == 0) {
3637 		/* Write magic sequence to WriteSequence register
3638 		 * Loop until in diagnostic mode
3639 		 */
3640 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3641 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3642 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3643 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3644 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3645 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3646 
3647 		/* wait 100 msec */
3648 		if (sleepFlag == CAN_SLEEP) {
3649 			msleep (100);
3650 		} else {
3651 			mdelay (100);
3652 		}
3653 
3654 		count++;
3655 		if (count > 20) {
3656 			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3657 					ioc->name, diag0val);
3658 			break;
3659 		}
3660 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3661 	}
3662 	diag0val &= ~MPI_DIAG_RESET_HISTORY;
3663 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3664 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3665 	if (diag0val & MPI_DIAG_RESET_HISTORY) {
3666 		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3667 				ioc->name);
3668 	}
3669 
3670 	/* Disable Diagnostic Mode
3671 	 */
3672 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3673 
3674 	/* Check FW reload status flags.
3675 	 */
3676 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3677 	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3678 		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3679 				ioc->name, diag0val);
3680 		return -3;
3681 	}
3682 
3683 	if (ioc->debug_level & MPT_DEBUG) {
3684 		if (ioc->alt_ioc)
3685 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3686 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3687 			ioc->name, diag0val, diag1val));
3688 	}
3689 
3690 	/*
3691 	 * Reset flag that says we've enabled event notification
3692 	 */
3693 	ioc->facts.EventState = 0;
3694 
3695 	if (ioc->alt_ioc)
3696 		ioc->alt_ioc->facts.EventState = 0;
3697 
3698 	return hard_reset_done;
3699 }
3700 
3701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3702 /**
3703  *	SendIocReset - Send IOCReset request to MPT adapter.
3704  *	@ioc: Pointer to MPT_ADAPTER structure
3705  *	@reset_type: reset type, expected values are
3706  *	%MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3707  *	@sleepFlag: Specifies whether the process can sleep
3708  *
3709  *	Send IOCReset request to the MPT adapter.
3710  *
3711  *	Returns 0 for success, non-zero for failure.
3712  */
3713 static int
3714 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3715 {
3716 	int r;
3717 	u32 state;
3718 	int cntdn, count;
3719 
3720 	drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3721 			ioc->name, reset_type));
3722 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3723 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3724 		return r;
3725 
3726 	/* FW ACK'd request, wait for READY state
3727 	 */
3728 	count = 0;
3729 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
3730 
3731 	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3732 		cntdn--;
3733 		count++;
3734 		if (!cntdn) {
3735 			if (sleepFlag != CAN_SLEEP)
3736 				count *= 10;
3737 
3738 			printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3739 					ioc->name, (int)((count+5)/HZ));
3740 			return -ETIME;
3741 		}
3742 
3743 		if (sleepFlag == CAN_SLEEP) {
3744 			msleep(1);
3745 		} else {
3746 			mdelay (1);	/* 1 msec delay */
3747 		}
3748 	}
3749 
3750 	/* TODO!
3751 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
3752 	 *  request if needed.
3753 	 */
3754 	if (ioc->facts.Function)
3755 		ioc->facts.EventState = 0;
3756 
3757 	return 0;
3758 }
3759 
3760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3761 /**
3762  *	initChainBuffers - Allocate memory for and initialize chain buffers
3763  *	@ioc: Pointer to MPT_ADAPTER structure
3764  *
3765  *	Allocates memory for and initializes chain buffers,
3766  *	chain buffer control arrays and spinlock.
3767  */
3768 static int
3769 initChainBuffers(MPT_ADAPTER *ioc)
3770 {
3771 	u8		*mem;
3772 	int		sz, ii, num_chain;
3773 	int 		scale, num_sge, numSGE;
3774 
3775 	/* ReqToChain size must equal the req_depth
3776 	 * index = req_idx
3777 	 */
3778 	if (ioc->ReqToChain == NULL) {
3779 		sz = ioc->req_depth * sizeof(int);
3780 		mem = kmalloc(sz, GFP_ATOMIC);
3781 		if (mem == NULL)
3782 			return -1;
3783 
3784 		ioc->ReqToChain = (int *) mem;
3785 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
3786 			 	ioc->name, mem, sz));
3787 		mem = kmalloc(sz, GFP_ATOMIC);
3788 		if (mem == NULL)
3789 			return -1;
3790 
3791 		ioc->RequestNB = (int *) mem;
3792 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
3793 			 	ioc->name, mem, sz));
3794 	}
3795 	for (ii = 0; ii < ioc->req_depth; ii++) {
3796 		ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3797 	}
3798 
3799 	/* ChainToChain size must equal the total number
3800 	 * of chain buffers to be allocated.
3801 	 * index = chain_idx
3802 	 *
3803 	 * Calculate the number of chain buffers needed(plus 1) per I/O
3804 	 * then multiply the maximum number of simultaneous cmds
3805 	 *
3806 	 * num_sge = num sge in request frame + last chain buffer
3807 	 * scale = num sge per chain buffer if no chain element
3808 	 */
3809 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3810 	if (sizeof(dma_addr_t) == sizeof(u64))
3811 		num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3812 	else
3813 		num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3814 
3815 	if (sizeof(dma_addr_t) == sizeof(u64)) {
3816 		numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3817 			(ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3818 	} else {
3819 		numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3820 			(ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3821 	}
3822 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3823 		ioc->name, num_sge, numSGE));
3824 
3825 	if ( numSGE > MPT_SCSI_SG_DEPTH	)
3826 		numSGE = MPT_SCSI_SG_DEPTH;
3827 
3828 	num_chain = 1;
3829 	while (numSGE - num_sge > 0) {
3830 		num_chain++;
3831 		num_sge += (scale - 1);
3832 	}
3833 	num_chain++;
3834 
3835 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3836 		ioc->name, numSGE, num_sge, num_chain));
3837 
3838 	if (ioc->bus_type == SPI)
3839 		num_chain *= MPT_SCSI_CAN_QUEUE;
3840 	else
3841 		num_chain *= MPT_FC_CAN_QUEUE;
3842 
3843 	ioc->num_chain = num_chain;
3844 
3845 	sz = num_chain * sizeof(int);
3846 	if (ioc->ChainToChain == NULL) {
3847 		mem = kmalloc(sz, GFP_ATOMIC);
3848 		if (mem == NULL)
3849 			return -1;
3850 
3851 		ioc->ChainToChain = (int *) mem;
3852 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3853 			 	ioc->name, mem, sz));
3854 	} else {
3855 		mem = (u8 *) ioc->ChainToChain;
3856 	}
3857 	memset(mem, 0xFF, sz);
3858 	return num_chain;
3859 }
3860 
3861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3862 /**
3863  *	PrimeIocFifos - Initialize IOC request and reply FIFOs.
3864  *	@ioc: Pointer to MPT_ADAPTER structure
3865  *
3866  *	This routine allocates memory for the MPT reply and request frame
3867  *	pools (if necessary), and primes the IOC reply FIFO with
3868  *	reply frames.
3869  *
3870  *	Returns 0 for success, non-zero for failure.
3871  */
3872 static int
3873 PrimeIocFifos(MPT_ADAPTER *ioc)
3874 {
3875 	MPT_FRAME_HDR *mf;
3876 	unsigned long flags;
3877 	dma_addr_t alloc_dma;
3878 	u8 *mem;
3879 	int i, reply_sz, sz, total_size, num_chain;
3880 
3881 	/*  Prime reply FIFO...  */
3882 
3883 	if (ioc->reply_frames == NULL) {
3884 		if ( (num_chain = initChainBuffers(ioc)) < 0)
3885 			return -1;
3886 
3887 		total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3888 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3889 			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
3890 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3891 			 	ioc->name, reply_sz, reply_sz));
3892 
3893 		sz = (ioc->req_sz * ioc->req_depth);
3894 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3895 			 	ioc->name, ioc->req_sz, ioc->req_depth));
3896 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3897 			 	ioc->name, sz, sz));
3898 		total_size += sz;
3899 
3900 		sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3901 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3902 			 	ioc->name, ioc->req_sz, num_chain));
3903 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3904 			 	ioc->name, sz, sz, num_chain));
3905 
3906 		total_size += sz;
3907 		mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3908 		if (mem == NULL) {
3909 			printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3910 				ioc->name);
3911 			goto out_fail;
3912 		}
3913 
3914 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3915 			 	ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3916 
3917 		memset(mem, 0, total_size);
3918 		ioc->alloc_total += total_size;
3919 		ioc->alloc = mem;
3920 		ioc->alloc_dma = alloc_dma;
3921 		ioc->alloc_sz = total_size;
3922 		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3923 		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3924 
3925 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3926 	 		ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3927 
3928 		alloc_dma += reply_sz;
3929 		mem += reply_sz;
3930 
3931 		/*  Request FIFO - WE manage this!  */
3932 
3933 		ioc->req_frames = (MPT_FRAME_HDR *) mem;
3934 		ioc->req_frames_dma = alloc_dma;
3935 
3936 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
3937 			 	ioc->name, mem, (void *)(ulong)alloc_dma));
3938 
3939 		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3940 
3941 #if defined(CONFIG_MTRR) && 0
3942 		/*
3943 		 *  Enable Write Combining MTRR for IOC's memory region.
3944 		 *  (at least as much as we can; "size and base must be
3945 		 *  multiples of 4 kiB"
3946 		 */
3947 		ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3948 					 sz,
3949 					 MTRR_TYPE_WRCOMB, 1);
3950 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
3951 				ioc->name, ioc->req_frames_dma, sz));
3952 #endif
3953 
3954 		for (i = 0; i < ioc->req_depth; i++) {
3955 			alloc_dma += ioc->req_sz;
3956 			mem += ioc->req_sz;
3957 		}
3958 
3959 		ioc->ChainBuffer = mem;
3960 		ioc->ChainBufferDMA = alloc_dma;
3961 
3962 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
3963 			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3964 
3965 		/* Initialize the free chain Q.
3966 	 	*/
3967 
3968 		INIT_LIST_HEAD(&ioc->FreeChainQ);
3969 
3970 		/* Post the chain buffers to the FreeChainQ.
3971 	 	*/
3972 		mem = (u8 *)ioc->ChainBuffer;
3973 		for (i=0; i < num_chain; i++) {
3974 			mf = (MPT_FRAME_HDR *) mem;
3975 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3976 			mem += ioc->req_sz;
3977 		}
3978 
3979 		/* Initialize Request frames linked list
3980 		 */
3981 		alloc_dma = ioc->req_frames_dma;
3982 		mem = (u8 *) ioc->req_frames;
3983 
3984 		spin_lock_irqsave(&ioc->FreeQlock, flags);
3985 		INIT_LIST_HEAD(&ioc->FreeQ);
3986 		for (i = 0; i < ioc->req_depth; i++) {
3987 			mf = (MPT_FRAME_HDR *) mem;
3988 
3989 			/*  Queue REQUESTs *internally*!  */
3990 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3991 
3992 			mem += ioc->req_sz;
3993 		}
3994 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3995 
3996 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3997 		ioc->sense_buf_pool =
3998 			pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3999 		if (ioc->sense_buf_pool == NULL) {
4000 			printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4001 				ioc->name);
4002 			goto out_fail;
4003 		}
4004 
4005 		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4006 		ioc->alloc_total += sz;
4007 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4008  			ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4009 
4010 	}
4011 
4012 	/* Post Reply frames to FIFO
4013 	 */
4014 	alloc_dma = ioc->alloc_dma;
4015 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4016 	 	ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4017 
4018 	for (i = 0; i < ioc->reply_depth; i++) {
4019 		/*  Write each address to the IOC!  */
4020 		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4021 		alloc_dma += ioc->reply_sz;
4022 	}
4023 
4024 	return 0;
4025 
4026 out_fail:
4027 	if (ioc->alloc != NULL) {
4028 		sz = ioc->alloc_sz;
4029 		pci_free_consistent(ioc->pcidev,
4030 				sz,
4031 				ioc->alloc, ioc->alloc_dma);
4032 		ioc->reply_frames = NULL;
4033 		ioc->req_frames = NULL;
4034 		ioc->alloc_total -= sz;
4035 	}
4036 	if (ioc->sense_buf_pool != NULL) {
4037 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4038 		pci_free_consistent(ioc->pcidev,
4039 				sz,
4040 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4041 		ioc->sense_buf_pool = NULL;
4042 	}
4043 	return -1;
4044 }
4045 
4046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4047 /**
4048  *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4049  *	from IOC via doorbell handshake method.
4050  *	@ioc: Pointer to MPT_ADAPTER structure
4051  *	@reqBytes: Size of the request in bytes
4052  *	@req: Pointer to MPT request frame
4053  *	@replyBytes: Expected size of the reply in bytes
4054  *	@u16reply: Pointer to area where reply should be written
4055  *	@maxwait: Max wait time for a reply (in seconds)
4056  *	@sleepFlag: Specifies whether the process can sleep
4057  *
4058  *	NOTES: It is the callers responsibility to byte-swap fields in the
4059  *	request which are greater than 1 byte in size.  It is also the
4060  *	callers responsibility to byte-swap response fields which are
4061  *	greater than 1 byte in size.
4062  *
4063  *	Returns 0 for success, non-zero for failure.
4064  */
4065 static int
4066 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4067 		int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4068 {
4069 	MPIDefaultReply_t *mptReply;
4070 	int failcnt = 0;
4071 	int t;
4072 
4073 	/*
4074 	 * Get ready to cache a handshake reply
4075 	 */
4076 	ioc->hs_reply_idx = 0;
4077 	mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4078 	mptReply->MsgLength = 0;
4079 
4080 	/*
4081 	 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4082 	 * then tell IOC that we want to handshake a request of N words.
4083 	 * (WRITE u32val to Doorbell reg).
4084 	 */
4085 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4086 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
4087 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4088 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4089 
4090 	/*
4091 	 * Wait for IOC's doorbell handshake int
4092 	 */
4093 	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4094 		failcnt++;
4095 
4096 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4097 			ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4098 
4099 	/* Read doorbell and check for active bit */
4100 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4101 			return -1;
4102 
4103 	/*
4104 	 * Clear doorbell int (WRITE 0 to IntStatus reg),
4105 	 * then wait for IOC to ACKnowledge that it's ready for
4106 	 * our handshake request.
4107 	 */
4108 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4109 	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4110 		failcnt++;
4111 
4112 	if (!failcnt) {
4113 		int	 ii;
4114 		u8	*req_as_bytes = (u8 *) req;
4115 
4116 		/*
4117 		 * Stuff request words via doorbell handshake,
4118 		 * with ACK from IOC for each.
4119 		 */
4120 		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4121 			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4122 				    (req_as_bytes[(ii*4) + 1] <<  8) |
4123 				    (req_as_bytes[(ii*4) + 2] << 16) |
4124 				    (req_as_bytes[(ii*4) + 3] << 24));
4125 
4126 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4127 			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4128 				failcnt++;
4129 		}
4130 
4131 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4132 		DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req)
4133 
4134 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4135 				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4136 
4137 		/*
4138 		 * Wait for completion of doorbell handshake reply from the IOC
4139 		 */
4140 		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4141 			failcnt++;
4142 
4143 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4144 				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4145 
4146 		/*
4147 		 * Copy out the cached reply...
4148 		 */
4149 		for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4150 			u16reply[ii] = ioc->hs_reply[ii];
4151 	} else {
4152 		return -99;
4153 	}
4154 
4155 	return -failcnt;
4156 }
4157 
4158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4159 /**
4160  *	WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4161  *	@ioc: Pointer to MPT_ADAPTER structure
4162  *	@howlong: How long to wait (in seconds)
4163  *	@sleepFlag: Specifies whether the process can sleep
4164  *
4165  *	This routine waits (up to ~2 seconds max) for IOC doorbell
4166  *	handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4167  *	bit in its IntStatus register being clear.
4168  *
4169  *	Returns a negative value on failure, else wait loop count.
4170  */
4171 static int
4172 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4173 {
4174 	int cntdn;
4175 	int count = 0;
4176 	u32 intstat=0;
4177 
4178 	cntdn = 1000 * howlong;
4179 
4180 	if (sleepFlag == CAN_SLEEP) {
4181 		while (--cntdn) {
4182 			msleep (1);
4183 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4184 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4185 				break;
4186 			count++;
4187 		}
4188 	} else {
4189 		while (--cntdn) {
4190 			udelay (1000);
4191 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4192 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4193 				break;
4194 			count++;
4195 		}
4196 	}
4197 
4198 	if (cntdn) {
4199 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4200 				ioc->name, count));
4201 		return count;
4202 	}
4203 
4204 	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4205 			ioc->name, count, intstat);
4206 	return -1;
4207 }
4208 
4209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4210 /**
4211  *	WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4212  *	@ioc: Pointer to MPT_ADAPTER structure
4213  *	@howlong: How long to wait (in seconds)
4214  *	@sleepFlag: Specifies whether the process can sleep
4215  *
4216  *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4217  *	(MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4218  *
4219  *	Returns a negative value on failure, else wait loop count.
4220  */
4221 static int
4222 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4223 {
4224 	int cntdn;
4225 	int count = 0;
4226 	u32 intstat=0;
4227 
4228 	cntdn = 1000 * howlong;
4229 	if (sleepFlag == CAN_SLEEP) {
4230 		while (--cntdn) {
4231 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4232 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4233 				break;
4234 			msleep(1);
4235 			count++;
4236 		}
4237 	} else {
4238 		while (--cntdn) {
4239 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4240 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4241 				break;
4242 			udelay (1000);
4243 			count++;
4244 		}
4245 	}
4246 
4247 	if (cntdn) {
4248 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4249 				ioc->name, count, howlong));
4250 		return count;
4251 	}
4252 
4253 	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4254 			ioc->name, count, intstat);
4255 	return -1;
4256 }
4257 
4258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4259 /**
4260  *	WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4261  *	@ioc: Pointer to MPT_ADAPTER structure
4262  *	@howlong: How long to wait (in seconds)
4263  *	@sleepFlag: Specifies whether the process can sleep
4264  *
4265  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
4266  *	Reply is cached to IOC private area large enough to hold a maximum
4267  *	of 128 bytes of reply data.
4268  *
4269  *	Returns a negative value on failure, else size of reply in WORDS.
4270  */
4271 static int
4272 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4273 {
4274 	int u16cnt = 0;
4275 	int failcnt = 0;
4276 	int t;
4277 	u16 *hs_reply = ioc->hs_reply;
4278 	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4279 	u16 hword;
4280 
4281 	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4282 
4283 	/*
4284 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
4285 	 */
4286 	u16cnt=0;
4287 	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4288 		failcnt++;
4289 	} else {
4290 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4291 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4292 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4293 			failcnt++;
4294 		else {
4295 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4296 			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4297 		}
4298 	}
4299 
4300 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4301 			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4302 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4303 
4304 	/*
4305 	 * If no error (and IOC said MsgLength is > 0), piece together
4306 	 * reply 16 bits at a time.
4307 	 */
4308 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4309 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4310 			failcnt++;
4311 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4312 		/* don't overflow our IOC hs_reply[] buffer! */
4313 		if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4314 			hs_reply[u16cnt] = hword;
4315 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4316 	}
4317 
4318 	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4319 		failcnt++;
4320 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4321 
4322 	if (failcnt) {
4323 		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4324 				ioc->name);
4325 		return -failcnt;
4326 	}
4327 #if 0
4328 	else if (u16cnt != (2 * mptReply->MsgLength)) {
4329 		return -101;
4330 	}
4331 	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4332 		return -102;
4333 	}
4334 #endif
4335 
4336 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4337 	DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply)
4338 
4339 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4340 			ioc->name, t, u16cnt/2));
4341 	return u16cnt/2;
4342 }
4343 
4344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4345 /**
4346  *	GetLanConfigPages - Fetch LANConfig pages.
4347  *	@ioc: Pointer to MPT_ADAPTER structure
4348  *
4349  *	Return: 0 for success
4350  *	-ENOMEM if no memory available
4351  *		-EPERM if not allowed due to ISR context
4352  *		-EAGAIN if no msg frames currently available
4353  *		-EFAULT for non-successful reply or no reply (timeout)
4354  */
4355 static int
4356 GetLanConfigPages(MPT_ADAPTER *ioc)
4357 {
4358 	ConfigPageHeader_t	 hdr;
4359 	CONFIGPARMS		 cfg;
4360 	LANPage0_t		*ppage0_alloc;
4361 	dma_addr_t		 page0_dma;
4362 	LANPage1_t		*ppage1_alloc;
4363 	dma_addr_t		 page1_dma;
4364 	int			 rc = 0;
4365 	int			 data_sz;
4366 	int			 copy_sz;
4367 
4368 	/* Get LAN Page 0 header */
4369 	hdr.PageVersion = 0;
4370 	hdr.PageLength = 0;
4371 	hdr.PageNumber = 0;
4372 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4373 	cfg.cfghdr.hdr = &hdr;
4374 	cfg.physAddr = -1;
4375 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4376 	cfg.dir = 0;
4377 	cfg.pageAddr = 0;
4378 	cfg.timeout = 0;
4379 
4380 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4381 		return rc;
4382 
4383 	if (hdr.PageLength > 0) {
4384 		data_sz = hdr.PageLength * 4;
4385 		ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4386 		rc = -ENOMEM;
4387 		if (ppage0_alloc) {
4388 			memset((u8 *)ppage0_alloc, 0, data_sz);
4389 			cfg.physAddr = page0_dma;
4390 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4391 
4392 			if ((rc = mpt_config(ioc, &cfg)) == 0) {
4393 				/* save the data */
4394 				copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4395 				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4396 
4397 			}
4398 
4399 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4400 
4401 			/* FIXME!
4402 			 *	Normalize endianness of structure data,
4403 			 *	by byte-swapping all > 1 byte fields!
4404 			 */
4405 
4406 		}
4407 
4408 		if (rc)
4409 			return rc;
4410 	}
4411 
4412 	/* Get LAN Page 1 header */
4413 	hdr.PageVersion = 0;
4414 	hdr.PageLength = 0;
4415 	hdr.PageNumber = 1;
4416 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4417 	cfg.cfghdr.hdr = &hdr;
4418 	cfg.physAddr = -1;
4419 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4420 	cfg.dir = 0;
4421 	cfg.pageAddr = 0;
4422 
4423 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4424 		return rc;
4425 
4426 	if (hdr.PageLength == 0)
4427 		return 0;
4428 
4429 	data_sz = hdr.PageLength * 4;
4430 	rc = -ENOMEM;
4431 	ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4432 	if (ppage1_alloc) {
4433 		memset((u8 *)ppage1_alloc, 0, data_sz);
4434 		cfg.physAddr = page1_dma;
4435 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4436 
4437 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
4438 			/* save the data */
4439 			copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4440 			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4441 		}
4442 
4443 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4444 
4445 		/* FIXME!
4446 		 *	Normalize endianness of structure data,
4447 		 *	by byte-swapping all > 1 byte fields!
4448 		 */
4449 
4450 	}
4451 
4452 	return rc;
4453 }
4454 
4455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4456 /**
4457  *	mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4458  *	@ioc: Pointer to MPT_ADAPTER structure
4459  *	@persist_opcode: see below
4460  *
4461  *	MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4462  *		devices not currently present.
4463  *	MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4464  *
4465  *	NOTE: Don't use not this function during interrupt time.
4466  *
4467  *	Returns 0 for success, non-zero error
4468  */
4469 
4470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4471 int
4472 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4473 {
4474 	SasIoUnitControlRequest_t	*sasIoUnitCntrReq;
4475 	SasIoUnitControlReply_t		*sasIoUnitCntrReply;
4476 	MPT_FRAME_HDR			*mf = NULL;
4477 	MPIHeader_t			*mpi_hdr;
4478 
4479 
4480 	/* insure garbage is not sent to fw */
4481 	switch(persist_opcode) {
4482 
4483 	case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4484 	case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4485 		break;
4486 
4487 	default:
4488 		return -1;
4489 		break;
4490 	}
4491 
4492 	printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4493 
4494 	/* Get a MF for this command.
4495 	 */
4496 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4497 		printk("%s: no msg frames!\n",__FUNCTION__);
4498 		return -1;
4499         }
4500 
4501 	mpi_hdr = (MPIHeader_t *) mf;
4502 	sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4503 	memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4504 	sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4505 	sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4506 	sasIoUnitCntrReq->Operation = persist_opcode;
4507 
4508 	init_timer(&ioc->persist_timer);
4509 	ioc->persist_timer.data = (unsigned long) ioc;
4510 	ioc->persist_timer.function = mpt_timer_expired;
4511 	ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4512 	ioc->persist_wait_done=0;
4513 	add_timer(&ioc->persist_timer);
4514 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4515 	wait_event(mpt_waitq, ioc->persist_wait_done);
4516 
4517 	sasIoUnitCntrReply =
4518 	    (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4519 	if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4520 		printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4521 		    __FUNCTION__,
4522 		    sasIoUnitCntrReply->IOCStatus,
4523 		    sasIoUnitCntrReply->IOCLogInfo);
4524 		return -1;
4525 	}
4526 
4527 	printk("%s: success\n",__FUNCTION__);
4528 	return 0;
4529 }
4530 
4531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4532 
4533 static void
4534 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4535     MpiEventDataRaid_t * pRaidEventData)
4536 {
4537 	int 	volume;
4538 	int 	reason;
4539 	int 	disk;
4540 	int 	status;
4541 	int 	flags;
4542 	int 	state;
4543 
4544 	volume	= pRaidEventData->VolumeID;
4545 	reason	= pRaidEventData->ReasonCode;
4546 	disk	= pRaidEventData->PhysDiskNum;
4547 	status	= le32_to_cpu(pRaidEventData->SettingsStatus);
4548 	flags	= (status >> 0) & 0xff;
4549 	state	= (status >> 8) & 0xff;
4550 
4551 	if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4552 		return;
4553 	}
4554 
4555 	if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4556 	     reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4557 	    (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4558 		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4559 			ioc->name, disk, volume);
4560 	} else {
4561 		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4562 			ioc->name, volume);
4563 	}
4564 
4565 	switch(reason) {
4566 	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4567 		printk(MYIOC_s_INFO_FMT "  volume has been created\n",
4568 			ioc->name);
4569 		break;
4570 
4571 	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4572 
4573 		printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
4574 			ioc->name);
4575 		break;
4576 
4577 	case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4578 		printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
4579 			ioc->name);
4580 		break;
4581 
4582 	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4583 		printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
4584 			ioc->name,
4585 			state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4586 			 ? "optimal"
4587 			 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4588 			  ? "degraded"
4589 			  : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4590 			   ? "failed"
4591 			   : "state unknown",
4592 			flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4593 			 ? ", enabled" : "",
4594 			flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4595 			 ? ", quiesced" : "",
4596 			flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4597 			 ? ", resync in progress" : "" );
4598 		break;
4599 
4600 	case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4601 		printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
4602 			ioc->name, disk);
4603 		break;
4604 
4605 	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4606 		printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
4607 			ioc->name);
4608 		break;
4609 
4610 	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4611 		printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
4612 			ioc->name);
4613 		break;
4614 
4615 	case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4616 		printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
4617 			ioc->name);
4618 		break;
4619 
4620 	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4621 		printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
4622 			ioc->name,
4623 			state == MPI_PHYSDISK0_STATUS_ONLINE
4624 			 ? "online"
4625 			 : state == MPI_PHYSDISK0_STATUS_MISSING
4626 			  ? "missing"
4627 			  : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4628 			   ? "not compatible"
4629 			   : state == MPI_PHYSDISK0_STATUS_FAILED
4630 			    ? "failed"
4631 			    : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4632 			     ? "initializing"
4633 			     : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4634 			      ? "offline requested"
4635 			      : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4636 			       ? "failed requested"
4637 			       : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4638 			        ? "offline"
4639 			        : "state unknown",
4640 			flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4641 			 ? ", out of sync" : "",
4642 			flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4643 			 ? ", quiesced" : "" );
4644 		break;
4645 
4646 	case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4647 		printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
4648 			ioc->name, disk);
4649 		break;
4650 
4651 	case MPI_EVENT_RAID_RC_SMART_DATA:
4652 		printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4653 			ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4654 		break;
4655 
4656 	case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4657 		printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
4658 			ioc->name, disk);
4659 		break;
4660 	}
4661 }
4662 
4663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4664 /**
4665  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4666  *	@ioc: Pointer to MPT_ADAPTER structure
4667  *
4668  *	Returns: 0 for success
4669  *	-ENOMEM if no memory available
4670  *		-EPERM if not allowed due to ISR context
4671  *		-EAGAIN if no msg frames currently available
4672  *		-EFAULT for non-successful reply or no reply (timeout)
4673  */
4674 static int
4675 GetIoUnitPage2(MPT_ADAPTER *ioc)
4676 {
4677 	ConfigPageHeader_t	 hdr;
4678 	CONFIGPARMS		 cfg;
4679 	IOUnitPage2_t		*ppage_alloc;
4680 	dma_addr_t		 page_dma;
4681 	int			 data_sz;
4682 	int			 rc;
4683 
4684 	/* Get the page header */
4685 	hdr.PageVersion = 0;
4686 	hdr.PageLength = 0;
4687 	hdr.PageNumber = 2;
4688 	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4689 	cfg.cfghdr.hdr = &hdr;
4690 	cfg.physAddr = -1;
4691 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4692 	cfg.dir = 0;
4693 	cfg.pageAddr = 0;
4694 	cfg.timeout = 0;
4695 
4696 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4697 		return rc;
4698 
4699 	if (hdr.PageLength == 0)
4700 		return 0;
4701 
4702 	/* Read the config page */
4703 	data_sz = hdr.PageLength * 4;
4704 	rc = -ENOMEM;
4705 	ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4706 	if (ppage_alloc) {
4707 		memset((u8 *)ppage_alloc, 0, data_sz);
4708 		cfg.physAddr = page_dma;
4709 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4710 
4711 		/* If Good, save data */
4712 		if ((rc = mpt_config(ioc, &cfg)) == 0)
4713 			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4714 
4715 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4716 	}
4717 
4718 	return rc;
4719 }
4720 
4721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4722 /**
4723  *	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4724  *	@ioc: Pointer to a Adapter Strucutre
4725  *	@portnum: IOC port number
4726  *
4727  *	Return: -EFAULT if read of config page header fails
4728  *			or if no nvram
4729  *	If read of SCSI Port Page 0 fails,
4730  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4731  *		Adapter settings: async, narrow
4732  *		Return 1
4733  *	If read of SCSI Port Page 2 fails,
4734  *		Adapter settings valid
4735  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4736  *		Return 1
4737  *	Else
4738  *		Both valid
4739  *		Return 0
4740  *	CHECK - what type of locking mechanisms should be used????
4741  */
4742 static int
4743 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4744 {
4745 	u8			*pbuf;
4746 	dma_addr_t		 buf_dma;
4747 	CONFIGPARMS		 cfg;
4748 	ConfigPageHeader_t	 header;
4749 	int			 ii;
4750 	int			 data, rc = 0;
4751 
4752 	/* Allocate memory
4753 	 */
4754 	if (!ioc->spi_data.nvram) {
4755 		int	 sz;
4756 		u8	*mem;
4757 		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4758 		mem = kmalloc(sz, GFP_ATOMIC);
4759 		if (mem == NULL)
4760 			return -EFAULT;
4761 
4762 		ioc->spi_data.nvram = (int *) mem;
4763 
4764 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4765 			ioc->name, ioc->spi_data.nvram, sz));
4766 	}
4767 
4768 	/* Invalidate NVRAM information
4769 	 */
4770 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4771 		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4772 	}
4773 
4774 	/* Read SPP0 header, allocate memory, then read page.
4775 	 */
4776 	header.PageVersion = 0;
4777 	header.PageLength = 0;
4778 	header.PageNumber = 0;
4779 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4780 	cfg.cfghdr.hdr = &header;
4781 	cfg.physAddr = -1;
4782 	cfg.pageAddr = portnum;
4783 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4784 	cfg.dir = 0;
4785 	cfg.timeout = 0;	/* use default */
4786 	if (mpt_config(ioc, &cfg) != 0)
4787 		 return -EFAULT;
4788 
4789 	if (header.PageLength > 0) {
4790 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4791 		if (pbuf) {
4792 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4793 			cfg.physAddr = buf_dma;
4794 			if (mpt_config(ioc, &cfg) != 0) {
4795 				ioc->spi_data.maxBusWidth = MPT_NARROW;
4796 				ioc->spi_data.maxSyncOffset = 0;
4797 				ioc->spi_data.minSyncFactor = MPT_ASYNC;
4798 				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4799 				rc = 1;
4800 				ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4801 					"Unable to read PortPage0 minSyncFactor=%x\n",
4802 					ioc->name, ioc->spi_data.minSyncFactor));
4803 			} else {
4804 				/* Save the Port Page 0 data
4805 				 */
4806 				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4807 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4808 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4809 
4810 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4811 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4812 					ddvprintk(ioc, printk(KERN_INFO MYNAM
4813 						" :%s noQas due to Capabilities=%x\n",
4814 						ioc->name, pPP0->Capabilities));
4815 				}
4816 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4817 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4818 				if (data) {
4819 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4820 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4821 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4822 					ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4823 						"PortPage0 minSyncFactor=%x\n",
4824 						ioc->name, ioc->spi_data.minSyncFactor));
4825 				} else {
4826 					ioc->spi_data.maxSyncOffset = 0;
4827 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
4828 				}
4829 
4830 				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4831 
4832 				/* Update the minSyncFactor based on bus type.
4833 				 */
4834 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4835 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4836 
4837 					if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4838 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
4839 						ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4840 							"HVD or SE detected, minSyncFactor=%x\n",
4841 							ioc->name, ioc->spi_data.minSyncFactor));
4842 					}
4843 				}
4844 			}
4845 			if (pbuf) {
4846 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4847 			}
4848 		}
4849 	}
4850 
4851 	/* SCSI Port Page 2 - Read the header then the page.
4852 	 */
4853 	header.PageVersion = 0;
4854 	header.PageLength = 0;
4855 	header.PageNumber = 2;
4856 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4857 	cfg.cfghdr.hdr = &header;
4858 	cfg.physAddr = -1;
4859 	cfg.pageAddr = portnum;
4860 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4861 	cfg.dir = 0;
4862 	if (mpt_config(ioc, &cfg) != 0)
4863 		return -EFAULT;
4864 
4865 	if (header.PageLength > 0) {
4866 		/* Allocate memory and read SCSI Port Page 2
4867 		 */
4868 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4869 		if (pbuf) {
4870 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4871 			cfg.physAddr = buf_dma;
4872 			if (mpt_config(ioc, &cfg) != 0) {
4873 				/* Nvram data is left with INVALID mark
4874 				 */
4875 				rc = 1;
4876 			} else {
4877 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4878 				MpiDeviceInfo_t	*pdevice = NULL;
4879 
4880 				/*
4881 				 * Save "Set to Avoid SCSI Bus Resets" flag
4882 				 */
4883 				ioc->spi_data.bus_reset =
4884 				    (le32_to_cpu(pPP2->PortFlags) &
4885 			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4886 				    0 : 1 ;
4887 
4888 				/* Save the Port Page 2 data
4889 				 * (reformat into a 32bit quantity)
4890 				 */
4891 				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4892 				ioc->spi_data.PortFlags = data;
4893 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4894 					pdevice = &pPP2->DeviceSettings[ii];
4895 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4896 						(pdevice->SyncFactor << 8) | pdevice->Timeout;
4897 					ioc->spi_data.nvram[ii] = data;
4898 				}
4899 			}
4900 
4901 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4902 		}
4903 	}
4904 
4905 	/* Update Adapter limits with those from NVRAM
4906 	 * Comment: Don't need to do this. Target performance
4907 	 * parameters will never exceed the adapters limits.
4908 	 */
4909 
4910 	return rc;
4911 }
4912 
4913 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4914 /**
4915  *	mpt_readScsiDevicePageHeaders - save version and length of SDP1
4916  *	@ioc: Pointer to a Adapter Strucutre
4917  *	@portnum: IOC port number
4918  *
4919  *	Return: -EFAULT if read of config page header fails
4920  *		or 0 if success.
4921  */
4922 static int
4923 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4924 {
4925 	CONFIGPARMS		 cfg;
4926 	ConfigPageHeader_t	 header;
4927 
4928 	/* Read the SCSI Device Page 1 header
4929 	 */
4930 	header.PageVersion = 0;
4931 	header.PageLength = 0;
4932 	header.PageNumber = 1;
4933 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4934 	cfg.cfghdr.hdr = &header;
4935 	cfg.physAddr = -1;
4936 	cfg.pageAddr = portnum;
4937 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4938 	cfg.dir = 0;
4939 	cfg.timeout = 0;
4940 	if (mpt_config(ioc, &cfg) != 0)
4941 		 return -EFAULT;
4942 
4943 	ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4944 	ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4945 
4946 	header.PageVersion = 0;
4947 	header.PageLength = 0;
4948 	header.PageNumber = 0;
4949 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4950 	if (mpt_config(ioc, &cfg) != 0)
4951 		 return -EFAULT;
4952 
4953 	ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4954 	ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4955 
4956 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
4957 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4958 
4959 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
4960 			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4961 	return 0;
4962 }
4963 
4964 /**
4965  * mpt_inactive_raid_list_free - This clears this link list.
4966  * @ioc : pointer to per adapter structure
4967  **/
4968 static void
4969 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4970 {
4971 	struct inactive_raid_component_info *component_info, *pNext;
4972 
4973 	if (list_empty(&ioc->raid_data.inactive_list))
4974 		return;
4975 
4976 	down(&ioc->raid_data.inactive_list_mutex);
4977 	list_for_each_entry_safe(component_info, pNext,
4978 	    &ioc->raid_data.inactive_list, list) {
4979 		list_del(&component_info->list);
4980 		kfree(component_info);
4981 	}
4982 	up(&ioc->raid_data.inactive_list_mutex);
4983 }
4984 
4985 /**
4986  * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
4987  *
4988  * @ioc : pointer to per adapter structure
4989  * @channel : volume channel
4990  * @id : volume target id
4991  **/
4992 static void
4993 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4994 {
4995 	CONFIGPARMS			cfg;
4996 	ConfigPageHeader_t		hdr;
4997 	dma_addr_t			dma_handle;
4998 	pRaidVolumePage0_t		buffer = NULL;
4999 	int				i;
5000 	RaidPhysDiskPage0_t 		phys_disk;
5001 	struct inactive_raid_component_info *component_info;
5002 	int				handle_inactive_volumes;
5003 
5004 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5005 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5006 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5007 	cfg.pageAddr = (channel << 8) + id;
5008 	cfg.cfghdr.hdr = &hdr;
5009 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5010 
5011 	if (mpt_config(ioc, &cfg) != 0)
5012 		goto out;
5013 
5014 	if (!hdr.PageLength)
5015 		goto out;
5016 
5017 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5018 	    &dma_handle);
5019 
5020 	if (!buffer)
5021 		goto out;
5022 
5023 	cfg.physAddr = dma_handle;
5024 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5025 
5026 	if (mpt_config(ioc, &cfg) != 0)
5027 		goto out;
5028 
5029 	if (!buffer->NumPhysDisks)
5030 		goto out;
5031 
5032 	handle_inactive_volumes =
5033 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5034 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5035 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5036 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5037 
5038 	if (!handle_inactive_volumes)
5039 		goto out;
5040 
5041 	down(&ioc->raid_data.inactive_list_mutex);
5042 	for (i = 0; i < buffer->NumPhysDisks; i++) {
5043 		if(mpt_raid_phys_disk_pg0(ioc,
5044 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5045 			continue;
5046 
5047 		if ((component_info = kmalloc(sizeof (*component_info),
5048 		 GFP_KERNEL)) == NULL)
5049 			continue;
5050 
5051 		component_info->volumeID = id;
5052 		component_info->volumeBus = channel;
5053 		component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5054 		component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5055 		component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5056 		component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5057 
5058 		list_add_tail(&component_info->list,
5059 		    &ioc->raid_data.inactive_list);
5060 	}
5061 	up(&ioc->raid_data.inactive_list_mutex);
5062 
5063  out:
5064 	if (buffer)
5065 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5066 		    dma_handle);
5067 }
5068 
5069 /**
5070  *	mpt_raid_phys_disk_pg0 - returns phys disk page zero
5071  *	@ioc: Pointer to a Adapter Structure
5072  *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5073  *	@phys_disk: requested payload data returned
5074  *
5075  *	Return:
5076  *	0 on success
5077  *	-EFAULT if read of config page header fails or data pointer not NULL
5078  *	-ENOMEM if pci_alloc failed
5079  **/
5080 int
5081 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5082 {
5083 	CONFIGPARMS		 	cfg;
5084 	ConfigPageHeader_t	 	hdr;
5085 	dma_addr_t			dma_handle;
5086 	pRaidPhysDiskPage0_t		buffer = NULL;
5087 	int				rc;
5088 
5089 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5090 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5091 
5092 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5093 	cfg.cfghdr.hdr = &hdr;
5094 	cfg.physAddr = -1;
5095 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5096 
5097 	if (mpt_config(ioc, &cfg) != 0) {
5098 		rc = -EFAULT;
5099 		goto out;
5100 	}
5101 
5102 	if (!hdr.PageLength) {
5103 		rc = -EFAULT;
5104 		goto out;
5105 	}
5106 
5107 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5108 	    &dma_handle);
5109 
5110 	if (!buffer) {
5111 		rc = -ENOMEM;
5112 		goto out;
5113 	}
5114 
5115 	cfg.physAddr = dma_handle;
5116 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5117 	cfg.pageAddr = phys_disk_num;
5118 
5119 	if (mpt_config(ioc, &cfg) != 0) {
5120 		rc = -EFAULT;
5121 		goto out;
5122 	}
5123 
5124 	rc = 0;
5125 	memcpy(phys_disk, buffer, sizeof(*buffer));
5126 	phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5127 
5128  out:
5129 
5130 	if (buffer)
5131 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5132 		    dma_handle);
5133 
5134 	return rc;
5135 }
5136 
5137 /**
5138  *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5139  *	@ioc: Pointer to a Adapter Strucutre
5140  *	@portnum: IOC port number
5141  *
5142  *	Return:
5143  *	0 on success
5144  *	-EFAULT if read of config page header fails or data pointer not NULL
5145  *	-ENOMEM if pci_alloc failed
5146  **/
5147 int
5148 mpt_findImVolumes(MPT_ADAPTER *ioc)
5149 {
5150 	IOCPage2_t		*pIoc2;
5151 	u8			*mem;
5152 	dma_addr_t		 ioc2_dma;
5153 	CONFIGPARMS		 cfg;
5154 	ConfigPageHeader_t	 header;
5155 	int			 rc = 0;
5156 	int			 iocpage2sz;
5157 	int			 i;
5158 
5159 	if (!ioc->ir_firmware)
5160 		return 0;
5161 
5162 	/* Free the old page
5163 	 */
5164 	kfree(ioc->raid_data.pIocPg2);
5165 	ioc->raid_data.pIocPg2 = NULL;
5166 	mpt_inactive_raid_list_free(ioc);
5167 
5168 	/* Read IOCP2 header then the page.
5169 	 */
5170 	header.PageVersion = 0;
5171 	header.PageLength = 0;
5172 	header.PageNumber = 2;
5173 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5174 	cfg.cfghdr.hdr = &header;
5175 	cfg.physAddr = -1;
5176 	cfg.pageAddr = 0;
5177 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5178 	cfg.dir = 0;
5179 	cfg.timeout = 0;
5180 	if (mpt_config(ioc, &cfg) != 0)
5181 		 return -EFAULT;
5182 
5183 	if (header.PageLength == 0)
5184 		return -EFAULT;
5185 
5186 	iocpage2sz = header.PageLength * 4;
5187 	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5188 	if (!pIoc2)
5189 		return -ENOMEM;
5190 
5191 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5192 	cfg.physAddr = ioc2_dma;
5193 	if (mpt_config(ioc, &cfg) != 0)
5194 		goto out;
5195 
5196 	mem = kmalloc(iocpage2sz, GFP_KERNEL);
5197 	if (!mem)
5198 		goto out;
5199 
5200 	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5201 	ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5202 
5203 	mpt_read_ioc_pg_3(ioc);
5204 
5205 	for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5206 		mpt_inactive_raid_volumes(ioc,
5207 		    pIoc2->RaidVolume[i].VolumeBus,
5208 		    pIoc2->RaidVolume[i].VolumeID);
5209 
5210  out:
5211 	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5212 
5213 	return rc;
5214 }
5215 
5216 static int
5217 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5218 {
5219 	IOCPage3_t		*pIoc3;
5220 	u8			*mem;
5221 	CONFIGPARMS		 cfg;
5222 	ConfigPageHeader_t	 header;
5223 	dma_addr_t		 ioc3_dma;
5224 	int			 iocpage3sz = 0;
5225 
5226 	/* Free the old page
5227 	 */
5228 	kfree(ioc->raid_data.pIocPg3);
5229 	ioc->raid_data.pIocPg3 = NULL;
5230 
5231 	/* There is at least one physical disk.
5232 	 * Read and save IOC Page 3
5233 	 */
5234 	header.PageVersion = 0;
5235 	header.PageLength = 0;
5236 	header.PageNumber = 3;
5237 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5238 	cfg.cfghdr.hdr = &header;
5239 	cfg.physAddr = -1;
5240 	cfg.pageAddr = 0;
5241 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5242 	cfg.dir = 0;
5243 	cfg.timeout = 0;
5244 	if (mpt_config(ioc, &cfg) != 0)
5245 		return 0;
5246 
5247 	if (header.PageLength == 0)
5248 		return 0;
5249 
5250 	/* Read Header good, alloc memory
5251 	 */
5252 	iocpage3sz = header.PageLength * 4;
5253 	pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5254 	if (!pIoc3)
5255 		return 0;
5256 
5257 	/* Read the Page and save the data
5258 	 * into malloc'd memory.
5259 	 */
5260 	cfg.physAddr = ioc3_dma;
5261 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5262 	if (mpt_config(ioc, &cfg) == 0) {
5263 		mem = kmalloc(iocpage3sz, GFP_KERNEL);
5264 		if (mem) {
5265 			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5266 			ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5267 		}
5268 	}
5269 
5270 	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5271 
5272 	return 0;
5273 }
5274 
5275 static void
5276 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5277 {
5278 	IOCPage4_t		*pIoc4;
5279 	CONFIGPARMS		 cfg;
5280 	ConfigPageHeader_t	 header;
5281 	dma_addr_t		 ioc4_dma;
5282 	int			 iocpage4sz;
5283 
5284 	/* Read and save IOC Page 4
5285 	 */
5286 	header.PageVersion = 0;
5287 	header.PageLength = 0;
5288 	header.PageNumber = 4;
5289 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5290 	cfg.cfghdr.hdr = &header;
5291 	cfg.physAddr = -1;
5292 	cfg.pageAddr = 0;
5293 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5294 	cfg.dir = 0;
5295 	cfg.timeout = 0;
5296 	if (mpt_config(ioc, &cfg) != 0)
5297 		return;
5298 
5299 	if (header.PageLength == 0)
5300 		return;
5301 
5302 	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5303 		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5304 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5305 		if (!pIoc4)
5306 			return;
5307 		ioc->alloc_total += iocpage4sz;
5308 	} else {
5309 		ioc4_dma = ioc->spi_data.IocPg4_dma;
5310 		iocpage4sz = ioc->spi_data.IocPg4Sz;
5311 	}
5312 
5313 	/* Read the Page into dma memory.
5314 	 */
5315 	cfg.physAddr = ioc4_dma;
5316 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5317 	if (mpt_config(ioc, &cfg) == 0) {
5318 		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5319 		ioc->spi_data.IocPg4_dma = ioc4_dma;
5320 		ioc->spi_data.IocPg4Sz = iocpage4sz;
5321 	} else {
5322 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5323 		ioc->spi_data.pIocPg4 = NULL;
5324 		ioc->alloc_total -= iocpage4sz;
5325 	}
5326 }
5327 
5328 static void
5329 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5330 {
5331 	IOCPage1_t		*pIoc1;
5332 	CONFIGPARMS		 cfg;
5333 	ConfigPageHeader_t	 header;
5334 	dma_addr_t		 ioc1_dma;
5335 	int			 iocpage1sz = 0;
5336 	u32			 tmp;
5337 
5338 	/* Check the Coalescing Timeout in IOC Page 1
5339 	 */
5340 	header.PageVersion = 0;
5341 	header.PageLength = 0;
5342 	header.PageNumber = 1;
5343 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5344 	cfg.cfghdr.hdr = &header;
5345 	cfg.physAddr = -1;
5346 	cfg.pageAddr = 0;
5347 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5348 	cfg.dir = 0;
5349 	cfg.timeout = 0;
5350 	if (mpt_config(ioc, &cfg) != 0)
5351 		return;
5352 
5353 	if (header.PageLength == 0)
5354 		return;
5355 
5356 	/* Read Header good, alloc memory
5357 	 */
5358 	iocpage1sz = header.PageLength * 4;
5359 	pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5360 	if (!pIoc1)
5361 		return;
5362 
5363 	/* Read the Page and check coalescing timeout
5364 	 */
5365 	cfg.physAddr = ioc1_dma;
5366 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5367 	if (mpt_config(ioc, &cfg) == 0) {
5368 
5369 		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5370 		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5371 			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5372 
5373 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5374 					ioc->name, tmp));
5375 
5376 			if (tmp > MPT_COALESCING_TIMEOUT) {
5377 				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5378 
5379 				/* Write NVRAM and current
5380 				 */
5381 				cfg.dir = 1;
5382 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5383 				if (mpt_config(ioc, &cfg) == 0) {
5384 					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5385 							ioc->name, MPT_COALESCING_TIMEOUT));
5386 
5387 					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5388 					if (mpt_config(ioc, &cfg) == 0) {
5389 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5390 								"Reset NVRAM Coalescing Timeout to = %d\n",
5391 								ioc->name, MPT_COALESCING_TIMEOUT));
5392 					} else {
5393 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5394 								"Reset NVRAM Coalescing Timeout Failed\n",
5395 								ioc->name));
5396 					}
5397 
5398 				} else {
5399 					dprintk(ioc, printk(MYIOC_s_WARN_FMT
5400 						"Reset of Current Coalescing Timeout Failed!\n",
5401 						ioc->name));
5402 				}
5403 			}
5404 
5405 		} else {
5406 			dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5407 		}
5408 	}
5409 
5410 	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5411 
5412 	return;
5413 }
5414 
5415 static void
5416 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5417 {
5418 	CONFIGPARMS		cfg;
5419 	ConfigPageHeader_t	hdr;
5420 	dma_addr_t		buf_dma;
5421 	ManufacturingPage0_t	*pbuf = NULL;
5422 
5423 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5424 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5425 
5426 	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5427 	cfg.cfghdr.hdr = &hdr;
5428 	cfg.physAddr = -1;
5429 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5430 	cfg.timeout = 10;
5431 
5432 	if (mpt_config(ioc, &cfg) != 0)
5433 		goto out;
5434 
5435 	if (!cfg.cfghdr.hdr->PageLength)
5436 		goto out;
5437 
5438 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5439 	pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5440 	if (!pbuf)
5441 		goto out;
5442 
5443 	cfg.physAddr = buf_dma;
5444 
5445 	if (mpt_config(ioc, &cfg) != 0)
5446 		goto out;
5447 
5448 	memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5449 	memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5450 	memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5451 
5452 	out:
5453 
5454 	if (pbuf)
5455 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5456 }
5457 
5458 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5459 /**
5460  *	SendEventNotification - Send EventNotification (on or off) request to adapter
5461  *	@ioc: Pointer to MPT_ADAPTER structure
5462  *	@EvSwitch: Event switch flags
5463  */
5464 static int
5465 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5466 {
5467 	EventNotification_t	*evnp;
5468 
5469 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5470 	if (evnp == NULL) {
5471 		devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5472 				ioc->name));
5473 		return 0;
5474 	}
5475 	memset(evnp, 0, sizeof(*evnp));
5476 
5477 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5478 
5479 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5480 	evnp->ChainOffset = 0;
5481 	evnp->MsgFlags = 0;
5482 	evnp->Switch = EvSwitch;
5483 
5484 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5485 
5486 	return 0;
5487 }
5488 
5489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5490 /**
5491  *	SendEventAck - Send EventAck request to MPT adapter.
5492  *	@ioc: Pointer to MPT_ADAPTER structure
5493  *	@evnp: Pointer to original EventNotification request
5494  */
5495 static int
5496 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5497 {
5498 	EventAck_t	*pAck;
5499 
5500 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5501 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5502 		    ioc->name,__FUNCTION__));
5503 		return -1;
5504 	}
5505 
5506 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5507 
5508 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
5509 	pAck->ChainOffset  = 0;
5510 	pAck->Reserved[0]  = pAck->Reserved[1] = 0;
5511 	pAck->MsgFlags     = 0;
5512 	pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5513 	pAck->Event        = evnp->Event;
5514 	pAck->EventContext = evnp->EventContext;
5515 
5516 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5517 
5518 	return 0;
5519 }
5520 
5521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5522 /**
5523  *	mpt_config - Generic function to issue config message
5524  *	@ioc:   Pointer to an adapter structure
5525  *	@pCfg:  Pointer to a configuration structure. Struct contains
5526  *		action, page address, direction, physical address
5527  *		and pointer to a configuration page header
5528  *		Page header is updated.
5529  *
5530  *	Returns 0 for success
5531  *	-EPERM if not allowed due to ISR context
5532  *	-EAGAIN if no msg frames currently available
5533  *	-EFAULT for non-successful reply or no reply (timeout)
5534  */
5535 int
5536 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5537 {
5538 	Config_t	*pReq;
5539 	ConfigExtendedPageHeader_t  *pExtHdr = NULL;
5540 	MPT_FRAME_HDR	*mf;
5541 	unsigned long	 flags;
5542 	int		 ii, rc;
5543 	int		 flagsLength;
5544 	int		 in_isr;
5545 
5546 	/*	Prevent calling wait_event() (below), if caller happens
5547 	 *	to be in ISR context, because that is fatal!
5548 	 */
5549 	in_isr = in_interrupt();
5550 	if (in_isr) {
5551 		dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5552 				ioc->name));
5553 		return -EPERM;
5554 	}
5555 
5556 	/* Get and Populate a free Frame
5557 	 */
5558 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5559 		dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5560 				ioc->name));
5561 		return -EAGAIN;
5562 	}
5563 	pReq = (Config_t *)mf;
5564 	pReq->Action = pCfg->action;
5565 	pReq->Reserved = 0;
5566 	pReq->ChainOffset = 0;
5567 	pReq->Function = MPI_FUNCTION_CONFIG;
5568 
5569 	/* Assume page type is not extended and clear "reserved" fields. */
5570 	pReq->ExtPageLength = 0;
5571 	pReq->ExtPageType = 0;
5572 	pReq->MsgFlags = 0;
5573 
5574 	for (ii=0; ii < 8; ii++)
5575 		pReq->Reserved2[ii] = 0;
5576 
5577 	pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5578 	pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5579 	pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5580 	pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5581 
5582 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5583 		pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5584 		pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5585 		pReq->ExtPageType = pExtHdr->ExtPageType;
5586 		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5587 
5588 		/* Page Length must be treated as a reserved field for the extended header. */
5589 		pReq->Header.PageLength = 0;
5590 	}
5591 
5592 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5593 
5594 	/* Add a SGE to the config request.
5595 	 */
5596 	if (pCfg->dir)
5597 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5598 	else
5599 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5600 
5601 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5602 		flagsLength |= pExtHdr->ExtPageLength * 4;
5603 
5604 		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5605 			ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5606 	}
5607 	else {
5608 		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5609 
5610 		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5611 			ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5612 	}
5613 
5614 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5615 
5616 	/* Append pCfg pointer to end of mf
5617 	 */
5618 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
5619 
5620 	/* Initalize the timer
5621 	 */
5622 	init_timer(&pCfg->timer);
5623 	pCfg->timer.data = (unsigned long) ioc;
5624 	pCfg->timer.function = mpt_timer_expired;
5625 	pCfg->wait_done = 0;
5626 
5627 	/* Set the timer; ensure 10 second minimum */
5628 	if (pCfg->timeout < 10)
5629 		pCfg->timer.expires = jiffies + HZ*10;
5630 	else
5631 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5632 
5633 	/* Add to end of Q, set timer and then issue this command */
5634 	spin_lock_irqsave(&ioc->FreeQlock, flags);
5635 	list_add_tail(&pCfg->linkage, &ioc->configQ);
5636 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5637 
5638 	add_timer(&pCfg->timer);
5639 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
5640 	wait_event(mpt_waitq, pCfg->wait_done);
5641 
5642 	/* mf has been freed - do not access */
5643 
5644 	rc = pCfg->status;
5645 
5646 	return rc;
5647 }
5648 
5649 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5650 /**
5651  *	mpt_timer_expired - Callback for timer process.
5652  *	Used only internal config functionality.
5653  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5654  */
5655 static void
5656 mpt_timer_expired(unsigned long data)
5657 {
5658 	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5659 
5660 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5661 
5662 	/* Perform a FW reload */
5663 	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5664 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5665 
5666 	/* No more processing.
5667 	 * Hard reset clean-up will wake up
5668 	 * process and free all resources.
5669 	 */
5670 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5671 
5672 	return;
5673 }
5674 
5675 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5676 /**
5677  *	mpt_ioc_reset - Base cleanup for hard reset
5678  *	@ioc: Pointer to the adapter structure
5679  *	@reset_phase: Indicates pre- or post-reset functionality
5680  *
5681  *	Remark: Frees resources with internally generated commands.
5682  */
5683 static int
5684 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5685 {
5686 	CONFIGPARMS *pCfg;
5687 	unsigned long flags;
5688 
5689 	dprintk(ioc, printk(KERN_DEBUG MYNAM
5690 			": IOC %s_reset routed to MPT base driver!\n",
5691 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5692 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5693 
5694 	if (reset_phase == MPT_IOC_SETUP_RESET) {
5695 		;
5696 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
5697 		/* If the internal config Q is not empty -
5698 		 * delete timer. MF resources will be freed when
5699 		 * the FIFO's are primed.
5700 		 */
5701 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5702 		list_for_each_entry(pCfg, &ioc->configQ, linkage)
5703 			del_timer(&pCfg->timer);
5704 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5705 
5706 	} else {
5707 		CONFIGPARMS *pNext;
5708 
5709 		/* Search the configQ for internal commands.
5710 		 * Flush the Q, and wake up all suspended threads.
5711 		 */
5712 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5713 		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5714 			list_del(&pCfg->linkage);
5715 
5716 			pCfg->status = MPT_CONFIG_ERROR;
5717 			pCfg->wait_done = 1;
5718 			wake_up(&mpt_waitq);
5719 		}
5720 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5721 	}
5722 
5723 	return 1;		/* currently means nothing really */
5724 }
5725 
5726 
5727 #ifdef CONFIG_PROC_FS		/* { */
5728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5729 /*
5730  *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5731  */
5732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5733 /**
5734  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5735  *
5736  *	Returns 0 for success, non-zero for failure.
5737  */
5738 static int
5739 procmpt_create(void)
5740 {
5741 	struct proc_dir_entry	*ent;
5742 
5743 	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5744 	if (mpt_proc_root_dir == NULL)
5745 		return -ENOTDIR;
5746 
5747 	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5748 	if (ent)
5749 		ent->read_proc = procmpt_summary_read;
5750 
5751 	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5752 	if (ent)
5753 		ent->read_proc = procmpt_version_read;
5754 
5755 	return 0;
5756 }
5757 
5758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5759 /**
5760  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5761  *
5762  *	Returns 0 for success, non-zero for failure.
5763  */
5764 static void
5765 procmpt_destroy(void)
5766 {
5767 	remove_proc_entry("version", mpt_proc_root_dir);
5768 	remove_proc_entry("summary", mpt_proc_root_dir);
5769 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5770 }
5771 
5772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5773 /**
5774  *	procmpt_summary_read - Handle read request of a summary file
5775  *	@buf: Pointer to area to write information
5776  *	@start: Pointer to start pointer
5777  *	@offset: Offset to start writing
5778  *	@request: Amount of read data requested
5779  *	@eof: Pointer to EOF integer
5780  *	@data: Pointer
5781  *
5782  *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5783  *	Returns number of characters written to process performing the read.
5784  */
5785 static int
5786 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5787 {
5788 	MPT_ADAPTER *ioc;
5789 	char *out = buf;
5790 	int len;
5791 
5792 	if (data) {
5793 		int more = 0;
5794 
5795 		ioc = data;
5796 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5797 
5798 		out += more;
5799 	} else {
5800 		list_for_each_entry(ioc, &ioc_list, list) {
5801 			int	more = 0;
5802 
5803 			mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5804 
5805 			out += more;
5806 			if ((out-buf) >= request)
5807 				break;
5808 		}
5809 	}
5810 
5811 	len = out - buf;
5812 
5813 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5814 }
5815 
5816 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5817 /**
5818  *	procmpt_version_read - Handle read request from /proc/mpt/version.
5819  *	@buf: Pointer to area to write information
5820  *	@start: Pointer to start pointer
5821  *	@offset: Offset to start writing
5822  *	@request: Amount of read data requested
5823  *	@eof: Pointer to EOF integer
5824  *	@data: Pointer
5825  *
5826  *	Returns number of characters written to process performing the read.
5827  */
5828 static int
5829 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5830 {
5831 	int	 ii;
5832 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
5833 	char	*drvname;
5834 	int	 len;
5835 
5836 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5837 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
5838 
5839 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
5840 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5841 		drvname = NULL;
5842 		if (MptCallbacks[ii]) {
5843 			switch (MptDriverClass[ii]) {
5844 			case MPTSPI_DRIVER:
5845 				if (!scsi++) drvname = "SPI host";
5846 				break;
5847 			case MPTFC_DRIVER:
5848 				if (!fc++) drvname = "FC host";
5849 				break;
5850 			case MPTSAS_DRIVER:
5851 				if (!sas++) drvname = "SAS host";
5852 				break;
5853 			case MPTLAN_DRIVER:
5854 				if (!lan++) drvname = "LAN";
5855 				break;
5856 			case MPTSTM_DRIVER:
5857 				if (!targ++) drvname = "SCSI target";
5858 				break;
5859 			case MPTCTL_DRIVER:
5860 				if (!ctl++) drvname = "ioctl";
5861 				break;
5862 			}
5863 
5864 			if (drvname)
5865 				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5866 		}
5867 	}
5868 
5869 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5870 }
5871 
5872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5873 /**
5874  *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5875  *	@buf: Pointer to area to write information
5876  *	@start: Pointer to start pointer
5877  *	@offset: Offset to start writing
5878  *	@request: Amount of read data requested
5879  *	@eof: Pointer to EOF integer
5880  *	@data: Pointer
5881  *
5882  *	Returns number of characters written to process performing the read.
5883  */
5884 static int
5885 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5886 {
5887 	MPT_ADAPTER	*ioc = data;
5888 	int		 len;
5889 	char		 expVer[32];
5890 	int		 sz;
5891 	int		 p;
5892 
5893 	mpt_get_fw_exp_ver(expVer, ioc);
5894 
5895 	len = sprintf(buf, "%s:", ioc->name);
5896 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5897 		len += sprintf(buf+len, "  (f/w download boot flag set)");
5898 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5899 //		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
5900 
5901 	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
5902 			ioc->facts.ProductID,
5903 			ioc->prod_name);
5904 	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5905 	if (ioc->facts.FWImageSize)
5906 		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5907 	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5908 	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5909 	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
5910 
5911 	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
5912 			ioc->facts.CurrentHostMfaHighAddr);
5913 	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
5914 			ioc->facts.CurrentSenseBufferHighAddr);
5915 
5916 	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5917 	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5918 
5919 	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5920 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5921 	/*
5922 	 *  Rounding UP to nearest 4-kB boundary here...
5923 	 */
5924 	sz = (ioc->req_sz * ioc->req_depth) + 128;
5925 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5926 	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5927 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5928 	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
5929 					4*ioc->facts.RequestFrameSize,
5930 					ioc->facts.GlobalCredits);
5931 
5932 	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
5933 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5934 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5935 	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5936 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5937 	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
5938 					ioc->facts.CurReplyFrameSize,
5939 					ioc->facts.ReplyQueueDepth);
5940 
5941 	len += sprintf(buf+len, "  MaxDevices = %d\n",
5942 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5943 	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
5944 
5945 	/* per-port info */
5946 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5947 		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
5948 				p+1,
5949 				ioc->facts.NumberOfPorts);
5950 		if (ioc->bus_type == FC) {
5951 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5952 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5953 				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5954 						a[5], a[4], a[3], a[2], a[1], a[0]);
5955 			}
5956 			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
5957 					ioc->fc_port_page0[p].WWNN.High,
5958 					ioc->fc_port_page0[p].WWNN.Low,
5959 					ioc->fc_port_page0[p].WWPN.High,
5960 					ioc->fc_port_page0[p].WWPN.Low);
5961 		}
5962 	}
5963 
5964 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5965 }
5966 
5967 #endif		/* CONFIG_PROC_FS } */
5968 
5969 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5970 static void
5971 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5972 {
5973 	buf[0] ='\0';
5974 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5975 		sprintf(buf, " (Exp %02d%02d)",
5976 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
5977 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
5978 
5979 		/* insider hack! */
5980 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5981 			strcat(buf, " [MDBG]");
5982 	}
5983 }
5984 
5985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5986 /**
5987  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5988  *	@ioc: Pointer to MPT_ADAPTER structure
5989  *	@buffer: Pointer to buffer where IOC summary info should be written
5990  *	@size: Pointer to number of bytes we wrote (set by this routine)
5991  *	@len: Offset at which to start writing in buffer
5992  *	@showlan: Display LAN stuff?
5993  *
5994  *	This routine writes (english readable) ASCII text, which represents
5995  *	a summary of IOC information, to a buffer.
5996  */
5997 void
5998 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5999 {
6000 	char expVer[32];
6001 	int y;
6002 
6003 	mpt_get_fw_exp_ver(expVer, ioc);
6004 
6005 	/*
6006 	 *  Shorter summary of attached ioc's...
6007 	 */
6008 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6009 			ioc->name,
6010 			ioc->prod_name,
6011 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6012 			ioc->facts.FWVersion.Word,
6013 			expVer,
6014 			ioc->facts.NumberOfPorts,
6015 			ioc->req_depth);
6016 
6017 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6018 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6019 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6020 			a[5], a[4], a[3], a[2], a[1], a[0]);
6021 	}
6022 
6023 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6024 
6025 	if (!ioc->active)
6026 		y += sprintf(buffer+len+y, " (disabled)");
6027 
6028 	y += sprintf(buffer+len+y, "\n");
6029 
6030 	*size = y;
6031 }
6032 
6033 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6034 /*
6035  *	Reset Handling
6036  */
6037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6038 /**
6039  *	mpt_HardResetHandler - Generic reset handler
6040  *	@ioc: Pointer to MPT_ADAPTER structure
6041  *	@sleepFlag: Indicates if sleep or schedule must be called.
6042  *
6043  *	Issues SCSI Task Management call based on input arg values.
6044  *	If TaskMgmt fails, returns associated SCSI request.
6045  *
6046  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6047  *	or a non-interrupt thread.  In the former, must not call schedule().
6048  *
6049  *	Note: A return of -1 is a FATAL error case, as it means a
6050  *	FW reload/initialization failed.
6051  *
6052  *	Returns 0 for SUCCESS or -1 if FAILED.
6053  */
6054 int
6055 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6056 {
6057 	int		 rc;
6058 	unsigned long	 flags;
6059 
6060 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6061 #ifdef MFCNT
6062 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6063 	printk("MF count 0x%x !\n", ioc->mfcnt);
6064 #endif
6065 
6066 	/* Reset the adapter. Prevent more than 1 call to
6067 	 * mpt_do_ioc_recovery at any instant in time.
6068 	 */
6069 	spin_lock_irqsave(&ioc->diagLock, flags);
6070 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6071 		spin_unlock_irqrestore(&ioc->diagLock, flags);
6072 		return 0;
6073 	} else {
6074 		ioc->diagPending = 1;
6075 	}
6076 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6077 
6078 	/* FIXME: If do_ioc_recovery fails, repeat....
6079 	 */
6080 
6081 	/* The SCSI driver needs to adjust timeouts on all current
6082 	 * commands prior to the diagnostic reset being issued.
6083 	 * Prevents timeouts occurring during a diagnostic reset...very bad.
6084 	 * For all other protocol drivers, this is a no-op.
6085 	 */
6086 	{
6087 		int	 ii;
6088 		int	 r = 0;
6089 
6090 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6091 			if (MptResetHandlers[ii]) {
6092 				dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6093 						ioc->name, ii));
6094 				r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
6095 				if (ioc->alt_ioc) {
6096 					dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6097 							ioc->name, ioc->alt_ioc->name, ii));
6098 					r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6099 				}
6100 			}
6101 		}
6102 	}
6103 
6104 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6105 		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6106 			rc, ioc->name);
6107 	}
6108 	ioc->reload_fw = 0;
6109 	if (ioc->alt_ioc)
6110 		ioc->alt_ioc->reload_fw = 0;
6111 
6112 	spin_lock_irqsave(&ioc->diagLock, flags);
6113 	ioc->diagPending = 0;
6114 	if (ioc->alt_ioc)
6115 		ioc->alt_ioc->diagPending = 0;
6116 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6117 
6118 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6119 
6120 	return rc;
6121 }
6122 
6123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6124 static void
6125 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6126 {
6127 	char *ds = NULL;
6128 
6129 	switch(event) {
6130 	case MPI_EVENT_NONE:
6131 		ds = "None";
6132 		break;
6133 	case MPI_EVENT_LOG_DATA:
6134 		ds = "Log Data";
6135 		break;
6136 	case MPI_EVENT_STATE_CHANGE:
6137 		ds = "State Change";
6138 		break;
6139 	case MPI_EVENT_UNIT_ATTENTION:
6140 		ds = "Unit Attention";
6141 		break;
6142 	case MPI_EVENT_IOC_BUS_RESET:
6143 		ds = "IOC Bus Reset";
6144 		break;
6145 	case MPI_EVENT_EXT_BUS_RESET:
6146 		ds = "External Bus Reset";
6147 		break;
6148 	case MPI_EVENT_RESCAN:
6149 		ds = "Bus Rescan Event";
6150 		break;
6151 	case MPI_EVENT_LINK_STATUS_CHANGE:
6152 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6153 			ds = "Link Status(FAILURE) Change";
6154 		else
6155 			ds = "Link Status(ACTIVE) Change";
6156 		break;
6157 	case MPI_EVENT_LOOP_STATE_CHANGE:
6158 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6159 			ds = "Loop State(LIP) Change";
6160 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6161 			ds = "Loop State(LPE) Change";		/* ??? */
6162 		else
6163 			ds = "Loop State(LPB) Change";		/* ??? */
6164 		break;
6165 	case MPI_EVENT_LOGOUT:
6166 		ds = "Logout";
6167 		break;
6168 	case MPI_EVENT_EVENT_CHANGE:
6169 		if (evData0)
6170 			ds = "Events ON";
6171 		else
6172 			ds = "Events OFF";
6173 		break;
6174 	case MPI_EVENT_INTEGRATED_RAID:
6175 	{
6176 		u8 ReasonCode = (u8)(evData0 >> 16);
6177 		switch (ReasonCode) {
6178 		case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6179 			ds = "Integrated Raid: Volume Created";
6180 			break;
6181 		case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6182 			ds = "Integrated Raid: Volume Deleted";
6183 			break;
6184 		case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6185 			ds = "Integrated Raid: Volume Settings Changed";
6186 			break;
6187 		case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6188 			ds = "Integrated Raid: Volume Status Changed";
6189 			break;
6190 		case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6191 			ds = "Integrated Raid: Volume Physdisk Changed";
6192 			break;
6193 		case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6194 			ds = "Integrated Raid: Physdisk Created";
6195 			break;
6196 		case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6197 			ds = "Integrated Raid: Physdisk Deleted";
6198 			break;
6199 		case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6200 			ds = "Integrated Raid: Physdisk Settings Changed";
6201 			break;
6202 		case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6203 			ds = "Integrated Raid: Physdisk Status Changed";
6204 			break;
6205 		case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6206 			ds = "Integrated Raid: Domain Validation Needed";
6207 			break;
6208 		case MPI_EVENT_RAID_RC_SMART_DATA :
6209 			ds = "Integrated Raid; Smart Data";
6210 			break;
6211 		case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6212 			ds = "Integrated Raid: Replace Action Started";
6213 			break;
6214 		default:
6215 			ds = "Integrated Raid";
6216 		break;
6217 		}
6218 		break;
6219 	}
6220 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6221 		ds = "SCSI Device Status Change";
6222 		break;
6223 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6224 	{
6225 		u8 id = (u8)(evData0);
6226 		u8 channel = (u8)(evData0 >> 8);
6227 		u8 ReasonCode = (u8)(evData0 >> 16);
6228 		switch (ReasonCode) {
6229 		case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6230 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6231 			    "SAS Device Status Change: Added: "
6232 			    "id=%d channel=%d", id, channel);
6233 			break;
6234 		case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6235 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6236 			    "SAS Device Status Change: Deleted: "
6237 			    "id=%d channel=%d", id, channel);
6238 			break;
6239 		case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6240 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6241 			    "SAS Device Status Change: SMART Data: "
6242 			    "id=%d channel=%d", id, channel);
6243 			break;
6244 		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6245 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6246 			    "SAS Device Status Change: No Persistancy: "
6247 			    "id=%d channel=%d", id, channel);
6248 			break;
6249 		case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6250 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6251 			    "SAS Device Status Change: Unsupported Device "
6252 			    "Discovered : id=%d channel=%d", id, channel);
6253 			break;
6254 		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6255 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6256 			    "SAS Device Status Change: Internal Device "
6257 			    "Reset : id=%d channel=%d", id, channel);
6258 			break;
6259 		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6260 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6261 			    "SAS Device Status Change: Internal Task "
6262 			    "Abort : id=%d channel=%d", id, channel);
6263 			break;
6264 		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6265 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6266 			    "SAS Device Status Change: Internal Abort "
6267 			    "Task Set : id=%d channel=%d", id, channel);
6268 			break;
6269 		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6270 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6271 			    "SAS Device Status Change: Internal Clear "
6272 			    "Task Set : id=%d channel=%d", id, channel);
6273 			break;
6274 		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6275 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6276 			    "SAS Device Status Change: Internal Query "
6277 			    "Task : id=%d channel=%d", id, channel);
6278 			break;
6279 		default:
6280 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6281 			    "SAS Device Status Change: Unknown: "
6282 			    "id=%d channel=%d", id, channel);
6283 			break;
6284 		}
6285 		break;
6286 	}
6287 	case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6288 		ds = "Bus Timer Expired";
6289 		break;
6290 	case MPI_EVENT_QUEUE_FULL:
6291 	{
6292 		u16 curr_depth = (u16)(evData0 >> 16);
6293 		u8 channel = (u8)(evData0 >> 8);
6294 		u8 id = (u8)(evData0);
6295 
6296 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6297 		   "Queue Full: channel=%d id=%d depth=%d",
6298 		   channel, id, curr_depth);
6299 		break;
6300 	}
6301 	case MPI_EVENT_SAS_SES:
6302 		ds = "SAS SES Event";
6303 		break;
6304 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
6305 		ds = "Persistent Table Full";
6306 		break;
6307 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
6308 	{
6309 		u8 LinkRates = (u8)(evData0 >> 8);
6310 		u8 PhyNumber = (u8)(evData0);
6311 		LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6312 			MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6313 		switch (LinkRates) {
6314 		case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6315 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6316 			   "SAS PHY Link Status: Phy=%d:"
6317 			   " Rate Unknown",PhyNumber);
6318 			break;
6319 		case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6320 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6321 			   "SAS PHY Link Status: Phy=%d:"
6322 			   " Phy Disabled",PhyNumber);
6323 			break;
6324 		case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6325 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6326 			   "SAS PHY Link Status: Phy=%d:"
6327 			   " Failed Speed Nego",PhyNumber);
6328 			break;
6329 		case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6330 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6331 			   "SAS PHY Link Status: Phy=%d:"
6332 			   " Sata OOB Completed",PhyNumber);
6333 			break;
6334 		case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6335 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6336 			   "SAS PHY Link Status: Phy=%d:"
6337 			   " Rate 1.5 Gbps",PhyNumber);
6338 			break;
6339 		case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6340 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6341 			   "SAS PHY Link Status: Phy=%d:"
6342 			   " Rate 3.0 Gpbs",PhyNumber);
6343 			break;
6344 		default:
6345 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6346 			   "SAS PHY Link Status: Phy=%d", PhyNumber);
6347 			break;
6348 		}
6349 		break;
6350 	}
6351 	case MPI_EVENT_SAS_DISCOVERY_ERROR:
6352 		ds = "SAS Discovery Error";
6353 		break;
6354 	case MPI_EVENT_IR_RESYNC_UPDATE:
6355 	{
6356 		u8 resync_complete = (u8)(evData0 >> 16);
6357 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6358 		    "IR Resync Update: Complete = %d:",resync_complete);
6359 		break;
6360 	}
6361 	case MPI_EVENT_IR2:
6362 	{
6363 		u8 ReasonCode = (u8)(evData0 >> 16);
6364 		switch (ReasonCode) {
6365 		case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6366 			ds = "IR2: LD State Changed";
6367 			break;
6368 		case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6369 			ds = "IR2: PD State Changed";
6370 			break;
6371 		case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6372 			ds = "IR2: Bad Block Table Full";
6373 			break;
6374 		case MPI_EVENT_IR2_RC_PD_INSERTED:
6375 			ds = "IR2: PD Inserted";
6376 			break;
6377 		case MPI_EVENT_IR2_RC_PD_REMOVED:
6378 			ds = "IR2: PD Removed";
6379 			break;
6380 		case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6381 			ds = "IR2: Foreign CFG Detected";
6382 			break;
6383 		case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6384 			ds = "IR2: Rebuild Medium Error";
6385 			break;
6386 		default:
6387 			ds = "IR2";
6388 		break;
6389 		}
6390 		break;
6391 	}
6392 	case MPI_EVENT_SAS_DISCOVERY:
6393 	{
6394 		if (evData0)
6395 			ds = "SAS Discovery: Start";
6396 		else
6397 			ds = "SAS Discovery: Stop";
6398 		break;
6399 	}
6400 	case MPI_EVENT_LOG_ENTRY_ADDED:
6401 		ds = "SAS Log Entry Added";
6402 		break;
6403 
6404 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6405 	{
6406 		u8 phy_num = (u8)(evData0);
6407 		u8 port_num = (u8)(evData0 >> 8);
6408 		u8 port_width = (u8)(evData0 >> 16);
6409 		u8 primative = (u8)(evData0 >> 24);
6410 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6411 		    "SAS Broadcase Primative: phy=%d port=%d "
6412 		    "width=%d primative=0x%02x",
6413 		    phy_num, port_num, port_width, primative);
6414 		break;
6415 	}
6416 
6417 	case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6418 	{
6419 		u8 reason = (u8)(evData0);
6420 		u8 port_num = (u8)(evData0 >> 8);
6421 		u16 handle = le16_to_cpu(evData0 >> 16);
6422 
6423 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6424 		    "SAS Initiator Device Status Change: reason=0x%02x "
6425 		    "port=%d handle=0x%04x",
6426 		    reason, port_num, handle);
6427 		break;
6428 	}
6429 
6430 	case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6431 	{
6432 		u8 max_init = (u8)(evData0);
6433 		u8 current_init = (u8)(evData0 >> 8);
6434 
6435 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6436 		    "SAS Initiator Device Table Overflow: max initiators=%02d "
6437 		    "current initators=%02d",
6438 		    max_init, current_init);
6439 		break;
6440 	}
6441 	case MPI_EVENT_SAS_SMP_ERROR:
6442 	{
6443 		u8 status = (u8)(evData0);
6444 		u8 port_num = (u8)(evData0 >> 8);
6445 		u8 result = (u8)(evData0 >> 16);
6446 
6447 		if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6448 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6449 			    "SAS SMP Error: port=%d result=0x%02x",
6450 			    port_num, result);
6451 		else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6452 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 			    "SAS SMP Error: port=%d : CRC Error",
6454 			    port_num);
6455 		else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6456 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6457 			    "SAS SMP Error: port=%d : Timeout",
6458 			    port_num);
6459 		else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6460 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6461 			    "SAS SMP Error: port=%d : No Destination",
6462 			    port_num);
6463 		else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6464 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6465 			    "SAS SMP Error: port=%d : Bad Destination",
6466 			    port_num);
6467 		else
6468 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6469 			    "SAS SMP Error: port=%d : status=0x%02x",
6470 			    port_num, status);
6471 		break;
6472 	}
6473 
6474 	/*
6475 	 *  MPT base "custom" events may be added here...
6476 	 */
6477 	default:
6478 		ds = "Unknown";
6479 		break;
6480 	}
6481 	if (ds)
6482 		strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6483 }
6484 
6485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6486 /**
6487  *	ProcessEventNotification - Route EventNotificationReply to all event handlers
6488  *	@ioc: Pointer to MPT_ADAPTER structure
6489  *	@pEventReply: Pointer to EventNotification reply frame
6490  *	@evHandlers: Pointer to integer, number of event handlers
6491  *
6492  *	Routes a received EventNotificationReply to all currently registered
6493  *	event handlers.
6494  *	Returns sum of event handlers return values.
6495  */
6496 static int
6497 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6498 {
6499 	u16 evDataLen;
6500 	u32 evData0 = 0;
6501 //	u32 evCtx;
6502 	int ii;
6503 	int r = 0;
6504 	int handlers = 0;
6505 	char evStr[EVENT_DESCR_STR_SZ];
6506 	u8 event;
6507 
6508 	/*
6509 	 *  Do platform normalization of values
6510 	 */
6511 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
6512 //	evCtx = le32_to_cpu(pEventReply->EventContext);
6513 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6514 	if (evDataLen) {
6515 		evData0 = le32_to_cpu(pEventReply->Data[0]);
6516 	}
6517 
6518 	EventDescriptionStr(event, evData0, evStr);
6519 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6520 			ioc->name,
6521 			event,
6522 			evStr));
6523 
6524 #ifdef CONFIG_FUSION_LOGGING
6525 	devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
6526 	    ": Event data:\n"));
6527 	for (ii = 0; ii < evDataLen; ii++)
6528 		devtverboseprintk(ioc, printk(" %08x",
6529 		    le32_to_cpu(pEventReply->Data[ii])));
6530 	devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
6531 #endif
6532 
6533 	/*
6534 	 *  Do general / base driver event processing
6535 	 */
6536 	switch(event) {
6537 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
6538 		if (evDataLen) {
6539 			u8 evState = evData0 & 0xFF;
6540 
6541 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
6542 
6543 			/* Update EventState field in cached IocFacts */
6544 			if (ioc->facts.Function) {
6545 				ioc->facts.EventState = evState;
6546 			}
6547 		}
6548 		break;
6549 	case MPI_EVENT_INTEGRATED_RAID:
6550 		mptbase_raid_process_event_data(ioc,
6551 		    (MpiEventDataRaid_t *)pEventReply->Data);
6552 		break;
6553 	default:
6554 		break;
6555 	}
6556 
6557 	/*
6558 	 * Should this event be logged? Events are written sequentially.
6559 	 * When buffer is full, start again at the top.
6560 	 */
6561 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6562 		int idx;
6563 
6564 		idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6565 
6566 		ioc->events[idx].event = event;
6567 		ioc->events[idx].eventContext = ioc->eventContext;
6568 
6569 		for (ii = 0; ii < 2; ii++) {
6570 			if (ii < evDataLen)
6571 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6572 			else
6573 				ioc->events[idx].data[ii] =  0;
6574 		}
6575 
6576 		ioc->eventContext++;
6577 	}
6578 
6579 
6580 	/*
6581 	 *  Call each currently registered protocol event handler.
6582 	 */
6583 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6584 		if (MptEvHandlers[ii]) {
6585 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6586 					ioc->name, ii));
6587 			r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6588 			handlers++;
6589 		}
6590 	}
6591 	/* FIXME?  Examine results here? */
6592 
6593 	/*
6594 	 *  If needed, send (a single) EventAck.
6595 	 */
6596 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6597 		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6598 			"EventAck required\n",ioc->name));
6599 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6600 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6601 					ioc->name, ii));
6602 		}
6603 	}
6604 
6605 	*evHandlers = handlers;
6606 	return r;
6607 }
6608 
6609 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6610 /**
6611  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6612  *	@ioc: Pointer to MPT_ADAPTER structure
6613  *	@log_info: U32 LogInfo reply word from the IOC
6614  *
6615  *	Refer to lsi/mpi_log_fc.h.
6616  */
6617 static void
6618 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6619 {
6620 	char *desc = "unknown";
6621 
6622 	switch (log_info & 0xFF000000) {
6623 	case MPI_IOCLOGINFO_FC_INIT_BASE:
6624 		desc = "FCP Initiator";
6625 		break;
6626 	case MPI_IOCLOGINFO_FC_TARGET_BASE:
6627 		desc = "FCP Target";
6628 		break;
6629 	case MPI_IOCLOGINFO_FC_LAN_BASE:
6630 		desc = "LAN";
6631 		break;
6632 	case MPI_IOCLOGINFO_FC_MSG_BASE:
6633 		desc = "MPI Message Layer";
6634 		break;
6635 	case MPI_IOCLOGINFO_FC_LINK_BASE:
6636 		desc = "FC Link";
6637 		break;
6638 	case MPI_IOCLOGINFO_FC_CTX_BASE:
6639 		desc = "Context Manager";
6640 		break;
6641 	case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6642 		desc = "Invalid Field Offset";
6643 		break;
6644 	case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6645 		desc = "State Change Info";
6646 		break;
6647 	}
6648 
6649 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6650 			ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6651 }
6652 
6653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6654 /**
6655  *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6656  *	@ioc: Pointer to MPT_ADAPTER structure
6657  *	@mr: Pointer to MPT reply frame
6658  *	@log_info: U32 LogInfo word from the IOC
6659  *
6660  *	Refer to lsi/sp_log.h.
6661  */
6662 static void
6663 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6664 {
6665 	u32 info = log_info & 0x00FF0000;
6666 	char *desc = "unknown";
6667 
6668 	switch (info) {
6669 	case 0x00010000:
6670 		desc = "bug! MID not found";
6671 		if (ioc->reload_fw == 0)
6672 			ioc->reload_fw++;
6673 		break;
6674 
6675 	case 0x00020000:
6676 		desc = "Parity Error";
6677 		break;
6678 
6679 	case 0x00030000:
6680 		desc = "ASYNC Outbound Overrun";
6681 		break;
6682 
6683 	case 0x00040000:
6684 		desc = "SYNC Offset Error";
6685 		break;
6686 
6687 	case 0x00050000:
6688 		desc = "BM Change";
6689 		break;
6690 
6691 	case 0x00060000:
6692 		desc = "Msg In Overflow";
6693 		break;
6694 
6695 	case 0x00070000:
6696 		desc = "DMA Error";
6697 		break;
6698 
6699 	case 0x00080000:
6700 		desc = "Outbound DMA Overrun";
6701 		break;
6702 
6703 	case 0x00090000:
6704 		desc = "Task Management";
6705 		break;
6706 
6707 	case 0x000A0000:
6708 		desc = "Device Problem";
6709 		break;
6710 
6711 	case 0x000B0000:
6712 		desc = "Invalid Phase Change";
6713 		break;
6714 
6715 	case 0x000C0000:
6716 		desc = "Untagged Table Size";
6717 		break;
6718 
6719 	}
6720 
6721 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6722 }
6723 
6724 /* strings for sas loginfo */
6725 	static char *originator_str[] = {
6726 		"IOP",						/* 00h */
6727 		"PL",						/* 01h */
6728 		"IR"						/* 02h */
6729 	};
6730 	static char *iop_code_str[] = {
6731 		NULL,						/* 00h */
6732 		"Invalid SAS Address",				/* 01h */
6733 		NULL,						/* 02h */
6734 		"Invalid Page",					/* 03h */
6735 		"Diag Message Error",				/* 04h */
6736 		"Task Terminated",				/* 05h */
6737 		"Enclosure Management",				/* 06h */
6738 		"Target Mode"					/* 07h */
6739 	};
6740 	static char *pl_code_str[] = {
6741 		NULL,						/* 00h */
6742 		"Open Failure",					/* 01h */
6743 		"Invalid Scatter Gather List",			/* 02h */
6744 		"Wrong Relative Offset or Frame Length",	/* 03h */
6745 		"Frame Transfer Error",				/* 04h */
6746 		"Transmit Frame Connected Low",			/* 05h */
6747 		"SATA Non-NCQ RW Error Bit Set",		/* 06h */
6748 		"SATA Read Log Receive Data Error",		/* 07h */
6749 		"SATA NCQ Fail All Commands After Error",	/* 08h */
6750 		"SATA Error in Receive Set Device Bit FIS",	/* 09h */
6751 		"Receive Frame Invalid Message",		/* 0Ah */
6752 		"Receive Context Message Valid Error",		/* 0Bh */
6753 		"Receive Frame Current Frame Error",		/* 0Ch */
6754 		"SATA Link Down",				/* 0Dh */
6755 		"Discovery SATA Init W IOS",			/* 0Eh */
6756 		"Config Invalid Page",				/* 0Fh */
6757 		"Discovery SATA Init Timeout",			/* 10h */
6758 		"Reset",					/* 11h */
6759 		"Abort",					/* 12h */
6760 		"IO Not Yet Executed",				/* 13h */
6761 		"IO Executed",					/* 14h */
6762 		"Persistent Reservation Out Not Affiliation "
6763 		    "Owner", 					/* 15h */
6764 		"Open Transmit DMA Abort",			/* 16h */
6765 		"IO Device Missing Delay Retry",		/* 17h */
6766 		"IO Cancelled Due to Recieve Error",		/* 18h */
6767 		NULL,						/* 19h */
6768 		NULL,						/* 1Ah */
6769 		NULL,						/* 1Bh */
6770 		NULL,						/* 1Ch */
6771 		NULL,						/* 1Dh */
6772 		NULL,						/* 1Eh */
6773 		NULL,						/* 1Fh */
6774 		"Enclosure Management"				/* 20h */
6775 	};
6776 	static char *ir_code_str[] = {
6777 		"Raid Action Error",				/* 00h */
6778 		NULL,						/* 00h */
6779 		NULL,						/* 01h */
6780 		NULL,						/* 02h */
6781 		NULL,						/* 03h */
6782 		NULL,						/* 04h */
6783 		NULL,						/* 05h */
6784 		NULL,						/* 06h */
6785 		NULL						/* 07h */
6786 	};
6787 	static char *raid_sub_code_str[] = {
6788 		NULL, 						/* 00h */
6789 		"Volume Creation Failed: Data Passed too "
6790 		    "Large", 					/* 01h */
6791 		"Volume Creation Failed: Duplicate Volumes "
6792 		    "Attempted", 				/* 02h */
6793 		"Volume Creation Failed: Max Number "
6794 		    "Supported Volumes Exceeded",		/* 03h */
6795 		"Volume Creation Failed: DMA Error",		/* 04h */
6796 		"Volume Creation Failed: Invalid Volume Type",	/* 05h */
6797 		"Volume Creation Failed: Error Reading "
6798 		    "MFG Page 4", 				/* 06h */
6799 		"Volume Creation Failed: Creating Internal "
6800 		    "Structures", 				/* 07h */
6801 		NULL,						/* 08h */
6802 		NULL,						/* 09h */
6803 		NULL,						/* 0Ah */
6804 		NULL,						/* 0Bh */
6805 		NULL,						/* 0Ch */
6806 		NULL,						/* 0Dh */
6807 		NULL,						/* 0Eh */
6808 		NULL,						/* 0Fh */
6809 		"Activation failed: Already Active Volume", 	/* 10h */
6810 		"Activation failed: Unsupported Volume Type", 	/* 11h */
6811 		"Activation failed: Too Many Active Volumes", 	/* 12h */
6812 		"Activation failed: Volume ID in Use", 		/* 13h */
6813 		"Activation failed: Reported Failure", 		/* 14h */
6814 		"Activation failed: Importing a Volume", 	/* 15h */
6815 		NULL,						/* 16h */
6816 		NULL,						/* 17h */
6817 		NULL,						/* 18h */
6818 		NULL,						/* 19h */
6819 		NULL,						/* 1Ah */
6820 		NULL,						/* 1Bh */
6821 		NULL,						/* 1Ch */
6822 		NULL,						/* 1Dh */
6823 		NULL,						/* 1Eh */
6824 		NULL,						/* 1Fh */
6825 		"Phys Disk failed: Too Many Phys Disks", 	/* 20h */
6826 		"Phys Disk failed: Data Passed too Large",	/* 21h */
6827 		"Phys Disk failed: DMA Error", 			/* 22h */
6828 		"Phys Disk failed: Invalid <channel:id>", 	/* 23h */
6829 		"Phys Disk failed: Creating Phys Disk Config "
6830 		    "Page", 					/* 24h */
6831 		NULL,						/* 25h */
6832 		NULL,						/* 26h */
6833 		NULL,						/* 27h */
6834 		NULL,						/* 28h */
6835 		NULL,						/* 29h */
6836 		NULL,						/* 2Ah */
6837 		NULL,						/* 2Bh */
6838 		NULL,						/* 2Ch */
6839 		NULL,						/* 2Dh */
6840 		NULL,						/* 2Eh */
6841 		NULL,						/* 2Fh */
6842 		"Compatibility Error: IR Disabled",		/* 30h */
6843 		"Compatibility Error: Inquiry Comand Failed",	/* 31h */
6844 		"Compatibility Error: Device not Direct Access "
6845 		    "Device ",					/* 32h */
6846 		"Compatibility Error: Removable Device Found",	/* 33h */
6847 		"Compatibility Error: Device SCSI Version not "
6848 		    "2 or Higher", 				/* 34h */
6849 		"Compatibility Error: SATA Device, 48 BIT LBA "
6850 		    "not Supported", 				/* 35h */
6851 		"Compatibility Error: Device doesn't have "
6852 		    "512 Byte Block Sizes", 			/* 36h */
6853 		"Compatibility Error: Volume Type Check Failed", /* 37h */
6854 		"Compatibility Error: Volume Type is "
6855 		    "Unsupported by FW", 			/* 38h */
6856 		"Compatibility Error: Disk Drive too Small for "
6857 		    "use in Volume", 				/* 39h */
6858 		"Compatibility Error: Phys Disk for Create "
6859 		    "Volume not Found", 			/* 3Ah */
6860 		"Compatibility Error: Too Many or too Few "
6861 		    "Disks for Volume Type", 			/* 3Bh */
6862 		"Compatibility Error: Disk stripe Sizes "
6863 		    "Must be 64KB", 				/* 3Ch */
6864 		"Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6865 	};
6866 
6867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6868 /**
6869  *	mpt_sas_log_info - Log information returned from SAS IOC.
6870  *	@ioc: Pointer to MPT_ADAPTER structure
6871  *	@log_info: U32 LogInfo reply word from the IOC
6872  *
6873  *	Refer to lsi/mpi_log_sas.h.
6874  **/
6875 static void
6876 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6877 {
6878 union loginfo_type {
6879 	u32	loginfo;
6880 	struct {
6881 		u32	subcode:16;
6882 		u32	code:8;
6883 		u32	originator:4;
6884 		u32	bus_type:4;
6885 	}dw;
6886 };
6887 	union loginfo_type sas_loginfo;
6888 	char *originator_desc = NULL;
6889 	char *code_desc = NULL;
6890 	char *sub_code_desc = NULL;
6891 
6892 	sas_loginfo.loginfo = log_info;
6893 	if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6894 	    (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6895 		return;
6896 
6897 	originator_desc = originator_str[sas_loginfo.dw.originator];
6898 
6899 	switch (sas_loginfo.dw.originator) {
6900 
6901 		case 0:  /* IOP */
6902 			if (sas_loginfo.dw.code <
6903 			    sizeof(iop_code_str)/sizeof(char*))
6904 				code_desc = iop_code_str[sas_loginfo.dw.code];
6905 			break;
6906 		case 1:  /* PL */
6907 			if (sas_loginfo.dw.code <
6908 			    sizeof(pl_code_str)/sizeof(char*))
6909 				code_desc = pl_code_str[sas_loginfo.dw.code];
6910 			break;
6911 		case 2:  /* IR */
6912 			if (sas_loginfo.dw.code >=
6913 			    sizeof(ir_code_str)/sizeof(char*))
6914 				break;
6915 			code_desc = ir_code_str[sas_loginfo.dw.code];
6916 			if (sas_loginfo.dw.subcode >=
6917 			    sizeof(raid_sub_code_str)/sizeof(char*))
6918 			break;
6919 			if (sas_loginfo.dw.code == 0)
6920 				sub_code_desc =
6921 				    raid_sub_code_str[sas_loginfo.dw.subcode];
6922 			break;
6923 		default:
6924 			return;
6925 	}
6926 
6927 	if (sub_code_desc != NULL)
6928 		printk(MYIOC_s_INFO_FMT
6929 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
6930 			" SubCode={%s}\n",
6931 			ioc->name, log_info, originator_desc, code_desc,
6932 			sub_code_desc);
6933 	else if (code_desc != NULL)
6934 		printk(MYIOC_s_INFO_FMT
6935 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
6936 			" SubCode(0x%04x)\n",
6937 			ioc->name, log_info, originator_desc, code_desc,
6938 			sas_loginfo.dw.subcode);
6939 	else
6940 		printk(MYIOC_s_INFO_FMT
6941 			"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6942 			" SubCode(0x%04x)\n",
6943 			ioc->name, log_info, originator_desc,
6944 			sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6945 }
6946 
6947 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6948 /**
6949  *	mpt_iocstatus_info_config - IOCSTATUS information for config pages
6950  *	@ioc: Pointer to MPT_ADAPTER structure
6951  *	@ioc_status: U32 IOCStatus word from IOC
6952  *	@mf: Pointer to MPT request frame
6953  *
6954  *	Refer to lsi/mpi.h.
6955  **/
6956 static void
6957 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6958 {
6959 	Config_t *pReq = (Config_t *)mf;
6960 	char extend_desc[EVENT_DESCR_STR_SZ];
6961 	char *desc = NULL;
6962 	u32 form;
6963 	u8 page_type;
6964 
6965 	if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6966 		page_type = pReq->ExtPageType;
6967 	else
6968 		page_type = pReq->Header.PageType;
6969 
6970 	/*
6971 	 * ignore invalid page messages for GET_NEXT_HANDLE
6972 	 */
6973 	form = le32_to_cpu(pReq->PageAddress);
6974 	if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6975 		if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6976 		    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6977 		    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6978 			if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6979 				MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6980 				return;
6981 		}
6982 		if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6983 			if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6984 				MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6985 				return;
6986 	}
6987 
6988 	snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6989 	    "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6990 	    page_type, pReq->Header.PageNumber, pReq->Action, form);
6991 
6992 	switch (ioc_status) {
6993 
6994 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6995 		desc = "Config Page Invalid Action";
6996 		break;
6997 
6998 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
6999 		desc = "Config Page Invalid Type";
7000 		break;
7001 
7002 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
7003 		desc = "Config Page Invalid Page";
7004 		break;
7005 
7006 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
7007 		desc = "Config Page Invalid Data";
7008 		break;
7009 
7010 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7011 		desc = "Config Page No Defaults";
7012 		break;
7013 
7014 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7015 		desc = "Config Page Can't Commit";
7016 		break;
7017 	}
7018 
7019 	if (!desc)
7020 		return;
7021 
7022 	printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7023 	    ioc->name, ioc_status, desc, extend_desc);
7024 }
7025 
7026 /**
7027  *	mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7028  *	@ioc: Pointer to MPT_ADAPTER structure
7029  *	@ioc_status: U32 IOCStatus word from IOC
7030  *	@mf: Pointer to MPT request frame
7031  *
7032  *	Refer to lsi/mpi.h.
7033  **/
7034 static void
7035 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7036 {
7037 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7038 	char *desc = NULL;
7039 
7040 	switch (status) {
7041 
7042 /****************************************************************************/
7043 /*  Common IOCStatus values for all replies                                 */
7044 /****************************************************************************/
7045 
7046 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7047 		desc = "Invalid Function";
7048 		break;
7049 
7050 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7051 		desc = "Busy";
7052 		break;
7053 
7054 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7055 		desc = "Invalid SGL";
7056 		break;
7057 
7058 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7059 		desc = "Internal Error";
7060 		break;
7061 
7062 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7063 		desc = "Reserved";
7064 		break;
7065 
7066 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7067 		desc = "Insufficient Resources";
7068 		break;
7069 
7070 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7071 		desc = "Invalid Field";
7072 		break;
7073 
7074 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7075 		desc = "Invalid State";
7076 		break;
7077 
7078 /****************************************************************************/
7079 /*  Config IOCStatus values                                                 */
7080 /****************************************************************************/
7081 
7082 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7083 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
7084 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
7085 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
7086 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7087 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7088 		mpt_iocstatus_info_config(ioc, status, mf);
7089 		break;
7090 
7091 /****************************************************************************/
7092 /*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
7093 /*                                                                          */
7094 /*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7095 /*                                                                          */
7096 /****************************************************************************/
7097 
7098 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7099 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7100 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7101 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7102 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7103 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7104 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7105 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7106 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7107 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7108 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7109 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7110 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7111 		break;
7112 
7113 /****************************************************************************/
7114 /*  SCSI Target values                                                      */
7115 /****************************************************************************/
7116 
7117 	case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7118 		desc = "Target: Priority IO";
7119 		break;
7120 
7121 	case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7122 		desc = "Target: Invalid Port";
7123 		break;
7124 
7125 	case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7126 		desc = "Target Invalid IO Index:";
7127 		break;
7128 
7129 	case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7130 		desc = "Target: Aborted";
7131 		break;
7132 
7133 	case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7134 		desc = "Target: No Conn Retryable";
7135 		break;
7136 
7137 	case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7138 		desc = "Target: No Connection";
7139 		break;
7140 
7141 	case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7142 		desc = "Target: Transfer Count Mismatch";
7143 		break;
7144 
7145 	case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7146 		desc = "Target: STS Data not Sent";
7147 		break;
7148 
7149 	case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7150 		desc = "Target: Data Offset Error";
7151 		break;
7152 
7153 	case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7154 		desc = "Target: Too Much Write Data";
7155 		break;
7156 
7157 	case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7158 		desc = "Target: IU Too Short";
7159 		break;
7160 
7161 	case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7162 		desc = "Target: ACK NAK Timeout";
7163 		break;
7164 
7165 	case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7166 		desc = "Target: Nak Received";
7167 		break;
7168 
7169 /****************************************************************************/
7170 /*  Fibre Channel Direct Access values                                      */
7171 /****************************************************************************/
7172 
7173 	case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7174 		desc = "FC: Aborted";
7175 		break;
7176 
7177 	case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7178 		desc = "FC: RX ID Invalid";
7179 		break;
7180 
7181 	case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7182 		desc = "FC: DID Invalid";
7183 		break;
7184 
7185 	case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7186 		desc = "FC: Node Logged Out";
7187 		break;
7188 
7189 	case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7190 		desc = "FC: Exchange Canceled";
7191 		break;
7192 
7193 /****************************************************************************/
7194 /*  LAN values                                                              */
7195 /****************************************************************************/
7196 
7197 	case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7198 		desc = "LAN: Device not Found";
7199 		break;
7200 
7201 	case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7202 		desc = "LAN: Device Failure";
7203 		break;
7204 
7205 	case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7206 		desc = "LAN: Transmit Error";
7207 		break;
7208 
7209 	case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7210 		desc = "LAN: Transmit Aborted";
7211 		break;
7212 
7213 	case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7214 		desc = "LAN: Receive Error";
7215 		break;
7216 
7217 	case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7218 		desc = "LAN: Receive Aborted";
7219 		break;
7220 
7221 	case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7222 		desc = "LAN: Partial Packet";
7223 		break;
7224 
7225 	case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7226 		desc = "LAN: Canceled";
7227 		break;
7228 
7229 /****************************************************************************/
7230 /*  Serial Attached SCSI values                                             */
7231 /****************************************************************************/
7232 
7233 	case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7234 		desc = "SAS: SMP Request Failed";
7235 		break;
7236 
7237 	case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7238 		desc = "SAS: SMP Data Overrun";
7239 		break;
7240 
7241 	default:
7242 		desc = "Others";
7243 		break;
7244 	}
7245 
7246 	if (!desc)
7247 		return;
7248 
7249 	printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7250 }
7251 
7252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7253 EXPORT_SYMBOL(mpt_attach);
7254 EXPORT_SYMBOL(mpt_detach);
7255 #ifdef CONFIG_PM
7256 EXPORT_SYMBOL(mpt_resume);
7257 EXPORT_SYMBOL(mpt_suspend);
7258 #endif
7259 EXPORT_SYMBOL(ioc_list);
7260 EXPORT_SYMBOL(mpt_proc_root_dir);
7261 EXPORT_SYMBOL(mpt_register);
7262 EXPORT_SYMBOL(mpt_deregister);
7263 EXPORT_SYMBOL(mpt_event_register);
7264 EXPORT_SYMBOL(mpt_event_deregister);
7265 EXPORT_SYMBOL(mpt_reset_register);
7266 EXPORT_SYMBOL(mpt_reset_deregister);
7267 EXPORT_SYMBOL(mpt_device_driver_register);
7268 EXPORT_SYMBOL(mpt_device_driver_deregister);
7269 EXPORT_SYMBOL(mpt_get_msg_frame);
7270 EXPORT_SYMBOL(mpt_put_msg_frame);
7271 EXPORT_SYMBOL(mpt_free_msg_frame);
7272 EXPORT_SYMBOL(mpt_add_sge);
7273 EXPORT_SYMBOL(mpt_send_handshake_request);
7274 EXPORT_SYMBOL(mpt_verify_adapter);
7275 EXPORT_SYMBOL(mpt_GetIocState);
7276 EXPORT_SYMBOL(mpt_print_ioc_summary);
7277 EXPORT_SYMBOL(mpt_lan_index);
7278 EXPORT_SYMBOL(mpt_stm_index);
7279 EXPORT_SYMBOL(mpt_HardResetHandler);
7280 EXPORT_SYMBOL(mpt_config);
7281 EXPORT_SYMBOL(mpt_findImVolumes);
7282 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7283 EXPORT_SYMBOL(mpt_free_fw_memory);
7284 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7285 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7286 
7287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7288 /**
7289  *	fusion_init - Fusion MPT base driver initialization routine.
7290  *
7291  *	Returns 0 for success, non-zero for failure.
7292  */
7293 static int __init
7294 fusion_init(void)
7295 {
7296 	int i;
7297 
7298 	show_mptmod_ver(my_NAME, my_VERSION);
7299 	printk(KERN_INFO COPYRIGHT "\n");
7300 
7301 	for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7302 		MptCallbacks[i] = NULL;
7303 		MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7304 		MptEvHandlers[i] = NULL;
7305 		MptResetHandlers[i] = NULL;
7306 	}
7307 
7308 	/*  Register ourselves (mptbase) in order to facilitate
7309 	 *  EventNotification handling.
7310 	 */
7311 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7312 
7313 	/* Register for hard reset handling callbacks.
7314 	 */
7315 	mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7316 
7317 #ifdef CONFIG_PROC_FS
7318 	(void) procmpt_create();
7319 #endif
7320 	return 0;
7321 }
7322 
7323 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7324 /**
7325  *	fusion_exit - Perform driver unload cleanup.
7326  *
7327  *	This routine frees all resources associated with each MPT adapter
7328  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
7329  */
7330 static void __exit
7331 fusion_exit(void)
7332 {
7333 
7334 	mpt_reset_deregister(mpt_base_index);
7335 
7336 #ifdef CONFIG_PROC_FS
7337 	procmpt_destroy();
7338 #endif
7339 }
7340 
7341 module_init(fusion_init);
7342 module_exit(fusion_exit);
7343