xref: /openbmc/linux/drivers/message/fusion/mptbase.c (revision ef1d8df72fce074584244a8e3c4ae91606ccd784)
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 #ifdef MFCNT
91 static int mfcounter = 0;
92 #define PRINT_MF_COUNT 20000
93 #endif
94 
95 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
96 /*
97  *  Public data...
98  */
99 int mpt_lan_index = -1;
100 int mpt_stm_index = -1;
101 
102 struct proc_dir_entry *mpt_proc_root_dir;
103 
104 #define WHOINIT_UNKNOWN		0xAA
105 
106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
107 /*
108  *  Private data...
109  */
110 					/* Adapter link list */
111 LIST_HEAD(ioc_list);
112 					/* Callback lookup table */
113 static MPT_CALLBACK		 MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
114 					/* Protocol driver class lookup table */
115 static int			 MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
116 					/* Event handler lookup table */
117 static MPT_EVHANDLER		 MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
118 					/* Reset handler lookup table */
119 static MPT_RESETHANDLER		 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
120 static struct mpt_pci_driver 	*MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
121 
122 static int	mpt_base_index = -1;
123 static int	last_drv_idx = -1;
124 
125 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
126 
127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
128 /*
129  *  Forward protos...
130  */
131 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
132 static int	mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
133 static int	mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
134 			u32 *req, int replyBytes, u16 *u16reply, int maxwait,
135 			int sleepFlag);
136 static int	mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
137 static void	mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
138 static void	mpt_adapter_disable(MPT_ADAPTER *ioc);
139 static void	mpt_adapter_dispose(MPT_ADAPTER *ioc);
140 
141 static void	MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
142 static int	MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
143 static int	GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
144 static int	GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
145 static int	SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
146 static int	SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
147 static int	mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
148 static int	mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
149 static int	mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
150 static int	KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
151 static int	SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
152 static int	PrimeIocFifos(MPT_ADAPTER *ioc);
153 static int	WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
155 static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
156 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
157 static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
158 int		mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
159 static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
160 static int	mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
161 static void 	mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
162 static void 	mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
163 static void	mpt_timer_expired(unsigned long data);
164 static void	mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
165 static int	SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
166 static int	SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
167 static int	mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
168 static int	mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
169 
170 #ifdef CONFIG_PROC_FS
171 static int	procmpt_summary_read(char *buf, char **start, off_t offset,
172 				int request, int *eof, void *data);
173 static int	procmpt_version_read(char *buf, char **start, off_t offset,
174 				int request, int *eof, void *data);
175 static int	procmpt_iocinfo_read(char *buf, char **start, off_t offset,
176 				int request, int *eof, void *data);
177 #endif
178 static void	mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
179 
180 //int		mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
181 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
182 #ifdef MPT_DEBUG_REPLY
183 static void	mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
184 #endif
185 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
186 static void	mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
187 static void	mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
188 static int	mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
189 static void	mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
190 
191 /* module entry point */
192 static int  __init    fusion_init  (void);
193 static void __exit    fusion_exit  (void);
194 
195 #define CHIPREG_READ32(addr) 		readl_relaxed(addr)
196 #define CHIPREG_READ32_dmasync(addr)	readl(addr)
197 #define CHIPREG_WRITE32(addr,val) 	writel(val, addr)
198 #define CHIPREG_PIO_WRITE32(addr,val)	outl(val, (unsigned long)addr)
199 #define CHIPREG_PIO_READ32(addr) 	inl((unsigned long)addr)
200 
201 static void
202 pci_disable_io_access(struct pci_dev *pdev)
203 {
204 	u16 command_reg;
205 
206 	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
207 	command_reg &= ~1;
208 	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
209 }
210 
211 static void
212 pci_enable_io_access(struct pci_dev *pdev)
213 {
214 	u16 command_reg;
215 
216 	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
217 	command_reg |= 1;
218 	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
219 }
220 
221 /*
222  *  Process turbo (context) reply...
223  */
224 static void
225 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
226 {
227 	MPT_FRAME_HDR *mf = NULL;
228 	MPT_FRAME_HDR *mr = NULL;
229 	int req_idx = 0;
230 	int cb_idx;
231 
232 	dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
233 				ioc->name, pa));
234 
235 	switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
236 	case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
237 		req_idx = pa & 0x0000FFFF;
238 		cb_idx = (pa & 0x00FF0000) >> 16;
239 		mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
240 		break;
241 	case MPI_CONTEXT_REPLY_TYPE_LAN:
242 		cb_idx = mpt_lan_index;
243 		/*
244 		 *  Blind set of mf to NULL here was fatal
245 		 *  after lan_reply says "freeme"
246 		 *  Fix sort of combined with an optimization here;
247 		 *  added explicit check for case where lan_reply
248 		 *  was just returning 1 and doing nothing else.
249 		 *  For this case skip the callback, but set up
250 		 *  proper mf value first here:-)
251 		 */
252 		if ((pa & 0x58000000) == 0x58000000) {
253 			req_idx = pa & 0x0000FFFF;
254 			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
255 			mpt_free_msg_frame(ioc, mf);
256 			mb();
257 			return;
258 			break;
259 		}
260 		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
261 		break;
262 	case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
263 		cb_idx = mpt_stm_index;
264 		mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
265 		break;
266 	default:
267 		cb_idx = 0;
268 		BUG();
269 	}
270 
271 	/*  Check for (valid) IO callback!  */
272 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
273 			MptCallbacks[cb_idx] == NULL) {
274 		printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
275 				__FUNCTION__, ioc->name, cb_idx);
276 		goto out;
277 	}
278 
279 	if (MptCallbacks[cb_idx](ioc, mf, mr))
280 		mpt_free_msg_frame(ioc, mf);
281  out:
282 	mb();
283 }
284 
285 static void
286 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
287 {
288 	MPT_FRAME_HDR	*mf;
289 	MPT_FRAME_HDR	*mr;
290 	int		 req_idx;
291 	int		 cb_idx;
292 	int		 freeme;
293 
294 	u32 reply_dma_low;
295 	u16 ioc_stat;
296 
297 	/* non-TURBO reply!  Hmmm, something may be up...
298 	 *  Newest turbo reply mechanism; get address
299 	 *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
300 	 */
301 
302 	/* Map DMA address of reply header to cpu address.
303 	 * pa is 32 bits - but the dma address may be 32 or 64 bits
304 	 * get offset based only only the low addresses
305 	 */
306 
307 	reply_dma_low = (pa <<= 1);
308 	mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
309 			 (reply_dma_low - ioc->reply_frames_low_dma));
310 
311 	req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
312 	cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
313 	mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
314 
315 	dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
316 			ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
317 	DBG_DUMP_REPLY_FRAME(mr)
318 
319 	 /*  Check/log IOC log info
320 	 */
321 	ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
322 	if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
323 		u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
324 		if (ioc->bus_type == FC)
325 			mpt_fc_log_info(ioc, log_info);
326 		else if (ioc->bus_type == SPI)
327 			mpt_spi_log_info(ioc, log_info);
328 		else if (ioc->bus_type == SAS)
329 			mpt_sas_log_info(ioc, log_info);
330 	}
331 
332 #ifdef MPT_DEBUG_REPLY
333 	if (ioc_stat & MPI_IOCSTATUS_MASK)
334 		mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
335 #endif
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((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
418 
419 #if defined(MPT_DEBUG_MSG_FRAME)
420 	if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
421 		dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
422 		DBG_DUMP_REQUEST_FRAME_HDR(mf)
423 	}
424 #endif
425 
426 	func = reply->u.hdr.Function;
427 	dmfprintk((MYIOC_s_INFO_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((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((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((MYIOC_s_INFO_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((MYIOC_s_INFO_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((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((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 #ifdef MPT_DEBUG_MSG_FRAME
824 	{
825 		u32	*m = mf->u.frame.hwhdr.__hdr;
826 		int	 ii, n;
827 
828 		printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
829 				ioc->name, m);
830 		n = ioc->req_sz/4 - 1;
831 		while (m[n] == 0)
832 			n--;
833 		for (ii=0; ii<=n; ii++) {
834 			if (ii && ((ii%8)==0))
835 				printk("\n" KERN_INFO " ");
836 			printk(" %08x", le32_to_cpu(m[ii]));
837 		}
838 		printk("\n");
839 	}
840 #endif
841 
842 	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
843 	dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
844 	CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
845 }
846 
847 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
848 /**
849  *	mpt_free_msg_frame - Place MPT request frame back on FreeQ.
850  *	@handle: Handle of registered MPT protocol driver
851  *	@ioc: Pointer to MPT adapter structure
852  *	@mf: Pointer to MPT request frame
853  *
854  *	This routine places a MPT request frame back on the MPT adapter's
855  *	FreeQ.
856  */
857 void
858 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
859 {
860 	unsigned long flags;
861 
862 	/*  Put Request back on FreeQ!  */
863 	spin_lock_irqsave(&ioc->FreeQlock, flags);
864 	mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
865 	list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
866 #ifdef MFCNT
867 	ioc->mfcnt--;
868 #endif
869 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
870 }
871 
872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
873 /**
874  *	mpt_add_sge - Place a simple SGE at address pAddr.
875  *	@pAddr: virtual address for SGE
876  *	@flagslength: SGE flags and data transfer length
877  *	@dma_addr: Physical address
878  *
879  *	This routine places a MPT request frame back on the MPT adapter's
880  *	FreeQ.
881  */
882 void
883 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
884 {
885 	if (sizeof(dma_addr_t) == sizeof(u64)) {
886 		SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
887 		u32 tmp = dma_addr & 0xFFFFFFFF;
888 
889 		pSge->FlagsLength = cpu_to_le32(flagslength);
890 		pSge->Address.Low = cpu_to_le32(tmp);
891 		tmp = (u32) ((u64)dma_addr >> 32);
892 		pSge->Address.High = cpu_to_le32(tmp);
893 
894 	} else {
895 		SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
896 		pSge->FlagsLength = cpu_to_le32(flagslength);
897 		pSge->Address = cpu_to_le32(dma_addr);
898 	}
899 }
900 
901 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
902 /**
903  *	mpt_send_handshake_request - Send MPT request via doorbell handshake method.
904  *	@handle: Handle of registered MPT protocol driver
905  *	@ioc: Pointer to MPT adapter structure
906  *	@reqBytes: Size of the request in bytes
907  *	@req: Pointer to MPT request frame
908  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
909  *
910  *	This routine is used exclusively to send MptScsiTaskMgmt
911  *	requests since they are required to be sent via doorbell handshake.
912  *
913  *	NOTE: It is the callers responsibility to byte-swap fields in the
914  *	request which are greater than 1 byte in size.
915  *
916  *	Returns 0 for success, non-zero for failure.
917  */
918 int
919 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
920 {
921 	int	r = 0;
922 	u8	*req_as_bytes;
923 	int	 ii;
924 
925 	/* State is known to be good upon entering
926 	 * this function so issue the bus reset
927 	 * request.
928 	 */
929 
930 	/*
931 	 * Emulate what mpt_put_msg_frame() does /wrt to sanity
932 	 * setting cb_idx/req_idx.  But ONLY if this request
933 	 * is in proper (pre-alloc'd) request buffer range...
934 	 */
935 	ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
936 	if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
937 		MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
938 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
939 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
940 	}
941 
942 	/* Make sure there are no doorbells */
943 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
944 
945 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
946 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
947 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
948 
949 	/* Wait for IOC doorbell int */
950 	if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
951 		return ii;
952 	}
953 
954 	/* Read doorbell and check for active bit */
955 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
956 		return -5;
957 
958 	dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
959 		ioc->name, ii));
960 
961 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
962 
963 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
964 		return -2;
965 	}
966 
967 	/* Send request via doorbell handshake */
968 	req_as_bytes = (u8 *) req;
969 	for (ii = 0; ii < reqBytes/4; ii++) {
970 		u32 word;
971 
972 		word = ((req_as_bytes[(ii*4) + 0] <<  0) |
973 			(req_as_bytes[(ii*4) + 1] <<  8) |
974 			(req_as_bytes[(ii*4) + 2] << 16) |
975 			(req_as_bytes[(ii*4) + 3] << 24));
976 		CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
977 		if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
978 			r = -3;
979 			break;
980 		}
981 	}
982 
983 	if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
984 		r = 0;
985 	else
986 		r = -4;
987 
988 	/* Make sure there are no doorbells */
989 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
990 
991 	return r;
992 }
993 
994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
995 /**
996  * mpt_host_page_access_control - control the IOC's Host Page Buffer access
997  * @ioc: Pointer to MPT adapter structure
998  * @access_control_value: define bits below
999  * @sleepFlag: Specifies whether the process can sleep
1000  *
1001  * Provides mechanism for the host driver to control the IOC's
1002  * Host Page Buffer access.
1003  *
1004  * Access Control Value - bits[15:12]
1005  * 0h Reserved
1006  * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1007  * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1008  * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1009  *
1010  * Returns 0 for success, non-zero for failure.
1011  */
1012 
1013 static int
1014 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1015 {
1016 	int	 r = 0;
1017 
1018 	/* return if in use */
1019 	if (CHIPREG_READ32(&ioc->chip->Doorbell)
1020 	    & MPI_DOORBELL_ACTIVE)
1021 	    return -1;
1022 
1023 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1024 
1025 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1026 		((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1027 		 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1028 		 (access_control_value<<12)));
1029 
1030 	/* Wait for IOC to clear Doorbell Status bit */
1031 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1032 		return -2;
1033 	}else
1034 		return 0;
1035 }
1036 
1037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1038 /**
1039  *	mpt_host_page_alloc - allocate system memory for the fw
1040  *	@ioc: Pointer to pointer to IOC adapter
1041  *	@ioc_init: Pointer to ioc init config page
1042  *
1043  *	If we already allocated memory in past, then resend the same pointer.
1044  *	Returns 0 for success, non-zero for failure.
1045  */
1046 static int
1047 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1048 {
1049 	char	*psge;
1050 	int	flags_length;
1051 	u32	host_page_buffer_sz=0;
1052 
1053 	if(!ioc->HostPageBuffer) {
1054 
1055 		host_page_buffer_sz =
1056 		    le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1057 
1058 		if(!host_page_buffer_sz)
1059 			return 0; /* fw doesn't need any host buffers */
1060 
1061 		/* spin till we get enough memory */
1062 		while(host_page_buffer_sz > 0) {
1063 
1064 			if((ioc->HostPageBuffer = pci_alloc_consistent(
1065 			    ioc->pcidev,
1066 			    host_page_buffer_sz,
1067 			    &ioc->HostPageBuffer_dma)) != NULL) {
1068 
1069 				dinitprintk((MYIOC_s_INFO_FMT
1070 				    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1071 				    ioc->name, ioc->HostPageBuffer,
1072 				    (u32)ioc->HostPageBuffer_dma,
1073 				    host_page_buffer_sz));
1074 				ioc->alloc_total += host_page_buffer_sz;
1075 				ioc->HostPageBuffer_sz = host_page_buffer_sz;
1076 				break;
1077 			}
1078 
1079 			host_page_buffer_sz -= (4*1024);
1080 		}
1081 	}
1082 
1083 	if(!ioc->HostPageBuffer) {
1084 		printk(MYIOC_s_ERR_FMT
1085 		    "Failed to alloc memory for host_page_buffer!\n",
1086 		    ioc->name);
1087 		return -999;
1088 	}
1089 
1090 	psge = (char *)&ioc_init->HostPageBufferSGE;
1091 	flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1092 	    MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1093 	    MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1094 	    MPI_SGE_FLAGS_HOST_TO_IOC |
1095 	    MPI_SGE_FLAGS_END_OF_BUFFER;
1096 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1097 	    flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1098 	}
1099 	flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1100 	flags_length |= ioc->HostPageBuffer_sz;
1101 	mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1102 	ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1103 
1104 return 0;
1105 }
1106 
1107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1108 /**
1109  *	mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1110  *	@iocid: IOC unique identifier (integer)
1111  *	@iocpp: Pointer to pointer to IOC adapter
1112  *
1113  *	Given a unique IOC identifier, set pointer to the associated MPT
1114  *	adapter structure.
1115  *
1116  *	Returns iocid and sets iocpp if iocid is found.
1117  *	Returns -1 if iocid is not found.
1118  */
1119 int
1120 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1121 {
1122 	MPT_ADAPTER *ioc;
1123 
1124 	list_for_each_entry(ioc,&ioc_list,list) {
1125 		if (ioc->id == iocid) {
1126 			*iocpp =ioc;
1127 			return iocid;
1128 		}
1129 	}
1130 
1131 	*iocpp = NULL;
1132 	return -1;
1133 }
1134 
1135 /**
1136  *	mpt_get_product_name - returns product string
1137  *	@vendor: pci vendor id
1138  *	@device: pci device id
1139  *	@revision: pci revision id
1140  *	@prod_name: string returned
1141  *
1142  *	Returns product string displayed when driver loads,
1143  *	in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1144  *
1145  **/
1146 static void
1147 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1148 {
1149 	char *product_str = NULL;
1150 
1151 	if (vendor == PCI_VENDOR_ID_BROCADE) {
1152 		switch (device)
1153 		{
1154 		case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1155 			switch (revision)
1156 			{
1157 			case 0x00:
1158 				product_str = "BRE040 A0";
1159 				break;
1160 			case 0x01:
1161 				product_str = "BRE040 A1";
1162 				break;
1163 			default:
1164 				product_str = "BRE040";
1165 				break;
1166 			}
1167 			break;
1168 		}
1169 		goto out;
1170 	}
1171 
1172 	switch (device)
1173 	{
1174 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1175 		product_str = "LSIFC909 B1";
1176 		break;
1177 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1178 		product_str = "LSIFC919 B0";
1179 		break;
1180 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1181 		product_str = "LSIFC929 B0";
1182 		break;
1183 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1184 		if (revision < 0x80)
1185 			product_str = "LSIFC919X A0";
1186 		else
1187 			product_str = "LSIFC919XL A1";
1188 		break;
1189 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1190 		if (revision < 0x80)
1191 			product_str = "LSIFC929X A0";
1192 		else
1193 			product_str = "LSIFC929XL A1";
1194 		break;
1195 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1196 		product_str = "LSIFC939X A1";
1197 		break;
1198 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1199 		product_str = "LSIFC949X A1";
1200 		break;
1201 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1202 		switch (revision)
1203 		{
1204 		case 0x00:
1205 			product_str = "LSIFC949E A0";
1206 			break;
1207 		case 0x01:
1208 			product_str = "LSIFC949E A1";
1209 			break;
1210 		default:
1211 			product_str = "LSIFC949E";
1212 			break;
1213 		}
1214 		break;
1215 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1216 		switch (revision)
1217 		{
1218 		case 0x00:
1219 			product_str = "LSI53C1030 A0";
1220 			break;
1221 		case 0x01:
1222 			product_str = "LSI53C1030 B0";
1223 			break;
1224 		case 0x03:
1225 			product_str = "LSI53C1030 B1";
1226 			break;
1227 		case 0x07:
1228 			product_str = "LSI53C1030 B2";
1229 			break;
1230 		case 0x08:
1231 			product_str = "LSI53C1030 C0";
1232 			break;
1233 		case 0x80:
1234 			product_str = "LSI53C1030T A0";
1235 			break;
1236 		case 0x83:
1237 			product_str = "LSI53C1030T A2";
1238 			break;
1239 		case 0x87:
1240 			product_str = "LSI53C1030T A3";
1241 			break;
1242 		case 0xc1:
1243 			product_str = "LSI53C1020A A1";
1244 			break;
1245 		default:
1246 			product_str = "LSI53C1030";
1247 			break;
1248 		}
1249 		break;
1250 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1251 		switch (revision)
1252 		{
1253 		case 0x03:
1254 			product_str = "LSI53C1035 A2";
1255 			break;
1256 		case 0x04:
1257 			product_str = "LSI53C1035 B0";
1258 			break;
1259 		default:
1260 			product_str = "LSI53C1035";
1261 			break;
1262 		}
1263 		break;
1264 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1265 		switch (revision)
1266 		{
1267 		case 0x00:
1268 			product_str = "LSISAS1064 A1";
1269 			break;
1270 		case 0x01:
1271 			product_str = "LSISAS1064 A2";
1272 			break;
1273 		case 0x02:
1274 			product_str = "LSISAS1064 A3";
1275 			break;
1276 		case 0x03:
1277 			product_str = "LSISAS1064 A4";
1278 			break;
1279 		default:
1280 			product_str = "LSISAS1064";
1281 			break;
1282 		}
1283 		break;
1284 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1285 		switch (revision)
1286 		{
1287 		case 0x00:
1288 			product_str = "LSISAS1064E A0";
1289 			break;
1290 		case 0x01:
1291 			product_str = "LSISAS1064E B0";
1292 			break;
1293 		case 0x02:
1294 			product_str = "LSISAS1064E B1";
1295 			break;
1296 		case 0x04:
1297 			product_str = "LSISAS1064E B2";
1298 			break;
1299 		case 0x08:
1300 			product_str = "LSISAS1064E B3";
1301 			break;
1302 		default:
1303 			product_str = "LSISAS1064E";
1304 			break;
1305 		}
1306 		break;
1307 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1308 		switch (revision)
1309 		{
1310 		case 0x00:
1311 			product_str = "LSISAS1068 A0";
1312 			break;
1313 		case 0x01:
1314 			product_str = "LSISAS1068 B0";
1315 			break;
1316 		case 0x02:
1317 			product_str = "LSISAS1068 B1";
1318 			break;
1319 		default:
1320 			product_str = "LSISAS1068";
1321 			break;
1322 		}
1323 		break;
1324 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1325 		switch (revision)
1326 		{
1327 		case 0x00:
1328 			product_str = "LSISAS1068E A0";
1329 			break;
1330 		case 0x01:
1331 			product_str = "LSISAS1068E B0";
1332 			break;
1333 		case 0x02:
1334 			product_str = "LSISAS1068E B1";
1335 			break;
1336 		case 0x04:
1337 			product_str = "LSISAS1068E B2";
1338 			break;
1339 		case 0x08:
1340 			product_str = "LSISAS1068E B3";
1341 			break;
1342 		default:
1343 			product_str = "LSISAS1068E";
1344 			break;
1345 		}
1346 		break;
1347 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1348 		switch (revision)
1349 		{
1350 		case 0x00:
1351 			product_str = "LSISAS1078 A0";
1352 			break;
1353 		case 0x01:
1354 			product_str = "LSISAS1078 B0";
1355 			break;
1356 		case 0x02:
1357 			product_str = "LSISAS1078 C0";
1358 			break;
1359 		case 0x03:
1360 			product_str = "LSISAS1078 C1";
1361 			break;
1362 		case 0x04:
1363 			product_str = "LSISAS1078 C2";
1364 			break;
1365 		default:
1366 			product_str = "LSISAS1078";
1367 			break;
1368 		}
1369 		break;
1370 	}
1371 
1372  out:
1373 	if (product_str)
1374 		sprintf(prod_name, "%s", product_str);
1375 }
1376 
1377 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1378 /**
1379  *	mpt_attach - Install a PCI intelligent MPT adapter.
1380  *	@pdev: Pointer to pci_dev structure
1381  *	@id: PCI device ID information
1382  *
1383  *	This routine performs all the steps necessary to bring the IOC of
1384  *	a MPT adapter to a OPERATIONAL state.  This includes registering
1385  *	memory regions, registering the interrupt, and allocating request
1386  *	and reply memory pools.
1387  *
1388  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1389  *	MPT adapter.
1390  *
1391  *	Returns 0 for success, non-zero for failure.
1392  *
1393  *	TODO: Add support for polled controllers
1394  */
1395 int
1396 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1397 {
1398 	MPT_ADAPTER	*ioc;
1399 	u8		__iomem *mem;
1400 	unsigned long	 mem_phys;
1401 	unsigned long	 port;
1402 	u32		 msize;
1403 	u32		 psize;
1404 	int		 ii;
1405 	int		 r = -ENODEV;
1406 	u8		 revision;
1407 	u8		 pcixcmd;
1408 	static int	 mpt_ids = 0;
1409 #ifdef CONFIG_PROC_FS
1410 	struct proc_dir_entry *dent, *ent;
1411 #endif
1412 
1413 	if (pci_enable_device(pdev))
1414 		return r;
1415 
1416 	dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1417 
1418 	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1419 		dprintk((KERN_INFO MYNAM
1420 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1421 	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1422 		printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1423 		return r;
1424 	}
1425 
1426 	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1427 		dprintk((KERN_INFO MYNAM
1428 			": Using 64 bit consistent mask\n"));
1429 	else
1430 		dprintk((KERN_INFO MYNAM
1431 			": Not using 64 bit consistent mask\n"));
1432 
1433 	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1434 	if (ioc == NULL) {
1435 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1436 		return -ENOMEM;
1437 	}
1438 	ioc->alloc_total = sizeof(MPT_ADAPTER);
1439 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
1440 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1441 
1442 	ioc->pcidev = pdev;
1443 	ioc->diagPending = 0;
1444 	spin_lock_init(&ioc->diagLock);
1445 	spin_lock_init(&ioc->initializing_hba_lock);
1446 
1447 	/* Initialize the event logging.
1448 	 */
1449 	ioc->eventTypes = 0;	/* None */
1450 	ioc->eventContext = 0;
1451 	ioc->eventLogSize = 0;
1452 	ioc->events = NULL;
1453 
1454 #ifdef MFCNT
1455 	ioc->mfcnt = 0;
1456 #endif
1457 
1458 	ioc->cached_fw = NULL;
1459 
1460 	/* Initilize SCSI Config Data structure
1461 	 */
1462 	memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1463 
1464 	/* Initialize the running configQ head.
1465 	 */
1466 	INIT_LIST_HEAD(&ioc->configQ);
1467 
1468 	/* Initialize the fc rport list head.
1469 	 */
1470 	INIT_LIST_HEAD(&ioc->fc_rports);
1471 
1472 	/* Find lookup slot. */
1473 	INIT_LIST_HEAD(&ioc->list);
1474 	ioc->id = mpt_ids++;
1475 
1476 	mem_phys = msize = 0;
1477 	port = psize = 0;
1478 	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1479 		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1480 			if (psize)
1481 				continue;
1482 			/* Get I/O space! */
1483 			port = pci_resource_start(pdev, ii);
1484 			psize = pci_resource_len(pdev,ii);
1485 		} else {
1486 			if (msize)
1487 				continue;
1488 			/* Get memmap */
1489 			mem_phys = pci_resource_start(pdev, ii);
1490 			msize = pci_resource_len(pdev,ii);
1491 		}
1492 	}
1493 	ioc->mem_size = msize;
1494 
1495 	mem = NULL;
1496 	/* Get logical ptr for PciMem0 space */
1497 	/*mem = ioremap(mem_phys, msize);*/
1498 	mem = ioremap(mem_phys, msize);
1499 	if (mem == NULL) {
1500 		printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1501 		kfree(ioc);
1502 		return -EINVAL;
1503 	}
1504 	ioc->memmap = mem;
1505 	dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1506 
1507 	dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1508 			&ioc->facts, &ioc->pfacts[0]));
1509 
1510 	ioc->mem_phys = mem_phys;
1511 	ioc->chip = (SYSIF_REGS __iomem *)mem;
1512 
1513 	/* Save Port IO values in case we need to do downloadboot */
1514 	{
1515 		u8 *pmem = (u8*)port;
1516 		ioc->pio_mem_phys = port;
1517 		ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1518 	}
1519 
1520 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1521 	mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1522 
1523 	switch (pdev->device)
1524 	{
1525 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1526 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1527 		ioc->errata_flag_1064 = 1;
1528 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1529 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1530 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1531 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1532 		ioc->bus_type = FC;
1533 		break;
1534 
1535 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1536 		if (revision < XL_929) {
1537 			/* 929X Chip Fix. Set Split transactions level
1538 		 	* for PCIX. Set MOST bits to zero.
1539 		 	*/
1540 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1541 			pcixcmd &= 0x8F;
1542 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1543 		} else {
1544 			/* 929XL Chip Fix. Set MMRBC to 0x08.
1545 		 	*/
1546 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1547 			pcixcmd |= 0x08;
1548 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1549 		}
1550 		ioc->bus_type = FC;
1551 		break;
1552 
1553 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1554 		/* 919X Chip Fix. Set Split transactions level
1555 		 * for PCIX. Set MOST bits to zero.
1556 		 */
1557 		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1558 		pcixcmd &= 0x8F;
1559 		pci_write_config_byte(pdev, 0x6a, pcixcmd);
1560 		ioc->bus_type = FC;
1561 		break;
1562 
1563 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1564 		/* 1030 Chip Fix. Disable Split transactions
1565 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1566 		 */
1567 		if (revision < C0_1030) {
1568 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1569 			pcixcmd &= 0x8F;
1570 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1571 		}
1572 
1573 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1574 		ioc->bus_type = SPI;
1575 		break;
1576 
1577 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1578 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1579 		ioc->errata_flag_1064 = 1;
1580 
1581 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1582 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1583 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1584 		ioc->bus_type = SAS;
1585 	}
1586 
1587 	if (ioc->errata_flag_1064)
1588 		pci_disable_io_access(pdev);
1589 
1590 	sprintf(ioc->name, "ioc%d", ioc->id);
1591 
1592 	spin_lock_init(&ioc->FreeQlock);
1593 
1594 	/* Disable all! */
1595 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1596 	ioc->active = 0;
1597 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1598 
1599 	/* Set lookup ptr. */
1600 	list_add_tail(&ioc->list, &ioc_list);
1601 
1602 	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1603 	 */
1604 	mpt_detect_bound_ports(ioc, pdev);
1605 
1606 	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1607 	    CAN_SLEEP)) != 0){
1608 		printk(KERN_WARNING MYNAM
1609 		  ": WARNING - %s did not initialize properly! (%d)\n",
1610 		  ioc->name, r);
1611 
1612 		list_del(&ioc->list);
1613 		if (ioc->alt_ioc)
1614 			ioc->alt_ioc->alt_ioc = NULL;
1615 		iounmap(mem);
1616 		kfree(ioc);
1617 		pci_set_drvdata(pdev, NULL);
1618 		return r;
1619 	}
1620 
1621 	/* call per device driver probe entry point */
1622 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1623 		if(MptDeviceDriverHandlers[ii] &&
1624 		  MptDeviceDriverHandlers[ii]->probe) {
1625 			MptDeviceDriverHandlers[ii]->probe(pdev,id);
1626 		}
1627 	}
1628 
1629 #ifdef CONFIG_PROC_FS
1630 	/*
1631 	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1632 	 */
1633 	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1634 	if (dent) {
1635 		ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1636 		if (ent) {
1637 			ent->read_proc = procmpt_iocinfo_read;
1638 			ent->data = ioc;
1639 		}
1640 		ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1641 		if (ent) {
1642 			ent->read_proc = procmpt_summary_read;
1643 			ent->data = ioc;
1644 		}
1645 	}
1646 #endif
1647 
1648 	return 0;
1649 }
1650 
1651 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1652 /**
1653  *	mpt_detach - Remove a PCI intelligent MPT adapter.
1654  *	@pdev: Pointer to pci_dev structure
1655  */
1656 
1657 void
1658 mpt_detach(struct pci_dev *pdev)
1659 {
1660 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
1661 	char pname[32];
1662 	int ii;
1663 
1664 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1665 	remove_proc_entry(pname, NULL);
1666 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1667 	remove_proc_entry(pname, NULL);
1668 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1669 	remove_proc_entry(pname, NULL);
1670 
1671 	/* call per device driver remove entry point */
1672 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1673 		if(MptDeviceDriverHandlers[ii] &&
1674 		  MptDeviceDriverHandlers[ii]->remove) {
1675 			MptDeviceDriverHandlers[ii]->remove(pdev);
1676 		}
1677 	}
1678 
1679 	/* Disable interrupts! */
1680 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1681 
1682 	ioc->active = 0;
1683 	synchronize_irq(pdev->irq);
1684 
1685 	/* Clear any lingering interrupt */
1686 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1687 
1688 	CHIPREG_READ32(&ioc->chip->IntStatus);
1689 
1690 	mpt_adapter_dispose(ioc);
1691 
1692 	pci_set_drvdata(pdev, NULL);
1693 }
1694 
1695 /**************************************************************************
1696  * Power Management
1697  */
1698 #ifdef CONFIG_PM
1699 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1700 /**
1701  *	mpt_suspend - Fusion MPT base driver suspend routine.
1702  *	@pdev: Pointer to pci_dev structure
1703  *	@state: new state to enter
1704  */
1705 int
1706 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1707 {
1708 	u32 device_state;
1709 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1710 
1711 	device_state=pci_choose_state(pdev, state);
1712 
1713 	printk(MYIOC_s_INFO_FMT
1714 	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1715 		ioc->name, pdev, pci_name(pdev), device_state);
1716 
1717 	pci_save_state(pdev);
1718 
1719 	/* put ioc into READY_STATE */
1720 	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1721 		printk(MYIOC_s_ERR_FMT
1722 		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
1723 	}
1724 
1725 	/* disable interrupts */
1726 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1727 	ioc->active = 0;
1728 
1729 	/* Clear any lingering interrupt */
1730 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1731 
1732 	pci_disable_device(pdev);
1733 	pci_set_power_state(pdev, device_state);
1734 
1735 	return 0;
1736 }
1737 
1738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1739 /**
1740  *	mpt_resume - Fusion MPT base driver resume routine.
1741  *	@pdev: Pointer to pci_dev structure
1742  */
1743 int
1744 mpt_resume(struct pci_dev *pdev)
1745 {
1746 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1747 	u32 device_state = pdev->current_state;
1748 	int recovery_state;
1749 	int err;
1750 
1751 	printk(MYIOC_s_INFO_FMT
1752 	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1753 		ioc->name, pdev, pci_name(pdev), device_state);
1754 
1755 	pci_set_power_state(pdev, 0);
1756 	pci_restore_state(pdev);
1757 	err = pci_enable_device(pdev);
1758 	if (err)
1759 		return err;
1760 
1761 	/* enable interrupts */
1762 	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1763 	ioc->active = 1;
1764 
1765 	printk(MYIOC_s_INFO_FMT
1766 		"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1767 		ioc->name,
1768 		(mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1769 		CHIPREG_READ32(&ioc->chip->Doorbell));
1770 
1771 	/* bring ioc to operational state */
1772 	if ((recovery_state = mpt_do_ioc_recovery(ioc,
1773 	    MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1774 		printk(MYIOC_s_INFO_FMT
1775 			"pci-resume: Cannot recover, error:[%x]\n",
1776 			ioc->name, recovery_state);
1777 	} else {
1778 		printk(MYIOC_s_INFO_FMT
1779 			"pci-resume: success\n", ioc->name);
1780 	}
1781 
1782 	return 0;
1783 }
1784 #endif
1785 
1786 static int
1787 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1788 {
1789 	if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1790 	     ioc->bus_type != SPI) ||
1791 	    (MptDriverClass[index] == MPTFC_DRIVER &&
1792 	     ioc->bus_type != FC) ||
1793 	    (MptDriverClass[index] == MPTSAS_DRIVER &&
1794 	     ioc->bus_type != SAS))
1795 		/* make sure we only call the relevant reset handler
1796 		 * for the bus */
1797 		return 0;
1798 	return (MptResetHandlers[index])(ioc, reset_phase);
1799 }
1800 
1801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1802 /**
1803  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1804  *	@ioc: Pointer to MPT adapter structure
1805  *	@reason: Event word / reason
1806  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1807  *
1808  *	This routine performs all the steps necessary to bring the IOC
1809  *	to a OPERATIONAL state.
1810  *
1811  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1812  *	MPT adapter.
1813  *
1814  *	Returns:
1815  *		 0 for success
1816  *		-1 if failed to get board READY
1817  *		-2 if READY but IOCFacts Failed
1818  *		-3 if READY but PrimeIOCFifos Failed
1819  *		-4 if READY but IOCInit Failed
1820  */
1821 static int
1822 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1823 {
1824 	int	 hard_reset_done = 0;
1825 	int	 alt_ioc_ready = 0;
1826 	int	 hard;
1827 	int	 rc=0;
1828 	int	 ii;
1829 	int	 handlers;
1830 	int	 ret = 0;
1831 	int	 reset_alt_ioc_active = 0;
1832 	int	 irq_allocated = 0;
1833 
1834 	printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1835 			ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1836 
1837 	/* Disable reply interrupts (also blocks FreeQ) */
1838 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1839 	ioc->active = 0;
1840 
1841 	if (ioc->alt_ioc) {
1842 		if (ioc->alt_ioc->active)
1843 			reset_alt_ioc_active = 1;
1844 
1845 		/* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1846 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1847 		ioc->alt_ioc->active = 0;
1848 	}
1849 
1850 	hard = 1;
1851 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1852 		hard = 0;
1853 
1854 	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1855 		if (hard_reset_done == -4) {
1856 			printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1857 					ioc->name);
1858 
1859 			if (reset_alt_ioc_active && ioc->alt_ioc) {
1860 				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1861 				dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1862 						ioc->alt_ioc->name));
1863 				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1864 				ioc->alt_ioc->active = 1;
1865 			}
1866 
1867 		} else {
1868 			printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1869 					ioc->name);
1870 		}
1871 		return -1;
1872 	}
1873 
1874 	/* hard_reset_done = 0 if a soft reset was performed
1875 	 * and 1 if a hard reset was performed.
1876 	 */
1877 	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1878 		if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1879 			alt_ioc_ready = 1;
1880 		else
1881 			printk(KERN_WARNING MYNAM
1882 					": alt-%s: Not ready WARNING!\n",
1883 					ioc->alt_ioc->name);
1884 	}
1885 
1886 	for (ii=0; ii<5; ii++) {
1887 		/* Get IOC facts! Allow 5 retries */
1888 		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1889 			break;
1890 	}
1891 
1892 
1893 	if (ii == 5) {
1894 		dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1895 		ret = -2;
1896 	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1897 		MptDisplayIocCapabilities(ioc);
1898 	}
1899 
1900 	if (alt_ioc_ready) {
1901 		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1902 			dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1903 			/* Retry - alt IOC was initialized once
1904 			 */
1905 			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1906 		}
1907 		if (rc) {
1908 			dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1909 			alt_ioc_ready = 0;
1910 			reset_alt_ioc_active = 0;
1911 		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1912 			MptDisplayIocCapabilities(ioc->alt_ioc);
1913 		}
1914 	}
1915 
1916 	/*
1917 	 * Device is reset now. It must have de-asserted the interrupt line
1918 	 * (if it was asserted) and it should be safe to register for the
1919 	 * interrupt now.
1920 	 */
1921 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1922 		ioc->pci_irq = -1;
1923 		if (ioc->pcidev->irq) {
1924 			if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1925 				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1926 					ioc->name);
1927 			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1928 					IRQF_SHARED, ioc->name, ioc);
1929 			if (rc < 0) {
1930 				printk(MYIOC_s_ERR_FMT "Unable to allocate "
1931 					"interrupt %d!\n", ioc->name,
1932 					ioc->pcidev->irq);
1933 				if (mpt_msi_enable)
1934 					pci_disable_msi(ioc->pcidev);
1935 				return -EBUSY;
1936 			}
1937 			irq_allocated = 1;
1938 			ioc->pci_irq = ioc->pcidev->irq;
1939 			pci_set_master(ioc->pcidev);		/* ?? */
1940 			pci_set_drvdata(ioc->pcidev, ioc);
1941 			dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1942 				"%d\n", ioc->name, ioc->pcidev->irq));
1943 		}
1944 	}
1945 
1946 	/* Prime reply & request queues!
1947 	 * (mucho alloc's) Must be done prior to
1948 	 * init as upper addresses are needed for init.
1949 	 * If fails, continue with alt-ioc processing
1950 	 */
1951 	if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1952 		ret = -3;
1953 
1954 	/* May need to check/upload firmware & data here!
1955 	 * If fails, continue with alt-ioc processing
1956 	 */
1957 	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1958 		ret = -4;
1959 // NEW!
1960 	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1961 		printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1962 				ioc->alt_ioc->name, rc);
1963 		alt_ioc_ready = 0;
1964 		reset_alt_ioc_active = 0;
1965 	}
1966 
1967 	if (alt_ioc_ready) {
1968 		if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1969 			alt_ioc_ready = 0;
1970 			reset_alt_ioc_active = 0;
1971 			printk(KERN_WARNING MYNAM
1972 				": alt-%s: (%d) init failure WARNING!\n",
1973 					ioc->alt_ioc->name, rc);
1974 		}
1975 	}
1976 
1977 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1978 		if (ioc->upload_fw) {
1979 			ddlprintk((MYIOC_s_INFO_FMT
1980 				"firmware upload required!\n", ioc->name));
1981 
1982 			/* Controller is not operational, cannot do upload
1983 			 */
1984 			if (ret == 0) {
1985 				rc = mpt_do_upload(ioc, sleepFlag);
1986 				if (rc == 0) {
1987 					if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1988 						/*
1989 						 * Maintain only one pointer to FW memory
1990 						 * so there will not be two attempt to
1991 						 * downloadboot onboard dual function
1992 						 * chips (mpt_adapter_disable,
1993 						 * mpt_diag_reset)
1994 						 */
1995 						ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload:  alt_%s has cached_fw=%p \n",
1996 							ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1997 						ioc->alt_ioc->cached_fw = NULL;
1998 					}
1999 				} else {
2000 					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2001 					ret = -5;
2002 				}
2003 			}
2004 		}
2005 	}
2006 
2007 	if (ret == 0) {
2008 		/* Enable! (reply interrupt) */
2009 		CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2010 		ioc->active = 1;
2011 	}
2012 
2013 	if (reset_alt_ioc_active && ioc->alt_ioc) {
2014 		/* (re)Enable alt-IOC! (reply interrupt) */
2015 		dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2016 				ioc->alt_ioc->name));
2017 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2018 		ioc->alt_ioc->active = 1;
2019 	}
2020 
2021 	/*  Enable MPT base driver management of EventNotification
2022 	 *  and EventAck handling.
2023 	 */
2024 	if ((ret == 0) && (!ioc->facts.EventState))
2025 		(void) SendEventNotification(ioc, 1);	/* 1=Enable EventNotification */
2026 
2027 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2028 		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
2029 
2030 	/*	Add additional "reason" check before call to GetLanConfigPages
2031 	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
2032 	 *	recursive scenario; GetLanConfigPages times out, timer expired
2033 	 *	routine calls HardResetHandler, which calls into here again,
2034 	 *	and we try GetLanConfigPages again...
2035 	 */
2036 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2037 
2038 		/*
2039 		 * Initalize link list for inactive raid volumes.
2040 		 */
2041 		init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2042 		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2043 
2044 		if (ioc->bus_type == SAS) {
2045 
2046 			/* clear persistency table */
2047 			if(ioc->facts.IOCExceptions &
2048 			    MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2049 				ret = mptbase_sas_persist_operation(ioc,
2050 				    MPI_SAS_OP_CLEAR_NOT_PRESENT);
2051 				if(ret != 0)
2052 					goto out;
2053 			}
2054 
2055 			/* Find IM volumes
2056 			 */
2057 			mpt_findImVolumes(ioc);
2058 
2059 		} else if (ioc->bus_type == FC) {
2060 			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2061 			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2062 				/*
2063 				 *  Pre-fetch the ports LAN MAC address!
2064 				 *  (LANPage1_t stuff)
2065 				 */
2066 				(void) GetLanConfigPages(ioc);
2067 #ifdef MPT_DEBUG
2068 				{
2069 					u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2070 					dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2071 							ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
2072 				}
2073 #endif
2074 			}
2075 		} else {
2076 			/* Get NVRAM and adapter maximums from SPP 0 and 2
2077 			 */
2078 			mpt_GetScsiPortSettings(ioc, 0);
2079 
2080 			/* Get version and length of SDP 1
2081 			 */
2082 			mpt_readScsiDevicePageHeaders(ioc, 0);
2083 
2084 			/* Find IM volumes
2085 			 */
2086 			if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2087 				mpt_findImVolumes(ioc);
2088 
2089 			/* Check, and possibly reset, the coalescing value
2090 			 */
2091 			mpt_read_ioc_pg_1(ioc);
2092 
2093 			mpt_read_ioc_pg_4(ioc);
2094 		}
2095 
2096 		GetIoUnitPage2(ioc);
2097 		mpt_get_manufacturing_pg_0(ioc);
2098 	}
2099 
2100 	/*
2101 	 * Call each currently registered protocol IOC reset handler
2102 	 * with post-reset indication.
2103 	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2104 	 * MptResetHandlers[] registered yet.
2105 	 */
2106 	if (hard_reset_done) {
2107 		rc = handlers = 0;
2108 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2109 			if ((ret == 0) && MptResetHandlers[ii]) {
2110 				dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
2111 						ioc->name, ii));
2112 				rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
2113 				handlers++;
2114 			}
2115 
2116 			if (alt_ioc_ready && MptResetHandlers[ii]) {
2117 				drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
2118 						ioc->name, ioc->alt_ioc->name, ii));
2119 				rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
2120 				handlers++;
2121 			}
2122 		}
2123 		/* FIXME?  Examine results here? */
2124 	}
2125 
2126  out:
2127 	if ((ret != 0) && irq_allocated) {
2128 		free_irq(ioc->pci_irq, ioc);
2129 		if (mpt_msi_enable)
2130 			pci_disable_msi(ioc->pcidev);
2131 	}
2132 	return ret;
2133 }
2134 
2135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2136 /**
2137  *	mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2138  *	@ioc: Pointer to MPT adapter structure
2139  *	@pdev: Pointer to (struct pci_dev) structure
2140  *
2141  *	Search for PCI bus/dev_function which matches
2142  *	PCI bus/dev_function (+/-1) for newly discovered 929,
2143  *	929X, 1030 or 1035.
2144  *
2145  *	If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2146  *	using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2147  */
2148 static void
2149 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2150 {
2151 	struct pci_dev *peer=NULL;
2152 	unsigned int slot = PCI_SLOT(pdev->devfn);
2153 	unsigned int func = PCI_FUNC(pdev->devfn);
2154 	MPT_ADAPTER *ioc_srch;
2155 
2156 	dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
2157 	    " searching for devfn match on %x or %x\n",
2158 		ioc->name, pci_name(pdev), pdev->bus->number,
2159 		pdev->devfn, func-1, func+1));
2160 
2161 	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2162 	if (!peer) {
2163 		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2164 		if (!peer)
2165 			return;
2166 	}
2167 
2168 	list_for_each_entry(ioc_srch, &ioc_list, list) {
2169 		struct pci_dev *_pcidev = ioc_srch->pcidev;
2170 		if (_pcidev == peer) {
2171 			/* Paranoia checks */
2172 			if (ioc->alt_ioc != NULL) {
2173 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2174 					ioc->name, ioc->alt_ioc->name);
2175 				break;
2176 			} else if (ioc_srch->alt_ioc != NULL) {
2177 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2178 					ioc_srch->name, ioc_srch->alt_ioc->name);
2179 				break;
2180 			}
2181 			dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2182 				ioc->name, ioc_srch->name));
2183 			ioc_srch->alt_ioc = ioc;
2184 			ioc->alt_ioc = ioc_srch;
2185 		}
2186 	}
2187 	pci_dev_put(peer);
2188 }
2189 
2190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2191 /**
2192  *	mpt_adapter_disable - Disable misbehaving MPT adapter.
2193  *	@ioc: Pointer to MPT adapter structure
2194  */
2195 static void
2196 mpt_adapter_disable(MPT_ADAPTER *ioc)
2197 {
2198 	int sz;
2199 	int ret;
2200 
2201 	if (ioc->cached_fw != NULL) {
2202 		ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2203 		if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2204 			printk(KERN_WARNING MYNAM
2205 				": firmware downloadboot failure (%d)!\n", ret);
2206 		}
2207 	}
2208 
2209 	/* Disable adapter interrupts! */
2210 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2211 	ioc->active = 0;
2212 	/* Clear any lingering interrupt */
2213 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2214 
2215 	if (ioc->alloc != NULL) {
2216 		sz = ioc->alloc_sz;
2217 		dexitprintk((KERN_INFO MYNAM ": %s.free  @ %p, sz=%d bytes\n",
2218 		 	ioc->name, ioc->alloc, ioc->alloc_sz));
2219 		pci_free_consistent(ioc->pcidev, sz,
2220 				ioc->alloc, ioc->alloc_dma);
2221 		ioc->reply_frames = NULL;
2222 		ioc->req_frames = NULL;
2223 		ioc->alloc = NULL;
2224 		ioc->alloc_total -= sz;
2225 	}
2226 
2227 	if (ioc->sense_buf_pool != NULL) {
2228 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2229 		pci_free_consistent(ioc->pcidev, sz,
2230 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2231 		ioc->sense_buf_pool = NULL;
2232 		ioc->alloc_total -= sz;
2233 	}
2234 
2235 	if (ioc->events != NULL){
2236 		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2237 		kfree(ioc->events);
2238 		ioc->events = NULL;
2239 		ioc->alloc_total -= sz;
2240 	}
2241 
2242 	if (ioc->cached_fw != NULL) {
2243 		sz = ioc->facts.FWImageSize;
2244 		pci_free_consistent(ioc->pcidev, sz,
2245 			ioc->cached_fw, ioc->cached_fw_dma);
2246 		ioc->cached_fw = NULL;
2247 		ioc->alloc_total -= sz;
2248 	}
2249 
2250 	kfree(ioc->spi_data.nvram);
2251 	mpt_inactive_raid_list_free(ioc);
2252 	kfree(ioc->raid_data.pIocPg2);
2253 	kfree(ioc->raid_data.pIocPg3);
2254 	ioc->spi_data.nvram = NULL;
2255 	ioc->raid_data.pIocPg3 = NULL;
2256 
2257 	if (ioc->spi_data.pIocPg4 != NULL) {
2258 		sz = ioc->spi_data.IocPg4Sz;
2259 		pci_free_consistent(ioc->pcidev, sz,
2260 			ioc->spi_data.pIocPg4,
2261 			ioc->spi_data.IocPg4_dma);
2262 		ioc->spi_data.pIocPg4 = NULL;
2263 		ioc->alloc_total -= sz;
2264 	}
2265 
2266 	if (ioc->ReqToChain != NULL) {
2267 		kfree(ioc->ReqToChain);
2268 		kfree(ioc->RequestNB);
2269 		ioc->ReqToChain = NULL;
2270 	}
2271 
2272 	kfree(ioc->ChainToChain);
2273 	ioc->ChainToChain = NULL;
2274 
2275 	if (ioc->HostPageBuffer != NULL) {
2276 		if((ret = mpt_host_page_access_control(ioc,
2277 		    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2278 			printk(KERN_ERR MYNAM
2279 			   ": %s: host page buffers free failed (%d)!\n",
2280 			    __FUNCTION__, ret);
2281 		}
2282 		dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free  @ %p, sz=%d bytes\n",
2283 		 	ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2284 		pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2285 				ioc->HostPageBuffer,
2286 				ioc->HostPageBuffer_dma);
2287 		ioc->HostPageBuffer = NULL;
2288 		ioc->HostPageBuffer_sz = 0;
2289 		ioc->alloc_total -= ioc->HostPageBuffer_sz;
2290 	}
2291 }
2292 
2293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2294 /**
2295  *	mpt_adapter_dispose - Free all resources associated with an MPT adapter
2296  *	@ioc: Pointer to MPT adapter structure
2297  *
2298  *	This routine unregisters h/w resources and frees all alloc'd memory
2299  *	associated with a MPT adapter structure.
2300  */
2301 static void
2302 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2303 {
2304 	int sz_first, sz_last;
2305 
2306 	if (ioc == NULL)
2307 		return;
2308 
2309 	sz_first = ioc->alloc_total;
2310 
2311 	mpt_adapter_disable(ioc);
2312 
2313 	if (ioc->pci_irq != -1) {
2314 		free_irq(ioc->pci_irq, ioc);
2315 		if (mpt_msi_enable)
2316 			pci_disable_msi(ioc->pcidev);
2317 		ioc->pci_irq = -1;
2318 	}
2319 
2320 	if (ioc->memmap != NULL) {
2321 		iounmap(ioc->memmap);
2322 		ioc->memmap = NULL;
2323 	}
2324 
2325 #if defined(CONFIG_MTRR) && 0
2326 	if (ioc->mtrr_reg > 0) {
2327 		mtrr_del(ioc->mtrr_reg, 0, 0);
2328 		dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2329 	}
2330 #endif
2331 
2332 	/*  Zap the adapter lookup ptr!  */
2333 	list_del(&ioc->list);
2334 
2335 	sz_last = ioc->alloc_total;
2336 	dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2337 			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2338 
2339 	if (ioc->alt_ioc)
2340 		ioc->alt_ioc->alt_ioc = NULL;
2341 
2342 	kfree(ioc);
2343 }
2344 
2345 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2346 /**
2347  *	MptDisplayIocCapabilities - Disply IOC's capabilities.
2348  *	@ioc: Pointer to MPT adapter structure
2349  */
2350 static void
2351 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2352 {
2353 	int i = 0;
2354 
2355 	printk(KERN_INFO "%s: ", ioc->name);
2356 	if (ioc->prod_name)
2357 		printk("%s: ", ioc->prod_name);
2358 	printk("Capabilities={");
2359 
2360 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2361 		printk("Initiator");
2362 		i++;
2363 	}
2364 
2365 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2366 		printk("%sTarget", i ? "," : "");
2367 		i++;
2368 	}
2369 
2370 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2371 		printk("%sLAN", i ? "," : "");
2372 		i++;
2373 	}
2374 
2375 #if 0
2376 	/*
2377 	 *  This would probably evoke more questions than it's worth
2378 	 */
2379 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2380 		printk("%sLogBusAddr", i ? "," : "");
2381 		i++;
2382 	}
2383 #endif
2384 
2385 	printk("}\n");
2386 }
2387 
2388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 /**
2390  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2391  *	@ioc: Pointer to MPT_ADAPTER structure
2392  *	@force: Force hard KickStart of IOC
2393  *	@sleepFlag: Specifies whether the process can sleep
2394  *
2395  *	Returns:
2396  *		 1 - DIAG reset and READY
2397  *		 0 - READY initially OR soft reset and READY
2398  *		-1 - Any failure on KickStart
2399  *		-2 - Msg Unit Reset Failed
2400  *		-3 - IO Unit Reset Failed
2401  *		-4 - IOC owned by a PEER
2402  */
2403 static int
2404 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2405 {
2406 	u32	 ioc_state;
2407 	int	 statefault = 0;
2408 	int	 cntdn;
2409 	int	 hard_reset_done = 0;
2410 	int	 r;
2411 	int	 ii;
2412 	int	 whoinit;
2413 
2414 	/* Get current [raw] IOC state  */
2415 	ioc_state = mpt_GetIocState(ioc, 0);
2416 	dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2417 
2418 	/*
2419 	 *	Check to see if IOC got left/stuck in doorbell handshake
2420 	 *	grip of death.  If so, hard reset the IOC.
2421 	 */
2422 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
2423 		statefault = 1;
2424 		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2425 				ioc->name);
2426 	}
2427 
2428 	/* Is it already READY? */
2429 	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2430 		return 0;
2431 
2432 	/*
2433 	 *	Check to see if IOC is in FAULT state.
2434 	 */
2435 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2436 		statefault = 2;
2437 		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2438 				ioc->name);
2439 		printk(KERN_WARNING "           FAULT code = %04xh\n",
2440 				ioc_state & MPI_DOORBELL_DATA_MASK);
2441 	}
2442 
2443 	/*
2444 	 *	Hmmm...  Did it get left operational?
2445 	 */
2446 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2447 		dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2448 				ioc->name));
2449 
2450 		/* Check WhoInit.
2451 		 * If PCI Peer, exit.
2452 		 * Else, if no fault conditions are present, issue a MessageUnitReset
2453 		 * Else, fall through to KickStart case
2454 		 */
2455 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2456 		dinitprintk((KERN_INFO MYNAM
2457 			": whoinit 0x%x statefault %d force %d\n",
2458 			whoinit, statefault, force));
2459 		if (whoinit == MPI_WHOINIT_PCI_PEER)
2460 			return -4;
2461 		else {
2462 			if ((statefault == 0 ) && (force == 0)) {
2463 				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2464 					return 0;
2465 			}
2466 			statefault = 3;
2467 		}
2468 	}
2469 
2470 	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2471 	if (hard_reset_done < 0)
2472 		return -1;
2473 
2474 	/*
2475 	 *  Loop here waiting for IOC to come READY.
2476 	 */
2477 	ii = 0;
2478 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;	/* 5 seconds */
2479 
2480 	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2481 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2482 			/*
2483 			 *  BIOS or previous driver load left IOC in OP state.
2484 			 *  Reset messaging FIFOs.
2485 			 */
2486 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2487 				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2488 				return -2;
2489 			}
2490 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
2491 			/*
2492 			 *  Something is wrong.  Try to get IOC back
2493 			 *  to a known state.
2494 			 */
2495 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2496 				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2497 				return -3;
2498 			}
2499 		}
2500 
2501 		ii++; cntdn--;
2502 		if (!cntdn) {
2503 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2504 					ioc->name, (int)((ii+5)/HZ));
2505 			return -ETIME;
2506 		}
2507 
2508 		if (sleepFlag == CAN_SLEEP) {
2509 			msleep(1);
2510 		} else {
2511 			mdelay (1);	/* 1 msec delay */
2512 		}
2513 
2514 	}
2515 
2516 	if (statefault < 3) {
2517 		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2518 				ioc->name,
2519 				statefault==1 ? "stuck handshake" : "IOC FAULT");
2520 	}
2521 
2522 	return hard_reset_done;
2523 }
2524 
2525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2526 /**
2527  *	mpt_GetIocState - Get the current state of a MPT adapter.
2528  *	@ioc: Pointer to MPT_ADAPTER structure
2529  *	@cooked: Request raw or cooked IOC state
2530  *
2531  *	Returns all IOC Doorbell register bits if cooked==0, else just the
2532  *	Doorbell bits in MPI_IOC_STATE_MASK.
2533  */
2534 u32
2535 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2536 {
2537 	u32 s, sc;
2538 
2539 	/*  Get!  */
2540 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
2541 //	dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2542 	sc = s & MPI_IOC_STATE_MASK;
2543 
2544 	/*  Save!  */
2545 	ioc->last_state = sc;
2546 
2547 	return cooked ? sc : s;
2548 }
2549 
2550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2551 /**
2552  *	GetIocFacts - Send IOCFacts request to MPT adapter.
2553  *	@ioc: Pointer to MPT_ADAPTER structure
2554  *	@sleepFlag: Specifies whether the process can sleep
2555  *	@reason: If recovery, only update facts.
2556  *
2557  *	Returns 0 for success, non-zero for failure.
2558  */
2559 static int
2560 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2561 {
2562 	IOCFacts_t		 get_facts;
2563 	IOCFactsReply_t		*facts;
2564 	int			 r;
2565 	int			 req_sz;
2566 	int			 reply_sz;
2567 	int			 sz;
2568 	u32			 status, vv;
2569 	u8			 shiftFactor=1;
2570 
2571 	/* IOC *must* NOT be in RESET state! */
2572 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2573 		printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2574 				ioc->name,
2575 				ioc->last_state );
2576 		return -44;
2577 	}
2578 
2579 	facts = &ioc->facts;
2580 
2581 	/* Destination (reply area)... */
2582 	reply_sz = sizeof(*facts);
2583 	memset(facts, 0, reply_sz);
2584 
2585 	/* Request area (get_facts on the stack right now!) */
2586 	req_sz = sizeof(get_facts);
2587 	memset(&get_facts, 0, req_sz);
2588 
2589 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2590 	/* Assert: All other get_facts fields are zero! */
2591 
2592 	dinitprintk((MYIOC_s_INFO_FMT
2593 	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2594 	    ioc->name, req_sz, reply_sz));
2595 
2596 	/* No non-zero fields in the get_facts request are greater than
2597 	 * 1 byte in size, so we can just fire it off as is.
2598 	 */
2599 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2600 			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2601 	if (r != 0)
2602 		return r;
2603 
2604 	/*
2605 	 * Now byte swap (GRRR) the necessary fields before any further
2606 	 * inspection of reply contents.
2607 	 *
2608 	 * But need to do some sanity checks on MsgLength (byte) field
2609 	 * to make sure we don't zero IOC's req_sz!
2610 	 */
2611 	/* Did we get a valid reply? */
2612 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2613 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2614 			/*
2615 			 * If not been here, done that, save off first WhoInit value
2616 			 */
2617 			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2618 				ioc->FirstWhoInit = facts->WhoInit;
2619 		}
2620 
2621 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2622 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
2623 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2624 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2625 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2626 		status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2627 		/* CHECKME! IOCStatus, IOCLogInfo */
2628 
2629 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2630 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2631 
2632 		/*
2633 		 * FC f/w version changed between 1.1 and 1.2
2634 		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
2635 		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2636 		 */
2637 		if (facts->MsgVersion < 0x0102) {
2638 			/*
2639 			 *	Handle old FC f/w style, convert to new...
2640 			 */
2641 			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2642 			facts->FWVersion.Word =
2643 					((oldv<<12) & 0xFF000000) |
2644 					((oldv<<8)  & 0x000FFF00);
2645 		} else
2646 			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2647 
2648 		facts->ProductID = le16_to_cpu(facts->ProductID);
2649 		if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2650 		    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2651 			ioc->ir_firmware = 1;
2652 		facts->CurrentHostMfaHighAddr =
2653 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
2654 		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2655 		facts->CurrentSenseBufferHighAddr =
2656 				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2657 		facts->CurReplyFrameSize =
2658 				le16_to_cpu(facts->CurReplyFrameSize);
2659 		facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2660 
2661 		/*
2662 		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2663 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2664 		 * to 14 in MPI-1.01.0x.
2665 		 */
2666 		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2667 		    facts->MsgVersion > 0x0100) {
2668 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2669 		}
2670 
2671 		sz = facts->FWImageSize;
2672 		if ( sz & 0x01 )
2673 			sz += 1;
2674 		if ( sz & 0x02 )
2675 			sz += 2;
2676 		facts->FWImageSize = sz;
2677 
2678 		if (!facts->RequestFrameSize) {
2679 			/*  Something is wrong!  */
2680 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2681 					ioc->name);
2682 			return -55;
2683 		}
2684 
2685 		r = sz = facts->BlockSize;
2686 		vv = ((63 / (sz * 4)) + 1) & 0x03;
2687 		ioc->NB_for_64_byte_frame = vv;
2688 		while ( sz )
2689 		{
2690 			shiftFactor++;
2691 			sz = sz >> 1;
2692 		}
2693 		ioc->NBShiftFactor  = shiftFactor;
2694 		dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2695 					ioc->name, vv, shiftFactor, r));
2696 
2697 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2698 			/*
2699 			 * Set values for this IOC's request & reply frame sizes,
2700 			 * and request & reply queue depths...
2701 			 */
2702 			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2703 			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2704 			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2705 			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2706 
2707 			dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2708 				ioc->name, ioc->reply_sz, ioc->reply_depth));
2709 			dinitprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
2710 				ioc->name, ioc->req_sz, ioc->req_depth));
2711 
2712 			/* Get port facts! */
2713 			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2714 				return r;
2715 		}
2716 	} else {
2717 		printk(MYIOC_s_ERR_FMT
2718 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2719 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2720 		     RequestFrameSize)/sizeof(u32)));
2721 		return -66;
2722 	}
2723 
2724 	return 0;
2725 }
2726 
2727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2728 /**
2729  *	GetPortFacts - Send PortFacts request to MPT adapter.
2730  *	@ioc: Pointer to MPT_ADAPTER structure
2731  *	@portnum: Port number
2732  *	@sleepFlag: Specifies whether the process can sleep
2733  *
2734  *	Returns 0 for success, non-zero for failure.
2735  */
2736 static int
2737 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2738 {
2739 	PortFacts_t		 get_pfacts;
2740 	PortFactsReply_t	*pfacts;
2741 	int			 ii;
2742 	int			 req_sz;
2743 	int			 reply_sz;
2744 	int			 max_id;
2745 
2746 	/* IOC *must* NOT be in RESET state! */
2747 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2748 		printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2749 				ioc->name,
2750 				ioc->last_state );
2751 		return -4;
2752 	}
2753 
2754 	pfacts = &ioc->pfacts[portnum];
2755 
2756 	/* Destination (reply area)...  */
2757 	reply_sz = sizeof(*pfacts);
2758 	memset(pfacts, 0, reply_sz);
2759 
2760 	/* Request area (get_pfacts on the stack right now!) */
2761 	req_sz = sizeof(get_pfacts);
2762 	memset(&get_pfacts, 0, req_sz);
2763 
2764 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2765 	get_pfacts.PortNumber = portnum;
2766 	/* Assert: All other get_pfacts fields are zero! */
2767 
2768 	dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2769 			ioc->name, portnum));
2770 
2771 	/* No non-zero fields in the get_pfacts request are greater than
2772 	 * 1 byte in size, so we can just fire it off as is.
2773 	 */
2774 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2775 				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2776 	if (ii != 0)
2777 		return ii;
2778 
2779 	/* Did we get a valid reply? */
2780 
2781 	/* Now byte swap the necessary fields in the response. */
2782 	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2783 	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2784 	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2785 	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2786 	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2787 	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2788 	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2789 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2790 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2791 
2792 	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2793 	    pfacts->MaxDevices;
2794 	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2795 	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2796 
2797 	/*
2798 	 * Place all the devices on channels
2799 	 *
2800 	 * (for debuging)
2801 	 */
2802 	if (mpt_channel_mapping) {
2803 		ioc->devices_per_bus = 1;
2804 		ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2805 	}
2806 
2807 	return 0;
2808 }
2809 
2810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811 /**
2812  *	SendIocInit - Send IOCInit request to MPT adapter.
2813  *	@ioc: Pointer to MPT_ADAPTER structure
2814  *	@sleepFlag: Specifies whether the process can sleep
2815  *
2816  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2817  *
2818  *	Returns 0 for success, non-zero for failure.
2819  */
2820 static int
2821 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2822 {
2823 	IOCInit_t		 ioc_init;
2824 	MPIDefaultReply_t	 init_reply;
2825 	u32			 state;
2826 	int			 r;
2827 	int			 count;
2828 	int			 cntdn;
2829 
2830 	memset(&ioc_init, 0, sizeof(ioc_init));
2831 	memset(&init_reply, 0, sizeof(init_reply));
2832 
2833 	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2834 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2835 
2836 	/* If we are in a recovery mode and we uploaded the FW image,
2837 	 * then this pointer is not NULL. Skip the upload a second time.
2838 	 * Set this flag if cached_fw set for either IOC.
2839 	 */
2840 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2841 		ioc->upload_fw = 1;
2842 	else
2843 		ioc->upload_fw = 0;
2844 	ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2845 		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
2846 
2847 	ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2848 	ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2849 	dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2850 		   ioc->name, ioc->facts.MsgVersion));
2851 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2852 		// set MsgVersion and HeaderVersion host driver was built with
2853 		ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2854 	        ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2855 
2856 		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2857 			ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2858 		} else if(mpt_host_page_alloc(ioc, &ioc_init))
2859 			return -99;
2860 	}
2861 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
2862 
2863 	if (sizeof(dma_addr_t) == sizeof(u64)) {
2864 		/* Save the upper 32-bits of the request
2865 		 * (reply) and sense buffers.
2866 		 */
2867 		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2868 		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2869 	} else {
2870 		/* Force 32-bit addressing */
2871 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2872 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2873 	}
2874 
2875 	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2876 	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2877 	ioc->facts.MaxDevices = ioc_init.MaxDevices;
2878 	ioc->facts.MaxBuses = ioc_init.MaxBuses;
2879 
2880 	dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2881 			ioc->name, &ioc_init));
2882 
2883 	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2884 				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2885 	if (r != 0) {
2886 		printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2887 		return r;
2888 	}
2889 
2890 	/* No need to byte swap the multibyte fields in the reply
2891 	 * since we don't even look at its contents.
2892 	 */
2893 
2894 	dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2895 			ioc->name, &ioc_init));
2896 
2897 	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2898 		printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2899 		return r;
2900 	}
2901 
2902 	/* YIKES!  SUPER IMPORTANT!!!
2903 	 *  Poll IocState until _OPERATIONAL while IOC is doing
2904 	 *  LoopInit and TargetDiscovery!
2905 	 */
2906 	count = 0;
2907 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
2908 	state = mpt_GetIocState(ioc, 1);
2909 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2910 		if (sleepFlag == CAN_SLEEP) {
2911 			msleep(1);
2912 		} else {
2913 			mdelay(1);
2914 		}
2915 
2916 		if (!cntdn) {
2917 			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2918 					ioc->name, (int)((count+5)/HZ));
2919 			return -9;
2920 		}
2921 
2922 		state = mpt_GetIocState(ioc, 1);
2923 		count++;
2924 	}
2925 	dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2926 			ioc->name, count));
2927 
2928 	ioc->aen_event_read_flag=0;
2929 	return r;
2930 }
2931 
2932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2933 /**
2934  *	SendPortEnable - Send PortEnable request to MPT adapter port.
2935  *	@ioc: Pointer to MPT_ADAPTER structure
2936  *	@portnum: Port number to enable
2937  *	@sleepFlag: Specifies whether the process can sleep
2938  *
2939  *	Send PortEnable to bring IOC to OPERATIONAL state.
2940  *
2941  *	Returns 0 for success, non-zero for failure.
2942  */
2943 static int
2944 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2945 {
2946 	PortEnable_t		 port_enable;
2947 	MPIDefaultReply_t	 reply_buf;
2948 	int	 rc;
2949 	int	 req_sz;
2950 	int	 reply_sz;
2951 
2952 	/*  Destination...  */
2953 	reply_sz = sizeof(MPIDefaultReply_t);
2954 	memset(&reply_buf, 0, reply_sz);
2955 
2956 	req_sz = sizeof(PortEnable_t);
2957 	memset(&port_enable, 0, req_sz);
2958 
2959 	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2960 	port_enable.PortNumber = portnum;
2961 /*	port_enable.ChainOffset = 0;		*/
2962 /*	port_enable.MsgFlags = 0;		*/
2963 /*	port_enable.MsgContext = 0;		*/
2964 
2965 	dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2966 			ioc->name, portnum, &port_enable));
2967 
2968 	/* RAID FW may take a long time to enable
2969 	 */
2970 	if (ioc->ir_firmware || ioc->bus_type == SAS) {
2971 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2972 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2973 		300 /*seconds*/, sleepFlag);
2974 	} else {
2975 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2976 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2977 		30 /*seconds*/, sleepFlag);
2978 	}
2979 	return rc;
2980 }
2981 
2982 /**
2983  *	mpt_alloc_fw_memory - allocate firmware memory
2984  *	@ioc: Pointer to MPT_ADAPTER structure
2985  *      @size: total FW bytes
2986  *
2987  *	If memory has already been allocated, the same (cached) value
2988  *	is returned.
2989  */
2990 void
2991 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2992 {
2993 	if (ioc->cached_fw)
2994 		return;  /* use already allocated memory */
2995 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2996 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2997 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2998 		ioc->alloc_total += size;
2999 		ioc->alt_ioc->alloc_total -= size;
3000 	} else {
3001 		if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3002 			ioc->alloc_total += size;
3003 	}
3004 }
3005 /**
3006  *	mpt_free_fw_memory - free firmware memory
3007  *	@ioc: Pointer to MPT_ADAPTER structure
3008  *
3009  *	If alt_img is NULL, delete from ioc structure.
3010  *	Else, delete a secondary image in same format.
3011  */
3012 void
3013 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3014 {
3015 	int sz;
3016 
3017 	sz = ioc->facts.FWImageSize;
3018 	dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3019 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3020 	pci_free_consistent(ioc->pcidev, sz,
3021 			ioc->cached_fw, ioc->cached_fw_dma);
3022 	ioc->cached_fw = NULL;
3023 
3024 	return;
3025 }
3026 
3027 
3028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3029 /**
3030  *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3031  *	@ioc: Pointer to MPT_ADAPTER structure
3032  *	@sleepFlag: Specifies whether the process can sleep
3033  *
3034  *	Returns 0 for success, >0 for handshake failure
3035  *		<0 for fw upload failure.
3036  *
3037  *	Remark: If bound IOC and a successful FWUpload was performed
3038  *	on the bound IOC, the second image is discarded
3039  *	and memory is free'd. Both channels must upload to prevent
3040  *	IOC from running in degraded mode.
3041  */
3042 static int
3043 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3044 {
3045 	u8			 request[ioc->req_sz];
3046 	u8			 reply[sizeof(FWUploadReply_t)];
3047 	FWUpload_t		*prequest;
3048 	FWUploadReply_t		*preply;
3049 	FWUploadTCSGE_t		*ptcsge;
3050 	int			 sgeoffset;
3051 	u32			 flagsLength;
3052 	int			 ii, sz, reply_sz;
3053 	int			 cmdStatus;
3054 
3055 	/* If the image size is 0, we are done.
3056 	 */
3057 	if ((sz = ioc->facts.FWImageSize) == 0)
3058 		return 0;
3059 
3060 	mpt_alloc_fw_memory(ioc, sz);
3061 
3062 	dinitprintk((KERN_INFO MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3063 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3064 
3065 	if (ioc->cached_fw == NULL) {
3066 		/* Major Failure.
3067 		 */
3068 		return -ENOMEM;
3069 	}
3070 
3071 	prequest = (FWUpload_t *)&request;
3072 	preply = (FWUploadReply_t *)&reply;
3073 
3074 	/*  Destination...  */
3075 	memset(prequest, 0, ioc->req_sz);
3076 
3077 	reply_sz = sizeof(reply);
3078 	memset(preply, 0, reply_sz);
3079 
3080 	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3081 	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3082 
3083 	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3084 	ptcsge->DetailsLength = 12;
3085 	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3086 	ptcsge->ImageSize = cpu_to_le32(sz);
3087 
3088 	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3089 
3090 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3091 	mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3092 
3093 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3094 	dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3095 			prequest, sgeoffset));
3096 	DBG_DUMP_FW_REQUEST_FRAME(prequest)
3097 
3098 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3099 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3100 
3101 	dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3102 
3103 	cmdStatus = -EFAULT;
3104 	if (ii == 0) {
3105 		/* Handshake transfer was complete and successful.
3106 		 * Check the Reply Frame.
3107 		 */
3108 		int status, transfer_sz;
3109 		status = le16_to_cpu(preply->IOCStatus);
3110 		if (status == MPI_IOCSTATUS_SUCCESS) {
3111 			transfer_sz = le32_to_cpu(preply->ActualImageSize);
3112 			if (transfer_sz == sz)
3113 				cmdStatus = 0;
3114 		}
3115 	}
3116 	dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
3117 			ioc->name, cmdStatus));
3118 
3119 
3120 	if (cmdStatus) {
3121 
3122 		ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
3123 			ioc->name));
3124 		mpt_free_fw_memory(ioc);
3125 	}
3126 
3127 	return cmdStatus;
3128 }
3129 
3130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3131 /**
3132  *	mpt_downloadboot - DownloadBoot code
3133  *	@ioc: Pointer to MPT_ADAPTER structure
3134  *	@pFwHeader: Pointer to firmware header info
3135  *	@sleepFlag: Specifies whether the process can sleep
3136  *
3137  *	FwDownloadBoot requires Programmed IO access.
3138  *
3139  *	Returns 0 for success
3140  *		-1 FW Image size is 0
3141  *		-2 No valid cached_fw Pointer
3142  *		<0 for fw upload failure.
3143  */
3144 static int
3145 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3146 {
3147 	MpiExtImageHeader_t	*pExtImage;
3148 	u32			 fwSize;
3149 	u32			 diag0val;
3150 	int			 count;
3151 	u32			*ptrFw;
3152 	u32			 diagRwData;
3153 	u32			 nextImage;
3154 	u32			 load_addr;
3155 	u32 			 ioc_state=0;
3156 
3157 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3158 				ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3159 
3160 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3161 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3162 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3163 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3164 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3165 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3166 
3167 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3168 
3169 	/* wait 1 msec */
3170 	if (sleepFlag == CAN_SLEEP) {
3171 		msleep(1);
3172 	} else {
3173 		mdelay (1);
3174 	}
3175 
3176 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3177 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3178 
3179 	for (count = 0; count < 30; count ++) {
3180 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3181 		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3182 			ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
3183 				ioc->name, count));
3184 			break;
3185 		}
3186 		/* wait .1 sec */
3187 		if (sleepFlag == CAN_SLEEP) {
3188 			msleep (100);
3189 		} else {
3190 			mdelay (100);
3191 		}
3192 	}
3193 
3194 	if ( count == 30 ) {
3195 		ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
3196 		"Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3197 		ioc->name, diag0val));
3198 		return -3;
3199 	}
3200 
3201 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3202 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3203 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3204 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3205 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3206 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3207 
3208 	/* Set the DiagRwEn and Disable ARM bits */
3209 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3210 
3211 	fwSize = (pFwHeader->ImageSize + 3)/4;
3212 	ptrFw = (u32 *) pFwHeader;
3213 
3214 	/* Write the LoadStartAddress to the DiagRw Address Register
3215 	 * using Programmed IO
3216 	 */
3217 	if (ioc->errata_flag_1064)
3218 		pci_enable_io_access(ioc->pcidev);
3219 
3220 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3221 	ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3222 		ioc->name, pFwHeader->LoadStartAddress));
3223 
3224 	ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3225 				ioc->name, fwSize*4, ptrFw));
3226 	while (fwSize--) {
3227 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3228 	}
3229 
3230 	nextImage = pFwHeader->NextImageHeaderOffset;
3231 	while (nextImage) {
3232 		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3233 
3234 		load_addr = pExtImage->LoadStartAddress;
3235 
3236 		fwSize = (pExtImage->ImageSize + 3) >> 2;
3237 		ptrFw = (u32 *)pExtImage;
3238 
3239 		ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3240 						ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3241 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3242 
3243 		while (fwSize--) {
3244 			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3245 		}
3246 		nextImage = pExtImage->NextImageHeaderOffset;
3247 	}
3248 
3249 	/* Write the IopResetVectorRegAddr */
3250 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
3251 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3252 
3253 	/* Write the IopResetVectorValue */
3254 	ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3255 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3256 
3257 	/* Clear the internal flash bad bit - autoincrementing register,
3258 	 * so must do two writes.
3259 	 */
3260 	if (ioc->bus_type == SPI) {
3261 		/*
3262 		 * 1030 and 1035 H/W errata, workaround to access
3263 		 * the ClearFlashBadSignatureBit
3264 		 */
3265 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3266 		diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3267 		diagRwData |= 0x40000000;
3268 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3269 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3270 
3271 	} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3272 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3273 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3274 		    MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3275 
3276 		/* wait 1 msec */
3277 		if (sleepFlag == CAN_SLEEP) {
3278 			msleep (1);
3279 		} else {
3280 			mdelay (1);
3281 		}
3282 	}
3283 
3284 	if (ioc->errata_flag_1064)
3285 		pci_disable_io_access(ioc->pcidev);
3286 
3287 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3288 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3289 		"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3290 		ioc->name, diag0val));
3291 	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3292 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3293 		ioc->name, diag0val));
3294 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3295 
3296 	/* Write 0xFF to reset the sequencer */
3297 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3298 
3299 	if (ioc->bus_type == SAS) {
3300 		ioc_state = mpt_GetIocState(ioc, 0);
3301 		if ( (GetIocFacts(ioc, sleepFlag,
3302 				MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3303 			ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3304 					ioc->name, ioc_state));
3305 			return -EFAULT;
3306 		}
3307 	}
3308 
3309 	for (count=0; count<HZ*20; count++) {
3310 		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3311 			ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3312 					ioc->name, count, ioc_state));
3313 			if (ioc->bus_type == SAS) {
3314 				return 0;
3315 			}
3316 			if ((SendIocInit(ioc, sleepFlag)) != 0) {
3317 				ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3318 					ioc->name));
3319 				return -EFAULT;
3320 			}
3321 			ddlprintk((MYIOC_s_INFO_FMT "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((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3332 		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((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((MYIOC_s_INFO_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((MYIOC_s_INFO_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 #ifdef MPT_DEBUG
3438 	u32 diag1val = 0;
3439 #endif
3440 
3441 	/* Clear any existing interrupts */
3442 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3443 
3444 	if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3445 		drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3446 			"address=%p\n",  ioc->name, __FUNCTION__,
3447 			&ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3448 		CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3449 		if (sleepFlag == CAN_SLEEP)
3450 			msleep(1);
3451 		else
3452 			mdelay(1);
3453 
3454 		for (count = 0; count < 60; count ++) {
3455 			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3456 			doorbell &= MPI_IOC_STATE_MASK;
3457 
3458 			drsprintk((MYIOC_s_INFO_FMT
3459 				"looking for READY STATE: doorbell=%x"
3460 			        " count=%d\n",
3461 				ioc->name, doorbell, count));
3462 			if (doorbell == MPI_IOC_STATE_READY) {
3463 				return 1;
3464 			}
3465 
3466 			/* wait 1 sec */
3467 			if (sleepFlag == CAN_SLEEP)
3468 				msleep(1000);
3469 			else
3470 				mdelay(1000);
3471 		}
3472 		return -1;
3473 	}
3474 
3475 	/* Use "Diagnostic reset" method! (only thing available!) */
3476 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3477 
3478 #ifdef MPT_DEBUG
3479 	if (ioc->alt_ioc)
3480 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3481 	dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3482 			ioc->name, diag0val, diag1val));
3483 #endif
3484 
3485 	/* Do the reset if we are told to ignore the reset history
3486 	 * or if the reset history is 0
3487 	 */
3488 	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3489 		while ((diag0val & MPI_DIAG_DRWE) == 0) {
3490 			/* Write magic sequence to WriteSequence register
3491 			 * Loop until in diagnostic mode
3492 			 */
3493 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3494 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3495 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3496 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3497 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3498 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3499 
3500 			/* wait 100 msec */
3501 			if (sleepFlag == CAN_SLEEP) {
3502 				msleep (100);
3503 			} else {
3504 				mdelay (100);
3505 			}
3506 
3507 			count++;
3508 			if (count > 20) {
3509 				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3510 						ioc->name, diag0val);
3511 				return -2;
3512 
3513 			}
3514 
3515 			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3516 
3517 			dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3518 					ioc->name, diag0val));
3519 		}
3520 
3521 #ifdef MPT_DEBUG
3522 		if (ioc->alt_ioc)
3523 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3524 		dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3525 				ioc->name, diag0val, diag1val));
3526 #endif
3527 		/*
3528 		 * Disable the ARM (Bug fix)
3529 		 *
3530 		 */
3531 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3532 		mdelay(1);
3533 
3534 		/*
3535 		 * Now hit the reset bit in the Diagnostic register
3536 		 * (THE BIG HAMMER!) (Clears DRWE bit).
3537 		 */
3538 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3539 		hard_reset_done = 1;
3540 		dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3541 				ioc->name));
3542 
3543 		/*
3544 		 * Call each currently registered protocol IOC reset handler
3545 		 * with pre-reset indication.
3546 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3547 		 * MptResetHandlers[] registered yet.
3548 		 */
3549 		{
3550 			int	 ii;
3551 			int	 r = 0;
3552 
3553 			for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3554 				if (MptResetHandlers[ii]) {
3555 					dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3556 							ioc->name, ii));
3557 					r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3558 					if (ioc->alt_ioc) {
3559 						dprintk((MYIOC_s_INFO_FMT "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((MYIOC_s_INFO_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 #ifdef MPT_DEBUG
3625 	if (ioc->alt_ioc)
3626 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3627 	dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3628 		ioc->name, diag0val, diag1val));
3629 #endif
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 #ifdef MPT_DEBUG
3684 	if (ioc->alt_ioc)
3685 		diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3686 	dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3687 			ioc->name, diag0val, diag1val));
3688 #endif
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((KERN_INFO MYNAM ": %s: 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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3889 			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
3890 		dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3891 			 	ioc->name, reply_sz, reply_sz));
3892 
3893 		sz = (ioc->req_sz * ioc->req_depth);
3894 		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3895 			 	ioc->name, ioc->req_sz, ioc->req_depth));
3896 		dinitprintk((KERN_INFO MYNAM ": %s.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((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3902 			 	ioc->name, ioc->req_sz, num_chain));
3903 		dinitprintk((KERN_INFO MYNAM ": %s.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((KERN_INFO MYNAM ": %s.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((KERN_INFO MYNAM ": %s 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((KERN_INFO MYNAM ": %s 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((MYIOC_s_INFO_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((KERN_INFO MYNAM " :%s 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((KERN_INFO MYNAM ": %s.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((KERN_INFO MYNAM ": %s.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((MYIOC_s_INFO_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((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
4132 		DBG_DUMP_REQUEST_FRAME_HDR(req)
4133 
4134 		dhsprintk((MYIOC_s_INFO_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((MYIOC_s_INFO_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((MYIOC_s_INFO_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((MYIOC_s_INFO_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((MYIOC_s_INFO_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((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4337 	DBG_DUMP_REPLY_FRAME(mptReply)
4338 
4339 	dhsprintk((MYIOC_s_INFO_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((MYIOC_s_INFO_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((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4801 					ioc->name, ioc->spi_data.minSyncFactor));
4802 			} else {
4803 				/* Save the Port Page 0 data
4804 				 */
4805 				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4806 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4807 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4808 
4809 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4810 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4811 					ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4812 						ioc->name, pPP0->Capabilities));
4813 				}
4814 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4815 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4816 				if (data) {
4817 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4818 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4819 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4820 					ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4821 						ioc->name, ioc->spi_data.minSyncFactor));
4822 				} else {
4823 					ioc->spi_data.maxSyncOffset = 0;
4824 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
4825 				}
4826 
4827 				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4828 
4829 				/* Update the minSyncFactor based on bus type.
4830 				 */
4831 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4832 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4833 
4834 					if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4835 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
4836 						ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4837 							ioc->name, ioc->spi_data.minSyncFactor));
4838 					}
4839 				}
4840 			}
4841 			if (pbuf) {
4842 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4843 			}
4844 		}
4845 	}
4846 
4847 	/* SCSI Port Page 2 - Read the header then the page.
4848 	 */
4849 	header.PageVersion = 0;
4850 	header.PageLength = 0;
4851 	header.PageNumber = 2;
4852 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4853 	cfg.cfghdr.hdr = &header;
4854 	cfg.physAddr = -1;
4855 	cfg.pageAddr = portnum;
4856 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4857 	cfg.dir = 0;
4858 	if (mpt_config(ioc, &cfg) != 0)
4859 		return -EFAULT;
4860 
4861 	if (header.PageLength > 0) {
4862 		/* Allocate memory and read SCSI Port Page 2
4863 		 */
4864 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4865 		if (pbuf) {
4866 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4867 			cfg.physAddr = buf_dma;
4868 			if (mpt_config(ioc, &cfg) != 0) {
4869 				/* Nvram data is left with INVALID mark
4870 				 */
4871 				rc = 1;
4872 			} else {
4873 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4874 				MpiDeviceInfo_t	*pdevice = NULL;
4875 
4876 				/*
4877 				 * Save "Set to Avoid SCSI Bus Resets" flag
4878 				 */
4879 				ioc->spi_data.bus_reset =
4880 				    (le32_to_cpu(pPP2->PortFlags) &
4881 			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4882 				    0 : 1 ;
4883 
4884 				/* Save the Port Page 2 data
4885 				 * (reformat into a 32bit quantity)
4886 				 */
4887 				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4888 				ioc->spi_data.PortFlags = data;
4889 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4890 					pdevice = &pPP2->DeviceSettings[ii];
4891 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4892 						(pdevice->SyncFactor << 8) | pdevice->Timeout;
4893 					ioc->spi_data.nvram[ii] = data;
4894 				}
4895 			}
4896 
4897 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4898 		}
4899 	}
4900 
4901 	/* Update Adapter limits with those from NVRAM
4902 	 * Comment: Don't need to do this. Target performance
4903 	 * parameters will never exceed the adapters limits.
4904 	 */
4905 
4906 	return rc;
4907 }
4908 
4909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4910 /**
4911  *	mpt_readScsiDevicePageHeaders - save version and length of SDP1
4912  *	@ioc: Pointer to a Adapter Strucutre
4913  *	@portnum: IOC port number
4914  *
4915  *	Return: -EFAULT if read of config page header fails
4916  *		or 0 if success.
4917  */
4918 static int
4919 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4920 {
4921 	CONFIGPARMS		 cfg;
4922 	ConfigPageHeader_t	 header;
4923 
4924 	/* Read the SCSI Device Page 1 header
4925 	 */
4926 	header.PageVersion = 0;
4927 	header.PageLength = 0;
4928 	header.PageNumber = 1;
4929 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4930 	cfg.cfghdr.hdr = &header;
4931 	cfg.physAddr = -1;
4932 	cfg.pageAddr = portnum;
4933 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4934 	cfg.dir = 0;
4935 	cfg.timeout = 0;
4936 	if (mpt_config(ioc, &cfg) != 0)
4937 		 return -EFAULT;
4938 
4939 	ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4940 	ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4941 
4942 	header.PageVersion = 0;
4943 	header.PageLength = 0;
4944 	header.PageNumber = 0;
4945 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4946 	if (mpt_config(ioc, &cfg) != 0)
4947 		 return -EFAULT;
4948 
4949 	ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4950 	ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4951 
4952 	dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4953 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4954 
4955 	dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4956 			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4957 	return 0;
4958 }
4959 
4960 /**
4961  * mpt_inactive_raid_list_free - This clears this link list.
4962  * @ioc : pointer to per adapter structure
4963  **/
4964 static void
4965 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4966 {
4967 	struct inactive_raid_component_info *component_info, *pNext;
4968 
4969 	if (list_empty(&ioc->raid_data.inactive_list))
4970 		return;
4971 
4972 	down(&ioc->raid_data.inactive_list_mutex);
4973 	list_for_each_entry_safe(component_info, pNext,
4974 	    &ioc->raid_data.inactive_list, list) {
4975 		list_del(&component_info->list);
4976 		kfree(component_info);
4977 	}
4978 	up(&ioc->raid_data.inactive_list_mutex);
4979 }
4980 
4981 /**
4982  * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
4983  *
4984  * @ioc : pointer to per adapter structure
4985  * @channel : volume channel
4986  * @id : volume target id
4987  **/
4988 static void
4989 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4990 {
4991 	CONFIGPARMS			cfg;
4992 	ConfigPageHeader_t		hdr;
4993 	dma_addr_t			dma_handle;
4994 	pRaidVolumePage0_t		buffer = NULL;
4995 	int				i;
4996 	RaidPhysDiskPage0_t 		phys_disk;
4997 	struct inactive_raid_component_info *component_info;
4998 	int				handle_inactive_volumes;
4999 
5000 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5001 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5002 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5003 	cfg.pageAddr = (channel << 8) + id;
5004 	cfg.cfghdr.hdr = &hdr;
5005 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5006 
5007 	if (mpt_config(ioc, &cfg) != 0)
5008 		goto out;
5009 
5010 	if (!hdr.PageLength)
5011 		goto out;
5012 
5013 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5014 	    &dma_handle);
5015 
5016 	if (!buffer)
5017 		goto out;
5018 
5019 	cfg.physAddr = dma_handle;
5020 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5021 
5022 	if (mpt_config(ioc, &cfg) != 0)
5023 		goto out;
5024 
5025 	if (!buffer->NumPhysDisks)
5026 		goto out;
5027 
5028 	handle_inactive_volumes =
5029 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5030 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5031 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5032 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5033 
5034 	if (!handle_inactive_volumes)
5035 		goto out;
5036 
5037 	down(&ioc->raid_data.inactive_list_mutex);
5038 	for (i = 0; i < buffer->NumPhysDisks; i++) {
5039 		if(mpt_raid_phys_disk_pg0(ioc,
5040 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5041 			continue;
5042 
5043 		if ((component_info = kmalloc(sizeof (*component_info),
5044 		 GFP_KERNEL)) == NULL)
5045 			continue;
5046 
5047 		component_info->volumeID = id;
5048 		component_info->volumeBus = channel;
5049 		component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5050 		component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5051 		component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5052 		component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5053 
5054 		list_add_tail(&component_info->list,
5055 		    &ioc->raid_data.inactive_list);
5056 	}
5057 	up(&ioc->raid_data.inactive_list_mutex);
5058 
5059  out:
5060 	if (buffer)
5061 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5062 		    dma_handle);
5063 }
5064 
5065 /**
5066  *	mpt_raid_phys_disk_pg0 - returns phys disk page zero
5067  *	@ioc: Pointer to a Adapter Structure
5068  *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5069  *	@phys_disk: requested payload data returned
5070  *
5071  *	Return:
5072  *	0 on success
5073  *	-EFAULT if read of config page header fails or data pointer not NULL
5074  *	-ENOMEM if pci_alloc failed
5075  **/
5076 int
5077 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5078 {
5079 	CONFIGPARMS		 	cfg;
5080 	ConfigPageHeader_t	 	hdr;
5081 	dma_addr_t			dma_handle;
5082 	pRaidPhysDiskPage0_t		buffer = NULL;
5083 	int				rc;
5084 
5085 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5086 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5087 
5088 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5089 	cfg.cfghdr.hdr = &hdr;
5090 	cfg.physAddr = -1;
5091 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5092 
5093 	if (mpt_config(ioc, &cfg) != 0) {
5094 		rc = -EFAULT;
5095 		goto out;
5096 	}
5097 
5098 	if (!hdr.PageLength) {
5099 		rc = -EFAULT;
5100 		goto out;
5101 	}
5102 
5103 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5104 	    &dma_handle);
5105 
5106 	if (!buffer) {
5107 		rc = -ENOMEM;
5108 		goto out;
5109 	}
5110 
5111 	cfg.physAddr = dma_handle;
5112 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5113 	cfg.pageAddr = phys_disk_num;
5114 
5115 	if (mpt_config(ioc, &cfg) != 0) {
5116 		rc = -EFAULT;
5117 		goto out;
5118 	}
5119 
5120 	rc = 0;
5121 	memcpy(phys_disk, buffer, sizeof(*buffer));
5122 	phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5123 
5124  out:
5125 
5126 	if (buffer)
5127 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5128 		    dma_handle);
5129 
5130 	return rc;
5131 }
5132 
5133 /**
5134  *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5135  *	@ioc: Pointer to a Adapter Strucutre
5136  *	@portnum: IOC port number
5137  *
5138  *	Return:
5139  *	0 on success
5140  *	-EFAULT if read of config page header fails or data pointer not NULL
5141  *	-ENOMEM if pci_alloc failed
5142  **/
5143 int
5144 mpt_findImVolumes(MPT_ADAPTER *ioc)
5145 {
5146 	IOCPage2_t		*pIoc2;
5147 	u8			*mem;
5148 	dma_addr_t		 ioc2_dma;
5149 	CONFIGPARMS		 cfg;
5150 	ConfigPageHeader_t	 header;
5151 	int			 rc = 0;
5152 	int			 iocpage2sz;
5153 	int			 i;
5154 
5155 	if (!ioc->ir_firmware)
5156 		return 0;
5157 
5158 	/* Free the old page
5159 	 */
5160 	kfree(ioc->raid_data.pIocPg2);
5161 	ioc->raid_data.pIocPg2 = NULL;
5162 	mpt_inactive_raid_list_free(ioc);
5163 
5164 	/* Read IOCP2 header then the page.
5165 	 */
5166 	header.PageVersion = 0;
5167 	header.PageLength = 0;
5168 	header.PageNumber = 2;
5169 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5170 	cfg.cfghdr.hdr = &header;
5171 	cfg.physAddr = -1;
5172 	cfg.pageAddr = 0;
5173 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5174 	cfg.dir = 0;
5175 	cfg.timeout = 0;
5176 	if (mpt_config(ioc, &cfg) != 0)
5177 		 return -EFAULT;
5178 
5179 	if (header.PageLength == 0)
5180 		return -EFAULT;
5181 
5182 	iocpage2sz = header.PageLength * 4;
5183 	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5184 	if (!pIoc2)
5185 		return -ENOMEM;
5186 
5187 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5188 	cfg.physAddr = ioc2_dma;
5189 	if (mpt_config(ioc, &cfg) != 0)
5190 		goto out;
5191 
5192 	mem = kmalloc(iocpage2sz, GFP_KERNEL);
5193 	if (!mem)
5194 		goto out;
5195 
5196 	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5197 	ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5198 
5199 	mpt_read_ioc_pg_3(ioc);
5200 
5201 	for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5202 		mpt_inactive_raid_volumes(ioc,
5203 		    pIoc2->RaidVolume[i].VolumeBus,
5204 		    pIoc2->RaidVolume[i].VolumeID);
5205 
5206  out:
5207 	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5208 
5209 	return rc;
5210 }
5211 
5212 static int
5213 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5214 {
5215 	IOCPage3_t		*pIoc3;
5216 	u8			*mem;
5217 	CONFIGPARMS		 cfg;
5218 	ConfigPageHeader_t	 header;
5219 	dma_addr_t		 ioc3_dma;
5220 	int			 iocpage3sz = 0;
5221 
5222 	/* Free the old page
5223 	 */
5224 	kfree(ioc->raid_data.pIocPg3);
5225 	ioc->raid_data.pIocPg3 = NULL;
5226 
5227 	/* There is at least one physical disk.
5228 	 * Read and save IOC Page 3
5229 	 */
5230 	header.PageVersion = 0;
5231 	header.PageLength = 0;
5232 	header.PageNumber = 3;
5233 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5234 	cfg.cfghdr.hdr = &header;
5235 	cfg.physAddr = -1;
5236 	cfg.pageAddr = 0;
5237 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5238 	cfg.dir = 0;
5239 	cfg.timeout = 0;
5240 	if (mpt_config(ioc, &cfg) != 0)
5241 		return 0;
5242 
5243 	if (header.PageLength == 0)
5244 		return 0;
5245 
5246 	/* Read Header good, alloc memory
5247 	 */
5248 	iocpage3sz = header.PageLength * 4;
5249 	pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5250 	if (!pIoc3)
5251 		return 0;
5252 
5253 	/* Read the Page and save the data
5254 	 * into malloc'd memory.
5255 	 */
5256 	cfg.physAddr = ioc3_dma;
5257 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5258 	if (mpt_config(ioc, &cfg) == 0) {
5259 		mem = kmalloc(iocpage3sz, GFP_KERNEL);
5260 		if (mem) {
5261 			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5262 			ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5263 		}
5264 	}
5265 
5266 	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5267 
5268 	return 0;
5269 }
5270 
5271 static void
5272 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5273 {
5274 	IOCPage4_t		*pIoc4;
5275 	CONFIGPARMS		 cfg;
5276 	ConfigPageHeader_t	 header;
5277 	dma_addr_t		 ioc4_dma;
5278 	int			 iocpage4sz;
5279 
5280 	/* Read and save IOC Page 4
5281 	 */
5282 	header.PageVersion = 0;
5283 	header.PageLength = 0;
5284 	header.PageNumber = 4;
5285 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5286 	cfg.cfghdr.hdr = &header;
5287 	cfg.physAddr = -1;
5288 	cfg.pageAddr = 0;
5289 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5290 	cfg.dir = 0;
5291 	cfg.timeout = 0;
5292 	if (mpt_config(ioc, &cfg) != 0)
5293 		return;
5294 
5295 	if (header.PageLength == 0)
5296 		return;
5297 
5298 	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5299 		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5300 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5301 		if (!pIoc4)
5302 			return;
5303 		ioc->alloc_total += iocpage4sz;
5304 	} else {
5305 		ioc4_dma = ioc->spi_data.IocPg4_dma;
5306 		iocpage4sz = ioc->spi_data.IocPg4Sz;
5307 	}
5308 
5309 	/* Read the Page into dma memory.
5310 	 */
5311 	cfg.physAddr = ioc4_dma;
5312 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5313 	if (mpt_config(ioc, &cfg) == 0) {
5314 		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5315 		ioc->spi_data.IocPg4_dma = ioc4_dma;
5316 		ioc->spi_data.IocPg4Sz = iocpage4sz;
5317 	} else {
5318 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5319 		ioc->spi_data.pIocPg4 = NULL;
5320 		ioc->alloc_total -= iocpage4sz;
5321 	}
5322 }
5323 
5324 static void
5325 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5326 {
5327 	IOCPage1_t		*pIoc1;
5328 	CONFIGPARMS		 cfg;
5329 	ConfigPageHeader_t	 header;
5330 	dma_addr_t		 ioc1_dma;
5331 	int			 iocpage1sz = 0;
5332 	u32			 tmp;
5333 
5334 	/* Check the Coalescing Timeout in IOC Page 1
5335 	 */
5336 	header.PageVersion = 0;
5337 	header.PageLength = 0;
5338 	header.PageNumber = 1;
5339 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5340 	cfg.cfghdr.hdr = &header;
5341 	cfg.physAddr = -1;
5342 	cfg.pageAddr = 0;
5343 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5344 	cfg.dir = 0;
5345 	cfg.timeout = 0;
5346 	if (mpt_config(ioc, &cfg) != 0)
5347 		return;
5348 
5349 	if (header.PageLength == 0)
5350 		return;
5351 
5352 	/* Read Header good, alloc memory
5353 	 */
5354 	iocpage1sz = header.PageLength * 4;
5355 	pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5356 	if (!pIoc1)
5357 		return;
5358 
5359 	/* Read the Page and check coalescing timeout
5360 	 */
5361 	cfg.physAddr = ioc1_dma;
5362 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5363 	if (mpt_config(ioc, &cfg) == 0) {
5364 
5365 		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5366 		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5367 			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5368 
5369 			dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5370 					ioc->name, tmp));
5371 
5372 			if (tmp > MPT_COALESCING_TIMEOUT) {
5373 				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5374 
5375 				/* Write NVRAM and current
5376 				 */
5377 				cfg.dir = 1;
5378 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5379 				if (mpt_config(ioc, &cfg) == 0) {
5380 					dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5381 							ioc->name, MPT_COALESCING_TIMEOUT));
5382 
5383 					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5384 					if (mpt_config(ioc, &cfg) == 0) {
5385 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5386 								ioc->name, MPT_COALESCING_TIMEOUT));
5387 					} else {
5388 						dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5389 									ioc->name));
5390 					}
5391 
5392 				} else {
5393 					dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5394 								ioc->name));
5395 				}
5396 			}
5397 
5398 		} else {
5399 			dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5400 		}
5401 	}
5402 
5403 	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5404 
5405 	return;
5406 }
5407 
5408 static void
5409 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5410 {
5411 	CONFIGPARMS		cfg;
5412 	ConfigPageHeader_t	hdr;
5413 	dma_addr_t		buf_dma;
5414 	ManufacturingPage0_t	*pbuf = NULL;
5415 
5416 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5417 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5418 
5419 	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5420 	cfg.cfghdr.hdr = &hdr;
5421 	cfg.physAddr = -1;
5422 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5423 	cfg.timeout = 10;
5424 
5425 	if (mpt_config(ioc, &cfg) != 0)
5426 		goto out;
5427 
5428 	if (!cfg.cfghdr.hdr->PageLength)
5429 		goto out;
5430 
5431 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5432 	pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5433 	if (!pbuf)
5434 		goto out;
5435 
5436 	cfg.physAddr = buf_dma;
5437 
5438 	if (mpt_config(ioc, &cfg) != 0)
5439 		goto out;
5440 
5441 	memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5442 	memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5443 	memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5444 
5445 	out:
5446 
5447 	if (pbuf)
5448 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5449 }
5450 
5451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5452 /**
5453  *	SendEventNotification - Send EventNotification (on or off) request to adapter
5454  *	@ioc: Pointer to MPT_ADAPTER structure
5455  *	@EvSwitch: Event switch flags
5456  */
5457 static int
5458 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5459 {
5460 	EventNotification_t	*evnp;
5461 
5462 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5463 	if (evnp == NULL) {
5464 		devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5465 				ioc->name));
5466 		return 0;
5467 	}
5468 	memset(evnp, 0, sizeof(*evnp));
5469 
5470 	devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5471 
5472 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5473 	evnp->ChainOffset = 0;
5474 	evnp->MsgFlags = 0;
5475 	evnp->Switch = EvSwitch;
5476 
5477 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5478 
5479 	return 0;
5480 }
5481 
5482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5483 /**
5484  *	SendEventAck - Send EventAck request to MPT adapter.
5485  *	@ioc: Pointer to MPT_ADAPTER structure
5486  *	@evnp: Pointer to original EventNotification request
5487  */
5488 static int
5489 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5490 {
5491 	EventAck_t	*pAck;
5492 
5493 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5494 		dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5495 		    ioc->name,__FUNCTION__));
5496 		return -1;
5497 	}
5498 
5499 	devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5500 
5501 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
5502 	pAck->ChainOffset  = 0;
5503 	pAck->Reserved[0]  = pAck->Reserved[1] = 0;
5504 	pAck->MsgFlags     = 0;
5505 	pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5506 	pAck->Event        = evnp->Event;
5507 	pAck->EventContext = evnp->EventContext;
5508 
5509 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5510 
5511 	return 0;
5512 }
5513 
5514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5515 /**
5516  *	mpt_config - Generic function to issue config message
5517  *	@ioc:   Pointer to an adapter structure
5518  *	@pCfg:  Pointer to a configuration structure. Struct contains
5519  *		action, page address, direction, physical address
5520  *		and pointer to a configuration page header
5521  *		Page header is updated.
5522  *
5523  *	Returns 0 for success
5524  *	-EPERM if not allowed due to ISR context
5525  *	-EAGAIN if no msg frames currently available
5526  *	-EFAULT for non-successful reply or no reply (timeout)
5527  */
5528 int
5529 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5530 {
5531 	Config_t	*pReq;
5532 	ConfigExtendedPageHeader_t  *pExtHdr = NULL;
5533 	MPT_FRAME_HDR	*mf;
5534 	unsigned long	 flags;
5535 	int		 ii, rc;
5536 	int		 flagsLength;
5537 	int		 in_isr;
5538 
5539 	/*	Prevent calling wait_event() (below), if caller happens
5540 	 *	to be in ISR context, because that is fatal!
5541 	 */
5542 	in_isr = in_interrupt();
5543 	if (in_isr) {
5544 		dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5545 				ioc->name));
5546 		return -EPERM;
5547 	}
5548 
5549 	/* Get and Populate a free Frame
5550 	 */
5551 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5552 		dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5553 				ioc->name));
5554 		return -EAGAIN;
5555 	}
5556 	pReq = (Config_t *)mf;
5557 	pReq->Action = pCfg->action;
5558 	pReq->Reserved = 0;
5559 	pReq->ChainOffset = 0;
5560 	pReq->Function = MPI_FUNCTION_CONFIG;
5561 
5562 	/* Assume page type is not extended and clear "reserved" fields. */
5563 	pReq->ExtPageLength = 0;
5564 	pReq->ExtPageType = 0;
5565 	pReq->MsgFlags = 0;
5566 
5567 	for (ii=0; ii < 8; ii++)
5568 		pReq->Reserved2[ii] = 0;
5569 
5570 	pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5571 	pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5572 	pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5573 	pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5574 
5575 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5576 		pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5577 		pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5578 		pReq->ExtPageType = pExtHdr->ExtPageType;
5579 		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5580 
5581 		/* Page Length must be treated as a reserved field for the extended header. */
5582 		pReq->Header.PageLength = 0;
5583 	}
5584 
5585 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5586 
5587 	/* Add a SGE to the config request.
5588 	 */
5589 	if (pCfg->dir)
5590 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5591 	else
5592 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5593 
5594 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5595 		flagsLength |= pExtHdr->ExtPageLength * 4;
5596 
5597 		dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5598 			ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5599 	}
5600 	else {
5601 		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5602 
5603 		dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5604 			ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5605 	}
5606 
5607 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5608 
5609 	/* Append pCfg pointer to end of mf
5610 	 */
5611 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
5612 
5613 	/* Initalize the timer
5614 	 */
5615 	init_timer(&pCfg->timer);
5616 	pCfg->timer.data = (unsigned long) ioc;
5617 	pCfg->timer.function = mpt_timer_expired;
5618 	pCfg->wait_done = 0;
5619 
5620 	/* Set the timer; ensure 10 second minimum */
5621 	if (pCfg->timeout < 10)
5622 		pCfg->timer.expires = jiffies + HZ*10;
5623 	else
5624 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5625 
5626 	/* Add to end of Q, set timer and then issue this command */
5627 	spin_lock_irqsave(&ioc->FreeQlock, flags);
5628 	list_add_tail(&pCfg->linkage, &ioc->configQ);
5629 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5630 
5631 	add_timer(&pCfg->timer);
5632 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
5633 	wait_event(mpt_waitq, pCfg->wait_done);
5634 
5635 	/* mf has been freed - do not access */
5636 
5637 	rc = pCfg->status;
5638 
5639 	return rc;
5640 }
5641 
5642 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5643 /**
5644  *	mpt_timer_expired - Callback for timer process.
5645  *	Used only internal config functionality.
5646  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5647  */
5648 static void
5649 mpt_timer_expired(unsigned long data)
5650 {
5651 	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5652 
5653 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5654 
5655 	/* Perform a FW reload */
5656 	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5657 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5658 
5659 	/* No more processing.
5660 	 * Hard reset clean-up will wake up
5661 	 * process and free all resources.
5662 	 */
5663 	dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5664 
5665 	return;
5666 }
5667 
5668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5669 /**
5670  *	mpt_ioc_reset - Base cleanup for hard reset
5671  *	@ioc: Pointer to the adapter structure
5672  *	@reset_phase: Indicates pre- or post-reset functionality
5673  *
5674  *	Remark: Frees resources with internally generated commands.
5675  */
5676 static int
5677 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5678 {
5679 	CONFIGPARMS *pCfg;
5680 	unsigned long flags;
5681 
5682 	dprintk((KERN_WARNING MYNAM
5683 			": IOC %s_reset routed to MPT base driver!\n",
5684 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5685 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5686 
5687 	if (reset_phase == MPT_IOC_SETUP_RESET) {
5688 		;
5689 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
5690 		/* If the internal config Q is not empty -
5691 		 * delete timer. MF resources will be freed when
5692 		 * the FIFO's are primed.
5693 		 */
5694 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5695 		list_for_each_entry(pCfg, &ioc->configQ, linkage)
5696 			del_timer(&pCfg->timer);
5697 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5698 
5699 	} else {
5700 		CONFIGPARMS *pNext;
5701 
5702 		/* Search the configQ for internal commands.
5703 		 * Flush the Q, and wake up all suspended threads.
5704 		 */
5705 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5706 		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5707 			list_del(&pCfg->linkage);
5708 
5709 			pCfg->status = MPT_CONFIG_ERROR;
5710 			pCfg->wait_done = 1;
5711 			wake_up(&mpt_waitq);
5712 		}
5713 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5714 	}
5715 
5716 	return 1;		/* currently means nothing really */
5717 }
5718 
5719 
5720 #ifdef CONFIG_PROC_FS		/* { */
5721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5722 /*
5723  *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5724  */
5725 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5726 /**
5727  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5728  *
5729  *	Returns 0 for success, non-zero for failure.
5730  */
5731 static int
5732 procmpt_create(void)
5733 {
5734 	struct proc_dir_entry	*ent;
5735 
5736 	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5737 	if (mpt_proc_root_dir == NULL)
5738 		return -ENOTDIR;
5739 
5740 	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5741 	if (ent)
5742 		ent->read_proc = procmpt_summary_read;
5743 
5744 	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5745 	if (ent)
5746 		ent->read_proc = procmpt_version_read;
5747 
5748 	return 0;
5749 }
5750 
5751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5752 /**
5753  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5754  *
5755  *	Returns 0 for success, non-zero for failure.
5756  */
5757 static void
5758 procmpt_destroy(void)
5759 {
5760 	remove_proc_entry("version", mpt_proc_root_dir);
5761 	remove_proc_entry("summary", mpt_proc_root_dir);
5762 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5763 }
5764 
5765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5766 /**
5767  *	procmpt_summary_read - Handle read request of a summary file
5768  *	@buf: Pointer to area to write information
5769  *	@start: Pointer to start pointer
5770  *	@offset: Offset to start writing
5771  *	@request: Amount of read data requested
5772  *	@eof: Pointer to EOF integer
5773  *	@data: Pointer
5774  *
5775  *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5776  *	Returns number of characters written to process performing the read.
5777  */
5778 static int
5779 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5780 {
5781 	MPT_ADAPTER *ioc;
5782 	char *out = buf;
5783 	int len;
5784 
5785 	if (data) {
5786 		int more = 0;
5787 
5788 		ioc = data;
5789 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5790 
5791 		out += more;
5792 	} else {
5793 		list_for_each_entry(ioc, &ioc_list, list) {
5794 			int	more = 0;
5795 
5796 			mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5797 
5798 			out += more;
5799 			if ((out-buf) >= request)
5800 				break;
5801 		}
5802 	}
5803 
5804 	len = out - buf;
5805 
5806 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5807 }
5808 
5809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5810 /**
5811  *	procmpt_version_read - Handle read request from /proc/mpt/version.
5812  *	@buf: Pointer to area to write information
5813  *	@start: Pointer to start pointer
5814  *	@offset: Offset to start writing
5815  *	@request: Amount of read data requested
5816  *	@eof: Pointer to EOF integer
5817  *	@data: Pointer
5818  *
5819  *	Returns number of characters written to process performing the read.
5820  */
5821 static int
5822 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5823 {
5824 	int	 ii;
5825 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
5826 	char	*drvname;
5827 	int	 len;
5828 
5829 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5830 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
5831 
5832 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
5833 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5834 		drvname = NULL;
5835 		if (MptCallbacks[ii]) {
5836 			switch (MptDriverClass[ii]) {
5837 			case MPTSPI_DRIVER:
5838 				if (!scsi++) drvname = "SPI host";
5839 				break;
5840 			case MPTFC_DRIVER:
5841 				if (!fc++) drvname = "FC host";
5842 				break;
5843 			case MPTSAS_DRIVER:
5844 				if (!sas++) drvname = "SAS host";
5845 				break;
5846 			case MPTLAN_DRIVER:
5847 				if (!lan++) drvname = "LAN";
5848 				break;
5849 			case MPTSTM_DRIVER:
5850 				if (!targ++) drvname = "SCSI target";
5851 				break;
5852 			case MPTCTL_DRIVER:
5853 				if (!ctl++) drvname = "ioctl";
5854 				break;
5855 			}
5856 
5857 			if (drvname)
5858 				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5859 		}
5860 	}
5861 
5862 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5863 }
5864 
5865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5866 /**
5867  *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5868  *	@buf: Pointer to area to write information
5869  *	@start: Pointer to start pointer
5870  *	@offset: Offset to start writing
5871  *	@request: Amount of read data requested
5872  *	@eof: Pointer to EOF integer
5873  *	@data: Pointer
5874  *
5875  *	Returns number of characters written to process performing the read.
5876  */
5877 static int
5878 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5879 {
5880 	MPT_ADAPTER	*ioc = data;
5881 	int		 len;
5882 	char		 expVer[32];
5883 	int		 sz;
5884 	int		 p;
5885 
5886 	mpt_get_fw_exp_ver(expVer, ioc);
5887 
5888 	len = sprintf(buf, "%s:", ioc->name);
5889 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5890 		len += sprintf(buf+len, "  (f/w download boot flag set)");
5891 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5892 //		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
5893 
5894 	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
5895 			ioc->facts.ProductID,
5896 			ioc->prod_name);
5897 	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5898 	if (ioc->facts.FWImageSize)
5899 		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5900 	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5901 	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5902 	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
5903 
5904 	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
5905 			ioc->facts.CurrentHostMfaHighAddr);
5906 	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
5907 			ioc->facts.CurrentSenseBufferHighAddr);
5908 
5909 	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5910 	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5911 
5912 	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5913 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5914 	/*
5915 	 *  Rounding UP to nearest 4-kB boundary here...
5916 	 */
5917 	sz = (ioc->req_sz * ioc->req_depth) + 128;
5918 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5919 	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5920 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5921 	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
5922 					4*ioc->facts.RequestFrameSize,
5923 					ioc->facts.GlobalCredits);
5924 
5925 	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
5926 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5927 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5928 	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5929 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5930 	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
5931 					ioc->facts.CurReplyFrameSize,
5932 					ioc->facts.ReplyQueueDepth);
5933 
5934 	len += sprintf(buf+len, "  MaxDevices = %d\n",
5935 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5936 	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
5937 
5938 	/* per-port info */
5939 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5940 		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
5941 				p+1,
5942 				ioc->facts.NumberOfPorts);
5943 		if (ioc->bus_type == FC) {
5944 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5945 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5946 				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5947 						a[5], a[4], a[3], a[2], a[1], a[0]);
5948 			}
5949 			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
5950 					ioc->fc_port_page0[p].WWNN.High,
5951 					ioc->fc_port_page0[p].WWNN.Low,
5952 					ioc->fc_port_page0[p].WWPN.High,
5953 					ioc->fc_port_page0[p].WWPN.Low);
5954 		}
5955 	}
5956 
5957 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5958 }
5959 
5960 #endif		/* CONFIG_PROC_FS } */
5961 
5962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5963 static void
5964 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5965 {
5966 	buf[0] ='\0';
5967 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5968 		sprintf(buf, " (Exp %02d%02d)",
5969 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
5970 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
5971 
5972 		/* insider hack! */
5973 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5974 			strcat(buf, " [MDBG]");
5975 	}
5976 }
5977 
5978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5979 /**
5980  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5981  *	@ioc: Pointer to MPT_ADAPTER structure
5982  *	@buffer: Pointer to buffer where IOC summary info should be written
5983  *	@size: Pointer to number of bytes we wrote (set by this routine)
5984  *	@len: Offset at which to start writing in buffer
5985  *	@showlan: Display LAN stuff?
5986  *
5987  *	This routine writes (english readable) ASCII text, which represents
5988  *	a summary of IOC information, to a buffer.
5989  */
5990 void
5991 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5992 {
5993 	char expVer[32];
5994 	int y;
5995 
5996 	mpt_get_fw_exp_ver(expVer, ioc);
5997 
5998 	/*
5999 	 *  Shorter summary of attached ioc's...
6000 	 */
6001 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6002 			ioc->name,
6003 			ioc->prod_name,
6004 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6005 			ioc->facts.FWVersion.Word,
6006 			expVer,
6007 			ioc->facts.NumberOfPorts,
6008 			ioc->req_depth);
6009 
6010 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6011 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6012 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6013 			a[5], a[4], a[3], a[2], a[1], a[0]);
6014 	}
6015 
6016 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6017 
6018 	if (!ioc->active)
6019 		y += sprintf(buffer+len+y, " (disabled)");
6020 
6021 	y += sprintf(buffer+len+y, "\n");
6022 
6023 	*size = y;
6024 }
6025 
6026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6027 /*
6028  *	Reset Handling
6029  */
6030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6031 /**
6032  *	mpt_HardResetHandler - Generic reset handler
6033  *	@ioc: Pointer to MPT_ADAPTER structure
6034  *	@sleepFlag: Indicates if sleep or schedule must be called.
6035  *
6036  *	Issues SCSI Task Management call based on input arg values.
6037  *	If TaskMgmt fails, returns associated SCSI request.
6038  *
6039  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6040  *	or a non-interrupt thread.  In the former, must not call schedule().
6041  *
6042  *	Note: A return of -1 is a FATAL error case, as it means a
6043  *	FW reload/initialization failed.
6044  *
6045  *	Returns 0 for SUCCESS or -1 if FAILED.
6046  */
6047 int
6048 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6049 {
6050 	int		 rc;
6051 	unsigned long	 flags;
6052 
6053 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
6054 #ifdef MFCNT
6055 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6056 	printk("MF count 0x%x !\n", ioc->mfcnt);
6057 #endif
6058 
6059 	/* Reset the adapter. Prevent more than 1 call to
6060 	 * mpt_do_ioc_recovery at any instant in time.
6061 	 */
6062 	spin_lock_irqsave(&ioc->diagLock, flags);
6063 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6064 		spin_unlock_irqrestore(&ioc->diagLock, flags);
6065 		return 0;
6066 	} else {
6067 		ioc->diagPending = 1;
6068 	}
6069 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6070 
6071 	/* FIXME: If do_ioc_recovery fails, repeat....
6072 	 */
6073 
6074 	/* The SCSI driver needs to adjust timeouts on all current
6075 	 * commands prior to the diagnostic reset being issued.
6076 	 * Prevents timeouts occurring during a diagnostic reset...very bad.
6077 	 * For all other protocol drivers, this is a no-op.
6078 	 */
6079 	{
6080 		int	 ii;
6081 		int	 r = 0;
6082 
6083 		for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6084 			if (MptResetHandlers[ii]) {
6085 				dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
6086 						ioc->name, ii));
6087 				r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
6088 				if (ioc->alt_ioc) {
6089 					dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
6090 							ioc->name, ioc->alt_ioc->name, ii));
6091 					r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6092 				}
6093 			}
6094 		}
6095 	}
6096 
6097 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6098 		printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6099 			rc, ioc->name);
6100 	}
6101 	ioc->reload_fw = 0;
6102 	if (ioc->alt_ioc)
6103 		ioc->alt_ioc->reload_fw = 0;
6104 
6105 	spin_lock_irqsave(&ioc->diagLock, flags);
6106 	ioc->diagPending = 0;
6107 	if (ioc->alt_ioc)
6108 		ioc->alt_ioc->diagPending = 0;
6109 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6110 
6111 	dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6112 
6113 	return rc;
6114 }
6115 
6116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6117 static void
6118 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6119 {
6120 	char *ds = NULL;
6121 
6122 	switch(event) {
6123 	case MPI_EVENT_NONE:
6124 		ds = "None";
6125 		break;
6126 	case MPI_EVENT_LOG_DATA:
6127 		ds = "Log Data";
6128 		break;
6129 	case MPI_EVENT_STATE_CHANGE:
6130 		ds = "State Change";
6131 		break;
6132 	case MPI_EVENT_UNIT_ATTENTION:
6133 		ds = "Unit Attention";
6134 		break;
6135 	case MPI_EVENT_IOC_BUS_RESET:
6136 		ds = "IOC Bus Reset";
6137 		break;
6138 	case MPI_EVENT_EXT_BUS_RESET:
6139 		ds = "External Bus Reset";
6140 		break;
6141 	case MPI_EVENT_RESCAN:
6142 		ds = "Bus Rescan Event";
6143 		break;
6144 	case MPI_EVENT_LINK_STATUS_CHANGE:
6145 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6146 			ds = "Link Status(FAILURE) Change";
6147 		else
6148 			ds = "Link Status(ACTIVE) Change";
6149 		break;
6150 	case MPI_EVENT_LOOP_STATE_CHANGE:
6151 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6152 			ds = "Loop State(LIP) Change";
6153 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6154 			ds = "Loop State(LPE) Change";		/* ??? */
6155 		else
6156 			ds = "Loop State(LPB) Change";		/* ??? */
6157 		break;
6158 	case MPI_EVENT_LOGOUT:
6159 		ds = "Logout";
6160 		break;
6161 	case MPI_EVENT_EVENT_CHANGE:
6162 		if (evData0)
6163 			ds = "Events ON";
6164 		else
6165 			ds = "Events OFF";
6166 		break;
6167 	case MPI_EVENT_INTEGRATED_RAID:
6168 	{
6169 		u8 ReasonCode = (u8)(evData0 >> 16);
6170 		switch (ReasonCode) {
6171 		case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6172 			ds = "Integrated Raid: Volume Created";
6173 			break;
6174 		case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6175 			ds = "Integrated Raid: Volume Deleted";
6176 			break;
6177 		case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6178 			ds = "Integrated Raid: Volume Settings Changed";
6179 			break;
6180 		case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6181 			ds = "Integrated Raid: Volume Status Changed";
6182 			break;
6183 		case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6184 			ds = "Integrated Raid: Volume Physdisk Changed";
6185 			break;
6186 		case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6187 			ds = "Integrated Raid: Physdisk Created";
6188 			break;
6189 		case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6190 			ds = "Integrated Raid: Physdisk Deleted";
6191 			break;
6192 		case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6193 			ds = "Integrated Raid: Physdisk Settings Changed";
6194 			break;
6195 		case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6196 			ds = "Integrated Raid: Physdisk Status Changed";
6197 			break;
6198 		case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6199 			ds = "Integrated Raid: Domain Validation Needed";
6200 			break;
6201 		case MPI_EVENT_RAID_RC_SMART_DATA :
6202 			ds = "Integrated Raid; Smart Data";
6203 			break;
6204 		case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6205 			ds = "Integrated Raid: Replace Action Started";
6206 			break;
6207 		default:
6208 			ds = "Integrated Raid";
6209 		break;
6210 		}
6211 		break;
6212 	}
6213 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6214 		ds = "SCSI Device Status Change";
6215 		break;
6216 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6217 	{
6218 		u8 id = (u8)(evData0);
6219 		u8 channel = (u8)(evData0 >> 8);
6220 		u8 ReasonCode = (u8)(evData0 >> 16);
6221 		switch (ReasonCode) {
6222 		case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6223 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6224 			    "SAS Device Status Change: Added: "
6225 			    "id=%d channel=%d", id, channel);
6226 			break;
6227 		case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6228 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6229 			    "SAS Device Status Change: Deleted: "
6230 			    "id=%d channel=%d", id, channel);
6231 			break;
6232 		case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6233 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6234 			    "SAS Device Status Change: SMART Data: "
6235 			    "id=%d channel=%d", id, channel);
6236 			break;
6237 		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6238 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6239 			    "SAS Device Status Change: No Persistancy: "
6240 			    "id=%d channel=%d", id, channel);
6241 			break;
6242 		case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6243 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6244 			    "SAS Device Status Change: Unsupported Device "
6245 			    "Discovered : id=%d channel=%d", id, channel);
6246 			break;
6247 		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6248 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6249 			    "SAS Device Status Change: Internal Device "
6250 			    "Reset : id=%d channel=%d", id, channel);
6251 			break;
6252 		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6253 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6254 			    "SAS Device Status Change: Internal Task "
6255 			    "Abort : id=%d channel=%d", id, channel);
6256 			break;
6257 		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6258 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6259 			    "SAS Device Status Change: Internal Abort "
6260 			    "Task Set : id=%d channel=%d", id, channel);
6261 			break;
6262 		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6263 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6264 			    "SAS Device Status Change: Internal Clear "
6265 			    "Task Set : id=%d channel=%d", id, channel);
6266 			break;
6267 		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6268 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6269 			    "SAS Device Status Change: Internal Query "
6270 			    "Task : id=%d channel=%d", id, channel);
6271 			break;
6272 		default:
6273 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6274 			    "SAS Device Status Change: Unknown: "
6275 			    "id=%d channel=%d", id, channel);
6276 			break;
6277 		}
6278 		break;
6279 	}
6280 	case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6281 		ds = "Bus Timer Expired";
6282 		break;
6283 	case MPI_EVENT_QUEUE_FULL:
6284 	{
6285 		u16 curr_depth = (u16)(evData0 >> 16);
6286 		u8 channel = (u8)(evData0 >> 8);
6287 		u8 id = (u8)(evData0);
6288 
6289 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6290 		   "Queue Full: channel=%d id=%d depth=%d",
6291 		   channel, id, curr_depth);
6292 		break;
6293 	}
6294 	case MPI_EVENT_SAS_SES:
6295 		ds = "SAS SES Event";
6296 		break;
6297 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
6298 		ds = "Persistent Table Full";
6299 		break;
6300 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
6301 	{
6302 		u8 LinkRates = (u8)(evData0 >> 8);
6303 		u8 PhyNumber = (u8)(evData0);
6304 		LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6305 			MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6306 		switch (LinkRates) {
6307 		case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6308 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6309 			   "SAS PHY Link Status: Phy=%d:"
6310 			   " Rate Unknown",PhyNumber);
6311 			break;
6312 		case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6313 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6314 			   "SAS PHY Link Status: Phy=%d:"
6315 			   " Phy Disabled",PhyNumber);
6316 			break;
6317 		case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6318 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6319 			   "SAS PHY Link Status: Phy=%d:"
6320 			   " Failed Speed Nego",PhyNumber);
6321 			break;
6322 		case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6323 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6324 			   "SAS PHY Link Status: Phy=%d:"
6325 			   " Sata OOB Completed",PhyNumber);
6326 			break;
6327 		case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6328 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6329 			   "SAS PHY Link Status: Phy=%d:"
6330 			   " Rate 1.5 Gbps",PhyNumber);
6331 			break;
6332 		case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6333 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6334 			   "SAS PHY Link Status: Phy=%d:"
6335 			   " Rate 3.0 Gpbs",PhyNumber);
6336 			break;
6337 		default:
6338 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6339 			   "SAS PHY Link Status: Phy=%d", PhyNumber);
6340 			break;
6341 		}
6342 		break;
6343 	}
6344 	case MPI_EVENT_SAS_DISCOVERY_ERROR:
6345 		ds = "SAS Discovery Error";
6346 		break;
6347 	case MPI_EVENT_IR_RESYNC_UPDATE:
6348 	{
6349 		u8 resync_complete = (u8)(evData0 >> 16);
6350 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6351 		    "IR Resync Update: Complete = %d:",resync_complete);
6352 		break;
6353 	}
6354 	case MPI_EVENT_IR2:
6355 	{
6356 		u8 ReasonCode = (u8)(evData0 >> 16);
6357 		switch (ReasonCode) {
6358 		case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6359 			ds = "IR2: LD State Changed";
6360 			break;
6361 		case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6362 			ds = "IR2: PD State Changed";
6363 			break;
6364 		case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6365 			ds = "IR2: Bad Block Table Full";
6366 			break;
6367 		case MPI_EVENT_IR2_RC_PD_INSERTED:
6368 			ds = "IR2: PD Inserted";
6369 			break;
6370 		case MPI_EVENT_IR2_RC_PD_REMOVED:
6371 			ds = "IR2: PD Removed";
6372 			break;
6373 		case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6374 			ds = "IR2: Foreign CFG Detected";
6375 			break;
6376 		case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6377 			ds = "IR2: Rebuild Medium Error";
6378 			break;
6379 		default:
6380 			ds = "IR2";
6381 		break;
6382 		}
6383 		break;
6384 	}
6385 	case MPI_EVENT_SAS_DISCOVERY:
6386 	{
6387 		if (evData0)
6388 			ds = "SAS Discovery: Start";
6389 		else
6390 			ds = "SAS Discovery: Stop";
6391 		break;
6392 	}
6393 	case MPI_EVENT_LOG_ENTRY_ADDED:
6394 		ds = "SAS Log Entry Added";
6395 		break;
6396 
6397 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6398 	{
6399 		u8 phy_num = (u8)(evData0);
6400 		u8 port_num = (u8)(evData0 >> 8);
6401 		u8 port_width = (u8)(evData0 >> 16);
6402 		u8 primative = (u8)(evData0 >> 24);
6403 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6404 		    "SAS Broadcase Primative: phy=%d port=%d "
6405 		    "width=%d primative=0x%02x",
6406 		    phy_num, port_num, port_width, primative);
6407 		break;
6408 	}
6409 
6410 	case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6411 	{
6412 		u8 reason = (u8)(evData0);
6413 		u8 port_num = (u8)(evData0 >> 8);
6414 		u16 handle = le16_to_cpu(evData0 >> 16);
6415 
6416 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6417 		    "SAS Initiator Device Status Change: reason=0x%02x "
6418 		    "port=%d handle=0x%04x",
6419 		    reason, port_num, handle);
6420 		break;
6421 	}
6422 
6423 	case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6424 	{
6425 		u8 max_init = (u8)(evData0);
6426 		u8 current_init = (u8)(evData0 >> 8);
6427 
6428 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6429 		    "SAS Initiator Device Table Overflow: max initiators=%02d "
6430 		    "current initators=%02d",
6431 		    max_init, current_init);
6432 		break;
6433 	}
6434 	case MPI_EVENT_SAS_SMP_ERROR:
6435 	{
6436 		u8 status = (u8)(evData0);
6437 		u8 port_num = (u8)(evData0 >> 8);
6438 		u8 result = (u8)(evData0 >> 16);
6439 
6440 		if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6441 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6442 			    "SAS SMP Error: port=%d result=0x%02x",
6443 			    port_num, result);
6444 		else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6445 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6446 			    "SAS SMP Error: port=%d : CRC Error",
6447 			    port_num);
6448 		else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6449 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6450 			    "SAS SMP Error: port=%d : Timeout",
6451 			    port_num);
6452 		else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6453 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6454 			    "SAS SMP Error: port=%d : No Destination",
6455 			    port_num);
6456 		else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6457 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 			    "SAS SMP Error: port=%d : Bad Destination",
6459 			    port_num);
6460 		else
6461 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6462 			    "SAS SMP Error: port=%d : status=0x%02x",
6463 			    port_num, status);
6464 		break;
6465 	}
6466 
6467 	/*
6468 	 *  MPT base "custom" events may be added here...
6469 	 */
6470 	default:
6471 		ds = "Unknown";
6472 		break;
6473 	}
6474 	if (ds)
6475 		strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6476 }
6477 
6478 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6479 /**
6480  *	ProcessEventNotification - Route EventNotificationReply to all event handlers
6481  *	@ioc: Pointer to MPT_ADAPTER structure
6482  *	@pEventReply: Pointer to EventNotification reply frame
6483  *	@evHandlers: Pointer to integer, number of event handlers
6484  *
6485  *	Routes a received EventNotificationReply to all currently registered
6486  *	event handlers.
6487  *	Returns sum of event handlers return values.
6488  */
6489 static int
6490 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6491 {
6492 	u16 evDataLen;
6493 	u32 evData0 = 0;
6494 //	u32 evCtx;
6495 	int ii;
6496 	int r = 0;
6497 	int handlers = 0;
6498 	char evStr[EVENT_DESCR_STR_SZ];
6499 	u8 event;
6500 
6501 	/*
6502 	 *  Do platform normalization of values
6503 	 */
6504 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
6505 //	evCtx = le32_to_cpu(pEventReply->EventContext);
6506 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6507 	if (evDataLen) {
6508 		evData0 = le32_to_cpu(pEventReply->Data[0]);
6509 	}
6510 
6511 	EventDescriptionStr(event, evData0, evStr);
6512 	devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6513 			ioc->name,
6514 			event,
6515 			evStr));
6516 
6517 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6518 	printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6519 	for (ii = 0; ii < evDataLen; ii++)
6520 		printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6521 	printk("\n");
6522 #endif
6523 
6524 	/*
6525 	 *  Do general / base driver event processing
6526 	 */
6527 	switch(event) {
6528 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
6529 		if (evDataLen) {
6530 			u8 evState = evData0 & 0xFF;
6531 
6532 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
6533 
6534 			/* Update EventState field in cached IocFacts */
6535 			if (ioc->facts.Function) {
6536 				ioc->facts.EventState = evState;
6537 			}
6538 		}
6539 		break;
6540 	case MPI_EVENT_INTEGRATED_RAID:
6541 		mptbase_raid_process_event_data(ioc,
6542 		    (MpiEventDataRaid_t *)pEventReply->Data);
6543 		break;
6544 	default:
6545 		break;
6546 	}
6547 
6548 	/*
6549 	 * Should this event be logged? Events are written sequentially.
6550 	 * When buffer is full, start again at the top.
6551 	 */
6552 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6553 		int idx;
6554 
6555 		idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6556 
6557 		ioc->events[idx].event = event;
6558 		ioc->events[idx].eventContext = ioc->eventContext;
6559 
6560 		for (ii = 0; ii < 2; ii++) {
6561 			if (ii < evDataLen)
6562 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6563 			else
6564 				ioc->events[idx].data[ii] =  0;
6565 		}
6566 
6567 		ioc->eventContext++;
6568 	}
6569 
6570 
6571 	/*
6572 	 *  Call each currently registered protocol event handler.
6573 	 */
6574 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6575 		if (MptEvHandlers[ii]) {
6576 			devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6577 					ioc->name, ii));
6578 			r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6579 			handlers++;
6580 		}
6581 	}
6582 	/* FIXME?  Examine results here? */
6583 
6584 	/*
6585 	 *  If needed, send (a single) EventAck.
6586 	 */
6587 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6588 		devtverboseprintk((MYIOC_s_WARN_FMT
6589 			"EventAck required\n",ioc->name));
6590 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6591 			devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6592 					ioc->name, ii));
6593 		}
6594 	}
6595 
6596 	*evHandlers = handlers;
6597 	return r;
6598 }
6599 
6600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6601 /**
6602  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6603  *	@ioc: Pointer to MPT_ADAPTER structure
6604  *	@log_info: U32 LogInfo reply word from the IOC
6605  *
6606  *	Refer to lsi/mpi_log_fc.h.
6607  */
6608 static void
6609 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6610 {
6611 	char *desc = "unknown";
6612 
6613 	switch (log_info & 0xFF000000) {
6614 	case MPI_IOCLOGINFO_FC_INIT_BASE:
6615 		desc = "FCP Initiator";
6616 		break;
6617 	case MPI_IOCLOGINFO_FC_TARGET_BASE:
6618 		desc = "FCP Target";
6619 		break;
6620 	case MPI_IOCLOGINFO_FC_LAN_BASE:
6621 		desc = "LAN";
6622 		break;
6623 	case MPI_IOCLOGINFO_FC_MSG_BASE:
6624 		desc = "MPI Message Layer";
6625 		break;
6626 	case MPI_IOCLOGINFO_FC_LINK_BASE:
6627 		desc = "FC Link";
6628 		break;
6629 	case MPI_IOCLOGINFO_FC_CTX_BASE:
6630 		desc = "Context Manager";
6631 		break;
6632 	case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6633 		desc = "Invalid Field Offset";
6634 		break;
6635 	case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6636 		desc = "State Change Info";
6637 		break;
6638 	}
6639 
6640 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6641 			ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6642 }
6643 
6644 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6645 /**
6646  *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6647  *	@ioc: Pointer to MPT_ADAPTER structure
6648  *	@mr: Pointer to MPT reply frame
6649  *	@log_info: U32 LogInfo word from the IOC
6650  *
6651  *	Refer to lsi/sp_log.h.
6652  */
6653 static void
6654 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6655 {
6656 	u32 info = log_info & 0x00FF0000;
6657 	char *desc = "unknown";
6658 
6659 	switch (info) {
6660 	case 0x00010000:
6661 		desc = "bug! MID not found";
6662 		if (ioc->reload_fw == 0)
6663 			ioc->reload_fw++;
6664 		break;
6665 
6666 	case 0x00020000:
6667 		desc = "Parity Error";
6668 		break;
6669 
6670 	case 0x00030000:
6671 		desc = "ASYNC Outbound Overrun";
6672 		break;
6673 
6674 	case 0x00040000:
6675 		desc = "SYNC Offset Error";
6676 		break;
6677 
6678 	case 0x00050000:
6679 		desc = "BM Change";
6680 		break;
6681 
6682 	case 0x00060000:
6683 		desc = "Msg In Overflow";
6684 		break;
6685 
6686 	case 0x00070000:
6687 		desc = "DMA Error";
6688 		break;
6689 
6690 	case 0x00080000:
6691 		desc = "Outbound DMA Overrun";
6692 		break;
6693 
6694 	case 0x00090000:
6695 		desc = "Task Management";
6696 		break;
6697 
6698 	case 0x000A0000:
6699 		desc = "Device Problem";
6700 		break;
6701 
6702 	case 0x000B0000:
6703 		desc = "Invalid Phase Change";
6704 		break;
6705 
6706 	case 0x000C0000:
6707 		desc = "Untagged Table Size";
6708 		break;
6709 
6710 	}
6711 
6712 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6713 }
6714 
6715 /* strings for sas loginfo */
6716 	static char *originator_str[] = {
6717 		"IOP",						/* 00h */
6718 		"PL",						/* 01h */
6719 		"IR"						/* 02h */
6720 	};
6721 	static char *iop_code_str[] = {
6722 		NULL,						/* 00h */
6723 		"Invalid SAS Address",				/* 01h */
6724 		NULL,						/* 02h */
6725 		"Invalid Page",					/* 03h */
6726 		"Diag Message Error",				/* 04h */
6727 		"Task Terminated",				/* 05h */
6728 		"Enclosure Management",				/* 06h */
6729 		"Target Mode"					/* 07h */
6730 	};
6731 	static char *pl_code_str[] = {
6732 		NULL,						/* 00h */
6733 		"Open Failure",					/* 01h */
6734 		"Invalid Scatter Gather List",			/* 02h */
6735 		"Wrong Relative Offset or Frame Length",	/* 03h */
6736 		"Frame Transfer Error",				/* 04h */
6737 		"Transmit Frame Connected Low",			/* 05h */
6738 		"SATA Non-NCQ RW Error Bit Set",		/* 06h */
6739 		"SATA Read Log Receive Data Error",		/* 07h */
6740 		"SATA NCQ Fail All Commands After Error",	/* 08h */
6741 		"SATA Error in Receive Set Device Bit FIS",	/* 09h */
6742 		"Receive Frame Invalid Message",		/* 0Ah */
6743 		"Receive Context Message Valid Error",		/* 0Bh */
6744 		"Receive Frame Current Frame Error",		/* 0Ch */
6745 		"SATA Link Down",				/* 0Dh */
6746 		"Discovery SATA Init W IOS",			/* 0Eh */
6747 		"Config Invalid Page",				/* 0Fh */
6748 		"Discovery SATA Init Timeout",			/* 10h */
6749 		"Reset",					/* 11h */
6750 		"Abort",					/* 12h */
6751 		"IO Not Yet Executed",				/* 13h */
6752 		"IO Executed",					/* 14h */
6753 		"Persistent Reservation Out Not Affiliation "
6754 		    "Owner", 					/* 15h */
6755 		"Open Transmit DMA Abort",			/* 16h */
6756 		"IO Device Missing Delay Retry",		/* 17h */
6757 		"IO Cancelled Due to Recieve Error",		/* 18h */
6758 		NULL,						/* 19h */
6759 		NULL,						/* 1Ah */
6760 		NULL,						/* 1Bh */
6761 		NULL,						/* 1Ch */
6762 		NULL,						/* 1Dh */
6763 		NULL,						/* 1Eh */
6764 		NULL,						/* 1Fh */
6765 		"Enclosure Management"				/* 20h */
6766 	};
6767 	static char *ir_code_str[] = {
6768 		"Raid Action Error",				/* 00h */
6769 		NULL,						/* 00h */
6770 		NULL,						/* 01h */
6771 		NULL,						/* 02h */
6772 		NULL,						/* 03h */
6773 		NULL,						/* 04h */
6774 		NULL,						/* 05h */
6775 		NULL,						/* 06h */
6776 		NULL						/* 07h */
6777 	};
6778 	static char *raid_sub_code_str[] = {
6779 		NULL, 						/* 00h */
6780 		"Volume Creation Failed: Data Passed too "
6781 		    "Large", 					/* 01h */
6782 		"Volume Creation Failed: Duplicate Volumes "
6783 		    "Attempted", 				/* 02h */
6784 		"Volume Creation Failed: Max Number "
6785 		    "Supported Volumes Exceeded",		/* 03h */
6786 		"Volume Creation Failed: DMA Error",		/* 04h */
6787 		"Volume Creation Failed: Invalid Volume Type",	/* 05h */
6788 		"Volume Creation Failed: Error Reading "
6789 		    "MFG Page 4", 				/* 06h */
6790 		"Volume Creation Failed: Creating Internal "
6791 		    "Structures", 				/* 07h */
6792 		NULL,						/* 08h */
6793 		NULL,						/* 09h */
6794 		NULL,						/* 0Ah */
6795 		NULL,						/* 0Bh */
6796 		NULL,						/* 0Ch */
6797 		NULL,						/* 0Dh */
6798 		NULL,						/* 0Eh */
6799 		NULL,						/* 0Fh */
6800 		"Activation failed: Already Active Volume", 	/* 10h */
6801 		"Activation failed: Unsupported Volume Type", 	/* 11h */
6802 		"Activation failed: Too Many Active Volumes", 	/* 12h */
6803 		"Activation failed: Volume ID in Use", 		/* 13h */
6804 		"Activation failed: Reported Failure", 		/* 14h */
6805 		"Activation failed: Importing a Volume", 	/* 15h */
6806 		NULL,						/* 16h */
6807 		NULL,						/* 17h */
6808 		NULL,						/* 18h */
6809 		NULL,						/* 19h */
6810 		NULL,						/* 1Ah */
6811 		NULL,						/* 1Bh */
6812 		NULL,						/* 1Ch */
6813 		NULL,						/* 1Dh */
6814 		NULL,						/* 1Eh */
6815 		NULL,						/* 1Fh */
6816 		"Phys Disk failed: Too Many Phys Disks", 	/* 20h */
6817 		"Phys Disk failed: Data Passed too Large",	/* 21h */
6818 		"Phys Disk failed: DMA Error", 			/* 22h */
6819 		"Phys Disk failed: Invalid <channel:id>", 	/* 23h */
6820 		"Phys Disk failed: Creating Phys Disk Config "
6821 		    "Page", 					/* 24h */
6822 		NULL,						/* 25h */
6823 		NULL,						/* 26h */
6824 		NULL,						/* 27h */
6825 		NULL,						/* 28h */
6826 		NULL,						/* 29h */
6827 		NULL,						/* 2Ah */
6828 		NULL,						/* 2Bh */
6829 		NULL,						/* 2Ch */
6830 		NULL,						/* 2Dh */
6831 		NULL,						/* 2Eh */
6832 		NULL,						/* 2Fh */
6833 		"Compatibility Error: IR Disabled",		/* 30h */
6834 		"Compatibility Error: Inquiry Comand Failed",	/* 31h */
6835 		"Compatibility Error: Device not Direct Access "
6836 		    "Device ",					/* 32h */
6837 		"Compatibility Error: Removable Device Found",	/* 33h */
6838 		"Compatibility Error: Device SCSI Version not "
6839 		    "2 or Higher", 				/* 34h */
6840 		"Compatibility Error: SATA Device, 48 BIT LBA "
6841 		    "not Supported", 				/* 35h */
6842 		"Compatibility Error: Device doesn't have "
6843 		    "512 Byte Block Sizes", 			/* 36h */
6844 		"Compatibility Error: Volume Type Check Failed", /* 37h */
6845 		"Compatibility Error: Volume Type is "
6846 		    "Unsupported by FW", 			/* 38h */
6847 		"Compatibility Error: Disk Drive too Small for "
6848 		    "use in Volume", 				/* 39h */
6849 		"Compatibility Error: Phys Disk for Create "
6850 		    "Volume not Found", 			/* 3Ah */
6851 		"Compatibility Error: Too Many or too Few "
6852 		    "Disks for Volume Type", 			/* 3Bh */
6853 		"Compatibility Error: Disk stripe Sizes "
6854 		    "Must be 64KB", 				/* 3Ch */
6855 		"Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6856 	};
6857 
6858 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6859 /**
6860  *	mpt_sas_log_info - Log information returned from SAS IOC.
6861  *	@ioc: Pointer to MPT_ADAPTER structure
6862  *	@log_info: U32 LogInfo reply word from the IOC
6863  *
6864  *	Refer to lsi/mpi_log_sas.h.
6865  **/
6866 static void
6867 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6868 {
6869 union loginfo_type {
6870 	u32	loginfo;
6871 	struct {
6872 		u32	subcode:16;
6873 		u32	code:8;
6874 		u32	originator:4;
6875 		u32	bus_type:4;
6876 	}dw;
6877 };
6878 	union loginfo_type sas_loginfo;
6879 	char *originator_desc = NULL;
6880 	char *code_desc = NULL;
6881 	char *sub_code_desc = NULL;
6882 
6883 	sas_loginfo.loginfo = log_info;
6884 	if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6885 	    (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6886 		return;
6887 
6888 	originator_desc = originator_str[sas_loginfo.dw.originator];
6889 
6890 	switch (sas_loginfo.dw.originator) {
6891 
6892 		case 0:  /* IOP */
6893 			if (sas_loginfo.dw.code <
6894 			    sizeof(iop_code_str)/sizeof(char*))
6895 				code_desc = iop_code_str[sas_loginfo.dw.code];
6896 			break;
6897 		case 1:  /* PL */
6898 			if (sas_loginfo.dw.code <
6899 			    sizeof(pl_code_str)/sizeof(char*))
6900 				code_desc = pl_code_str[sas_loginfo.dw.code];
6901 			break;
6902 		case 2:  /* IR */
6903 			if (sas_loginfo.dw.code >=
6904 			    sizeof(ir_code_str)/sizeof(char*))
6905 				break;
6906 			code_desc = ir_code_str[sas_loginfo.dw.code];
6907 			if (sas_loginfo.dw.subcode >=
6908 			    sizeof(raid_sub_code_str)/sizeof(char*))
6909 			break;
6910 			if (sas_loginfo.dw.code == 0)
6911 				sub_code_desc =
6912 				    raid_sub_code_str[sas_loginfo.dw.subcode];
6913 			break;
6914 		default:
6915 			return;
6916 	}
6917 
6918 	if (sub_code_desc != NULL)
6919 		printk(MYIOC_s_INFO_FMT
6920 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
6921 			" SubCode={%s}\n",
6922 			ioc->name, log_info, originator_desc, code_desc,
6923 			sub_code_desc);
6924 	else if (code_desc != NULL)
6925 		printk(MYIOC_s_INFO_FMT
6926 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
6927 			" SubCode(0x%04x)\n",
6928 			ioc->name, log_info, originator_desc, code_desc,
6929 			sas_loginfo.dw.subcode);
6930 	else
6931 		printk(MYIOC_s_INFO_FMT
6932 			"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6933 			" SubCode(0x%04x)\n",
6934 			ioc->name, log_info, originator_desc,
6935 			sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6936 }
6937 
6938 #ifdef MPT_DEBUG_REPLY
6939 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6940 /**
6941  *	mpt_iocstatus_info_config - IOCSTATUS information for config pages
6942  *	@ioc: Pointer to MPT_ADAPTER structure
6943  *	@ioc_status: U32 IOCStatus word from IOC
6944  *	@mf: Pointer to MPT request frame
6945  *
6946  *	Refer to lsi/mpi.h.
6947  **/
6948 static void
6949 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6950 {
6951 	Config_t *pReq = (Config_t *)mf;
6952 	char extend_desc[EVENT_DESCR_STR_SZ];
6953 	char *desc = NULL;
6954 	u32 form;
6955 	u8 page_type;
6956 
6957 	if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6958 		page_type = pReq->ExtPageType;
6959 	else
6960 		page_type = pReq->Header.PageType;
6961 
6962 	/*
6963 	 * ignore invalid page messages for GET_NEXT_HANDLE
6964 	 */
6965 	form = le32_to_cpu(pReq->PageAddress);
6966 	if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6967 		if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6968 		    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6969 		    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6970 			if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6971 				MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6972 				return;
6973 		}
6974 		if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6975 			if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6976 				MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6977 				return;
6978 	}
6979 
6980 	snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6981 	    "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6982 	    page_type, pReq->Header.PageNumber, pReq->Action, form);
6983 
6984 	switch (ioc_status) {
6985 
6986 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6987 		desc = "Config Page Invalid Action";
6988 		break;
6989 
6990 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
6991 		desc = "Config Page Invalid Type";
6992 		break;
6993 
6994 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
6995 		desc = "Config Page Invalid Page";
6996 		break;
6997 
6998 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
6999 		desc = "Config Page Invalid Data";
7000 		break;
7001 
7002 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7003 		desc = "Config Page No Defaults";
7004 		break;
7005 
7006 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7007 		desc = "Config Page Can't Commit";
7008 		break;
7009 	}
7010 
7011 	if (!desc)
7012 		return;
7013 
7014 	printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7015 	    ioc->name, ioc_status, desc, extend_desc);
7016 }
7017 
7018 /**
7019  *	mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7020  *	@ioc: Pointer to MPT_ADAPTER structure
7021  *	@ioc_status: U32 IOCStatus word from IOC
7022  *	@mf: Pointer to MPT request frame
7023  *
7024  *	Refer to lsi/mpi.h.
7025  **/
7026 static void
7027 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7028 {
7029 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7030 	char *desc = NULL;
7031 
7032 	switch (status) {
7033 
7034 /****************************************************************************/
7035 /*  Common IOCStatus values for all replies                                 */
7036 /****************************************************************************/
7037 
7038 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7039 		desc = "Invalid Function";
7040 		break;
7041 
7042 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7043 		desc = "Busy";
7044 		break;
7045 
7046 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7047 		desc = "Invalid SGL";
7048 		break;
7049 
7050 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7051 		desc = "Internal Error";
7052 		break;
7053 
7054 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7055 		desc = "Reserved";
7056 		break;
7057 
7058 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7059 		desc = "Insufficient Resources";
7060 		break;
7061 
7062 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7063 		desc = "Invalid Field";
7064 		break;
7065 
7066 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7067 		desc = "Invalid State";
7068 		break;
7069 
7070 /****************************************************************************/
7071 /*  Config IOCStatus values                                                 */
7072 /****************************************************************************/
7073 
7074 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7075 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
7076 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
7077 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
7078 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7079 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7080 		mpt_iocstatus_info_config(ioc, status, mf);
7081 		break;
7082 
7083 /****************************************************************************/
7084 /*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
7085 /*                                                                          */
7086 /*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7087 /*                                                                          */
7088 /****************************************************************************/
7089 
7090 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7091 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7092 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7093 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7094 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7095 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7096 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7097 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7098 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7099 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7100 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7101 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7102 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7103 		break;
7104 
7105 /****************************************************************************/
7106 /*  SCSI Target values                                                      */
7107 /****************************************************************************/
7108 
7109 	case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7110 		desc = "Target: Priority IO";
7111 		break;
7112 
7113 	case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7114 		desc = "Target: Invalid Port";
7115 		break;
7116 
7117 	case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7118 		desc = "Target Invalid IO Index:";
7119 		break;
7120 
7121 	case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7122 		desc = "Target: Aborted";
7123 		break;
7124 
7125 	case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7126 		desc = "Target: No Conn Retryable";
7127 		break;
7128 
7129 	case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7130 		desc = "Target: No Connection";
7131 		break;
7132 
7133 	case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7134 		desc = "Target: Transfer Count Mismatch";
7135 		break;
7136 
7137 	case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7138 		desc = "Target: STS Data not Sent";
7139 		break;
7140 
7141 	case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7142 		desc = "Target: Data Offset Error";
7143 		break;
7144 
7145 	case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7146 		desc = "Target: Too Much Write Data";
7147 		break;
7148 
7149 	case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7150 		desc = "Target: IU Too Short";
7151 		break;
7152 
7153 	case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7154 		desc = "Target: ACK NAK Timeout";
7155 		break;
7156 
7157 	case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7158 		desc = "Target: Nak Received";
7159 		break;
7160 
7161 /****************************************************************************/
7162 /*  Fibre Channel Direct Access values                                      */
7163 /****************************************************************************/
7164 
7165 	case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7166 		desc = "FC: Aborted";
7167 		break;
7168 
7169 	case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7170 		desc = "FC: RX ID Invalid";
7171 		break;
7172 
7173 	case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7174 		desc = "FC: DID Invalid";
7175 		break;
7176 
7177 	case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7178 		desc = "FC: Node Logged Out";
7179 		break;
7180 
7181 	case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7182 		desc = "FC: Exchange Canceled";
7183 		break;
7184 
7185 /****************************************************************************/
7186 /*  LAN values                                                              */
7187 /****************************************************************************/
7188 
7189 	case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7190 		desc = "LAN: Device not Found";
7191 		break;
7192 
7193 	case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7194 		desc = "LAN: Device Failure";
7195 		break;
7196 
7197 	case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7198 		desc = "LAN: Transmit Error";
7199 		break;
7200 
7201 	case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7202 		desc = "LAN: Transmit Aborted";
7203 		break;
7204 
7205 	case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7206 		desc = "LAN: Receive Error";
7207 		break;
7208 
7209 	case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7210 		desc = "LAN: Receive Aborted";
7211 		break;
7212 
7213 	case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7214 		desc = "LAN: Partial Packet";
7215 		break;
7216 
7217 	case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7218 		desc = "LAN: Canceled";
7219 		break;
7220 
7221 /****************************************************************************/
7222 /*  Serial Attached SCSI values                                             */
7223 /****************************************************************************/
7224 
7225 	case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7226 		desc = "SAS: SMP Request Failed";
7227 		break;
7228 
7229 	case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7230 		desc = "SAS: SMP Data Overrun";
7231 		break;
7232 
7233 	default:
7234 		desc = "Others";
7235 		break;
7236 	}
7237 
7238 	if (!desc)
7239 		return;
7240 
7241 	printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7242 }
7243 #endif
7244 
7245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7246 EXPORT_SYMBOL(mpt_attach);
7247 EXPORT_SYMBOL(mpt_detach);
7248 #ifdef CONFIG_PM
7249 EXPORT_SYMBOL(mpt_resume);
7250 EXPORT_SYMBOL(mpt_suspend);
7251 #endif
7252 EXPORT_SYMBOL(ioc_list);
7253 EXPORT_SYMBOL(mpt_proc_root_dir);
7254 EXPORT_SYMBOL(mpt_register);
7255 EXPORT_SYMBOL(mpt_deregister);
7256 EXPORT_SYMBOL(mpt_event_register);
7257 EXPORT_SYMBOL(mpt_event_deregister);
7258 EXPORT_SYMBOL(mpt_reset_register);
7259 EXPORT_SYMBOL(mpt_reset_deregister);
7260 EXPORT_SYMBOL(mpt_device_driver_register);
7261 EXPORT_SYMBOL(mpt_device_driver_deregister);
7262 EXPORT_SYMBOL(mpt_get_msg_frame);
7263 EXPORT_SYMBOL(mpt_put_msg_frame);
7264 EXPORT_SYMBOL(mpt_free_msg_frame);
7265 EXPORT_SYMBOL(mpt_add_sge);
7266 EXPORT_SYMBOL(mpt_send_handshake_request);
7267 EXPORT_SYMBOL(mpt_verify_adapter);
7268 EXPORT_SYMBOL(mpt_GetIocState);
7269 EXPORT_SYMBOL(mpt_print_ioc_summary);
7270 EXPORT_SYMBOL(mpt_lan_index);
7271 EXPORT_SYMBOL(mpt_stm_index);
7272 EXPORT_SYMBOL(mpt_HardResetHandler);
7273 EXPORT_SYMBOL(mpt_config);
7274 EXPORT_SYMBOL(mpt_findImVolumes);
7275 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7276 EXPORT_SYMBOL(mpt_free_fw_memory);
7277 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7278 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7279 
7280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7281 /**
7282  *	fusion_init - Fusion MPT base driver initialization routine.
7283  *
7284  *	Returns 0 for success, non-zero for failure.
7285  */
7286 static int __init
7287 fusion_init(void)
7288 {
7289 	int i;
7290 
7291 	show_mptmod_ver(my_NAME, my_VERSION);
7292 	printk(KERN_INFO COPYRIGHT "\n");
7293 
7294 	for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7295 		MptCallbacks[i] = NULL;
7296 		MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7297 		MptEvHandlers[i] = NULL;
7298 		MptResetHandlers[i] = NULL;
7299 	}
7300 
7301 	/*  Register ourselves (mptbase) in order to facilitate
7302 	 *  EventNotification handling.
7303 	 */
7304 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7305 
7306 	/* Register for hard reset handling callbacks.
7307 	 */
7308 	if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
7309 		dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
7310 	} else {
7311 		/* FIXME! */
7312 	}
7313 
7314 #ifdef CONFIG_PROC_FS
7315 	(void) procmpt_create();
7316 #endif
7317 	return 0;
7318 }
7319 
7320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7321 /**
7322  *	fusion_exit - Perform driver unload cleanup.
7323  *
7324  *	This routine frees all resources associated with each MPT adapter
7325  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
7326  */
7327 static void __exit
7328 fusion_exit(void)
7329 {
7330 
7331 	dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
7332 
7333 	mpt_reset_deregister(mpt_base_index);
7334 
7335 #ifdef CONFIG_PROC_FS
7336 	procmpt_destroy();
7337 #endif
7338 }
7339 
7340 module_init(fusion_init);
7341 module_exit(fusion_exit);
7342