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