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