xref: /openbmc/linux/drivers/message/fusion/mptbase.c (revision 643d1f7f)
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->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_DEBUG_FMT "%s: Pushing FW onto "
2266 		    "adapter\n", __FUNCTION__, ioc->name));
2267 		if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2268 		    ioc->cached_fw, CAN_SLEEP)) < 0) {
2269 			printk(MYIOC_s_WARN_FMT
2270 			    ": firmware downloadboot failure (%d)!\n",
2271 			    ioc->name, ret);
2272 		}
2273 	}
2274 
2275 	/* Disable adapter interrupts! */
2276 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2277 	ioc->active = 0;
2278 	/* Clear any lingering interrupt */
2279 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2280 
2281 	if (ioc->alloc != NULL) {
2282 		sz = ioc->alloc_sz;
2283 		dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free  @ %p, sz=%d bytes\n",
2284 		    ioc->name, ioc->alloc, ioc->alloc_sz));
2285 		pci_free_consistent(ioc->pcidev, sz,
2286 				ioc->alloc, ioc->alloc_dma);
2287 		ioc->reply_frames = NULL;
2288 		ioc->req_frames = NULL;
2289 		ioc->alloc = NULL;
2290 		ioc->alloc_total -= sz;
2291 	}
2292 
2293 	if (ioc->sense_buf_pool != NULL) {
2294 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2295 		pci_free_consistent(ioc->pcidev, sz,
2296 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2297 		ioc->sense_buf_pool = NULL;
2298 		ioc->alloc_total -= sz;
2299 	}
2300 
2301 	if (ioc->events != NULL){
2302 		sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2303 		kfree(ioc->events);
2304 		ioc->events = NULL;
2305 		ioc->alloc_total -= sz;
2306 	}
2307 
2308 	mpt_free_fw_memory(ioc);
2309 
2310 	kfree(ioc->spi_data.nvram);
2311 	mpt_inactive_raid_list_free(ioc);
2312 	kfree(ioc->raid_data.pIocPg2);
2313 	kfree(ioc->raid_data.pIocPg3);
2314 	ioc->spi_data.nvram = NULL;
2315 	ioc->raid_data.pIocPg3 = NULL;
2316 
2317 	if (ioc->spi_data.pIocPg4 != NULL) {
2318 		sz = ioc->spi_data.IocPg4Sz;
2319 		pci_free_consistent(ioc->pcidev, sz,
2320 			ioc->spi_data.pIocPg4,
2321 			ioc->spi_data.IocPg4_dma);
2322 		ioc->spi_data.pIocPg4 = NULL;
2323 		ioc->alloc_total -= sz;
2324 	}
2325 
2326 	if (ioc->ReqToChain != NULL) {
2327 		kfree(ioc->ReqToChain);
2328 		kfree(ioc->RequestNB);
2329 		ioc->ReqToChain = NULL;
2330 	}
2331 
2332 	kfree(ioc->ChainToChain);
2333 	ioc->ChainToChain = NULL;
2334 
2335 	if (ioc->HostPageBuffer != NULL) {
2336 		if((ret = mpt_host_page_access_control(ioc,
2337 		    MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2338 			printk(MYIOC_s_ERR_FMT
2339 			   "host page buffers free failed (%d)!\n",
2340 			    ioc->name, ret);
2341 		}
2342 		dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free  @ %p, sz=%d bytes\n",
2343 		 	ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2344 		pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2345 		    ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2346 		ioc->HostPageBuffer = NULL;
2347 		ioc->HostPageBuffer_sz = 0;
2348 		ioc->alloc_total -= ioc->HostPageBuffer_sz;
2349 	}
2350 }
2351 
2352 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2353 /**
2354  *	mpt_adapter_dispose - Free all resources associated with an MPT adapter
2355  *	@ioc: Pointer to MPT adapter structure
2356  *
2357  *	This routine unregisters h/w resources and frees all alloc'd memory
2358  *	associated with a MPT adapter structure.
2359  */
2360 static void
2361 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2362 {
2363 	int sz_first, sz_last;
2364 
2365 	if (ioc == NULL)
2366 		return;
2367 
2368 	sz_first = ioc->alloc_total;
2369 
2370 	mpt_adapter_disable(ioc);
2371 
2372 	if (ioc->pci_irq != -1) {
2373 		free_irq(ioc->pci_irq, ioc);
2374 		if (mpt_msi_enable)
2375 			pci_disable_msi(ioc->pcidev);
2376 		ioc->pci_irq = -1;
2377 	}
2378 
2379 	if (ioc->memmap != NULL) {
2380 		iounmap(ioc->memmap);
2381 		ioc->memmap = NULL;
2382 	}
2383 
2384 #if defined(CONFIG_MTRR) && 0
2385 	if (ioc->mtrr_reg > 0) {
2386 		mtrr_del(ioc->mtrr_reg, 0, 0);
2387 		dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2388 	}
2389 #endif
2390 
2391 	/*  Zap the adapter lookup ptr!  */
2392 	list_del(&ioc->list);
2393 
2394 	sz_last = ioc->alloc_total;
2395 	dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2396 	    ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2397 
2398 	if (ioc->alt_ioc)
2399 		ioc->alt_ioc->alt_ioc = NULL;
2400 
2401 	kfree(ioc);
2402 }
2403 
2404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2405 /**
2406  *	MptDisplayIocCapabilities - Disply IOC's capabilities.
2407  *	@ioc: Pointer to MPT adapter structure
2408  */
2409 static void
2410 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2411 {
2412 	int i = 0;
2413 
2414 	printk(KERN_INFO "%s: ", ioc->name);
2415 	if (ioc->prod_name)
2416 		printk("%s: ", ioc->prod_name);
2417 	printk("Capabilities={");
2418 
2419 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2420 		printk("Initiator");
2421 		i++;
2422 	}
2423 
2424 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2425 		printk("%sTarget", i ? "," : "");
2426 		i++;
2427 	}
2428 
2429 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2430 		printk("%sLAN", i ? "," : "");
2431 		i++;
2432 	}
2433 
2434 #if 0
2435 	/*
2436 	 *  This would probably evoke more questions than it's worth
2437 	 */
2438 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2439 		printk("%sLogBusAddr", i ? "," : "");
2440 		i++;
2441 	}
2442 #endif
2443 
2444 	printk("}\n");
2445 }
2446 
2447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2448 /**
2449  *	MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2450  *	@ioc: Pointer to MPT_ADAPTER structure
2451  *	@force: Force hard KickStart of IOC
2452  *	@sleepFlag: Specifies whether the process can sleep
2453  *
2454  *	Returns:
2455  *		 1 - DIAG reset and READY
2456  *		 0 - READY initially OR soft reset and READY
2457  *		-1 - Any failure on KickStart
2458  *		-2 - Msg Unit Reset Failed
2459  *		-3 - IO Unit Reset Failed
2460  *		-4 - IOC owned by a PEER
2461  */
2462 static int
2463 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2464 {
2465 	u32	 ioc_state;
2466 	int	 statefault = 0;
2467 	int	 cntdn;
2468 	int	 hard_reset_done = 0;
2469 	int	 r;
2470 	int	 ii;
2471 	int	 whoinit;
2472 
2473 	/* Get current [raw] IOC state  */
2474 	ioc_state = mpt_GetIocState(ioc, 0);
2475 	dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2476 
2477 	/*
2478 	 *	Check to see if IOC got left/stuck in doorbell handshake
2479 	 *	grip of death.  If so, hard reset the IOC.
2480 	 */
2481 	if (ioc_state & MPI_DOORBELL_ACTIVE) {
2482 		statefault = 1;
2483 		printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2484 				ioc->name);
2485 	}
2486 
2487 	/* Is it already READY? */
2488 	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2489 		return 0;
2490 
2491 	/*
2492 	 *	Check to see if IOC is in FAULT state.
2493 	 */
2494 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2495 		statefault = 2;
2496 		printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2497 		    ioc->name);
2498 		printk(MYIOC_s_WARN_FMT "           FAULT code = %04xh\n",
2499 		    ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2500 	}
2501 
2502 	/*
2503 	 *	Hmmm...  Did it get left operational?
2504 	 */
2505 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2506 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2507 				ioc->name));
2508 
2509 		/* Check WhoInit.
2510 		 * If PCI Peer, exit.
2511 		 * Else, if no fault conditions are present, issue a MessageUnitReset
2512 		 * Else, fall through to KickStart case
2513 		 */
2514 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2515 		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2516 			"whoinit 0x%x statefault %d force %d\n",
2517 			ioc->name, whoinit, statefault, force));
2518 		if (whoinit == MPI_WHOINIT_PCI_PEER)
2519 			return -4;
2520 		else {
2521 			if ((statefault == 0 ) && (force == 0)) {
2522 				if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2523 					return 0;
2524 			}
2525 			statefault = 3;
2526 		}
2527 	}
2528 
2529 	hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2530 	if (hard_reset_done < 0)
2531 		return -1;
2532 
2533 	/*
2534 	 *  Loop here waiting for IOC to come READY.
2535 	 */
2536 	ii = 0;
2537 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;	/* 5 seconds */
2538 
2539 	while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2540 		if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2541 			/*
2542 			 *  BIOS or previous driver load left IOC in OP state.
2543 			 *  Reset messaging FIFOs.
2544 			 */
2545 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2546 				printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2547 				return -2;
2548 			}
2549 		} else if (ioc_state == MPI_IOC_STATE_RESET) {
2550 			/*
2551 			 *  Something is wrong.  Try to get IOC back
2552 			 *  to a known state.
2553 			 */
2554 			if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2555 				printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2556 				return -3;
2557 			}
2558 		}
2559 
2560 		ii++; cntdn--;
2561 		if (!cntdn) {
2562 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2563 					ioc->name, (int)((ii+5)/HZ));
2564 			return -ETIME;
2565 		}
2566 
2567 		if (sleepFlag == CAN_SLEEP) {
2568 			msleep(1);
2569 		} else {
2570 			mdelay (1);	/* 1 msec delay */
2571 		}
2572 
2573 	}
2574 
2575 	if (statefault < 3) {
2576 		printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2577 				ioc->name,
2578 				statefault==1 ? "stuck handshake" : "IOC FAULT");
2579 	}
2580 
2581 	return hard_reset_done;
2582 }
2583 
2584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2585 /**
2586  *	mpt_GetIocState - Get the current state of a MPT adapter.
2587  *	@ioc: Pointer to MPT_ADAPTER structure
2588  *	@cooked: Request raw or cooked IOC state
2589  *
2590  *	Returns all IOC Doorbell register bits if cooked==0, else just the
2591  *	Doorbell bits in MPI_IOC_STATE_MASK.
2592  */
2593 u32
2594 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2595 {
2596 	u32 s, sc;
2597 
2598 	/*  Get!  */
2599 	s = CHIPREG_READ32(&ioc->chip->Doorbell);
2600 	sc = s & MPI_IOC_STATE_MASK;
2601 
2602 	/*  Save!  */
2603 	ioc->last_state = sc;
2604 
2605 	return cooked ? sc : s;
2606 }
2607 
2608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2609 /**
2610  *	GetIocFacts - Send IOCFacts request to MPT adapter.
2611  *	@ioc: Pointer to MPT_ADAPTER structure
2612  *	@sleepFlag: Specifies whether the process can sleep
2613  *	@reason: If recovery, only update facts.
2614  *
2615  *	Returns 0 for success, non-zero for failure.
2616  */
2617 static int
2618 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2619 {
2620 	IOCFacts_t		 get_facts;
2621 	IOCFactsReply_t		*facts;
2622 	int			 r;
2623 	int			 req_sz;
2624 	int			 reply_sz;
2625 	int			 sz;
2626 	u32			 status, vv;
2627 	u8			 shiftFactor=1;
2628 
2629 	/* IOC *must* NOT be in RESET state! */
2630 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2631 		printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2632 		    ioc->name, ioc->last_state );
2633 		return -44;
2634 	}
2635 
2636 	facts = &ioc->facts;
2637 
2638 	/* Destination (reply area)... */
2639 	reply_sz = sizeof(*facts);
2640 	memset(facts, 0, reply_sz);
2641 
2642 	/* Request area (get_facts on the stack right now!) */
2643 	req_sz = sizeof(get_facts);
2644 	memset(&get_facts, 0, req_sz);
2645 
2646 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2647 	/* Assert: All other get_facts fields are zero! */
2648 
2649 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2650 	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2651 	    ioc->name, req_sz, reply_sz));
2652 
2653 	/* No non-zero fields in the get_facts request are greater than
2654 	 * 1 byte in size, so we can just fire it off as is.
2655 	 */
2656 	r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2657 			reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2658 	if (r != 0)
2659 		return r;
2660 
2661 	/*
2662 	 * Now byte swap (GRRR) the necessary fields before any further
2663 	 * inspection of reply contents.
2664 	 *
2665 	 * But need to do some sanity checks on MsgLength (byte) field
2666 	 * to make sure we don't zero IOC's req_sz!
2667 	 */
2668 	/* Did we get a valid reply? */
2669 	if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2670 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2671 			/*
2672 			 * If not been here, done that, save off first WhoInit value
2673 			 */
2674 			if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2675 				ioc->FirstWhoInit = facts->WhoInit;
2676 		}
2677 
2678 		facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2679 		facts->MsgContext = le32_to_cpu(facts->MsgContext);
2680 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2681 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2682 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2683 		status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2684 		/* CHECKME! IOCStatus, IOCLogInfo */
2685 
2686 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2687 		facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2688 
2689 		/*
2690 		 * FC f/w version changed between 1.1 and 1.2
2691 		 *	Old: u16{Major(4),Minor(4),SubMinor(8)}
2692 		 *	New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2693 		 */
2694 		if (facts->MsgVersion < 0x0102) {
2695 			/*
2696 			 *	Handle old FC f/w style, convert to new...
2697 			 */
2698 			u16	 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2699 			facts->FWVersion.Word =
2700 					((oldv<<12) & 0xFF000000) |
2701 					((oldv<<8)  & 0x000FFF00);
2702 		} else
2703 			facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2704 
2705 		facts->ProductID = le16_to_cpu(facts->ProductID);
2706 		if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2707 		    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2708 			ioc->ir_firmware = 1;
2709 		facts->CurrentHostMfaHighAddr =
2710 				le32_to_cpu(facts->CurrentHostMfaHighAddr);
2711 		facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2712 		facts->CurrentSenseBufferHighAddr =
2713 				le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2714 		facts->CurReplyFrameSize =
2715 				le16_to_cpu(facts->CurReplyFrameSize);
2716 		facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2717 
2718 		/*
2719 		 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2720 		 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2721 		 * to 14 in MPI-1.01.0x.
2722 		 */
2723 		if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2724 		    facts->MsgVersion > 0x0100) {
2725 			facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2726 		}
2727 
2728 		sz = facts->FWImageSize;
2729 		if ( sz & 0x01 )
2730 			sz += 1;
2731 		if ( sz & 0x02 )
2732 			sz += 2;
2733 		facts->FWImageSize = sz;
2734 
2735 		if (!facts->RequestFrameSize) {
2736 			/*  Something is wrong!  */
2737 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2738 					ioc->name);
2739 			return -55;
2740 		}
2741 
2742 		r = sz = facts->BlockSize;
2743 		vv = ((63 / (sz * 4)) + 1) & 0x03;
2744 		ioc->NB_for_64_byte_frame = vv;
2745 		while ( sz )
2746 		{
2747 			shiftFactor++;
2748 			sz = sz >> 1;
2749 		}
2750 		ioc->NBShiftFactor  = shiftFactor;
2751 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2752 		    "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2753 		    ioc->name, vv, shiftFactor, r));
2754 
2755 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2756 			/*
2757 			 * Set values for this IOC's request & reply frame sizes,
2758 			 * and request & reply queue depths...
2759 			 */
2760 			ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2761 			ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2762 			ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2763 			ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2764 
2765 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2766 				ioc->name, ioc->reply_sz, ioc->reply_depth));
2767 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
2768 				ioc->name, ioc->req_sz, ioc->req_depth));
2769 
2770 			/* Get port facts! */
2771 			if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2772 				return r;
2773 		}
2774 	} else {
2775 		printk(MYIOC_s_ERR_FMT
2776 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2777 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2778 		     RequestFrameSize)/sizeof(u32)));
2779 		return -66;
2780 	}
2781 
2782 	return 0;
2783 }
2784 
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 /**
2787  *	GetPortFacts - Send PortFacts request to MPT adapter.
2788  *	@ioc: Pointer to MPT_ADAPTER structure
2789  *	@portnum: Port number
2790  *	@sleepFlag: Specifies whether the process can sleep
2791  *
2792  *	Returns 0 for success, non-zero for failure.
2793  */
2794 static int
2795 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2796 {
2797 	PortFacts_t		 get_pfacts;
2798 	PortFactsReply_t	*pfacts;
2799 	int			 ii;
2800 	int			 req_sz;
2801 	int			 reply_sz;
2802 	int			 max_id;
2803 
2804 	/* IOC *must* NOT be in RESET state! */
2805 	if (ioc->last_state == MPI_IOC_STATE_RESET) {
2806 		printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2807 		    ioc->name, ioc->last_state );
2808 		return -4;
2809 	}
2810 
2811 	pfacts = &ioc->pfacts[portnum];
2812 
2813 	/* Destination (reply area)...  */
2814 	reply_sz = sizeof(*pfacts);
2815 	memset(pfacts, 0, reply_sz);
2816 
2817 	/* Request area (get_pfacts on the stack right now!) */
2818 	req_sz = sizeof(get_pfacts);
2819 	memset(&get_pfacts, 0, req_sz);
2820 
2821 	get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2822 	get_pfacts.PortNumber = portnum;
2823 	/* Assert: All other get_pfacts fields are zero! */
2824 
2825 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2826 			ioc->name, portnum));
2827 
2828 	/* No non-zero fields in the get_pfacts request are greater than
2829 	 * 1 byte in size, so we can just fire it off as is.
2830 	 */
2831 	ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2832 				reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2833 	if (ii != 0)
2834 		return ii;
2835 
2836 	/* Did we get a valid reply? */
2837 
2838 	/* Now byte swap the necessary fields in the response. */
2839 	pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2840 	pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2841 	pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2842 	pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2843 	pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2844 	pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2845 	pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2846 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2847 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2848 
2849 	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2850 	    pfacts->MaxDevices;
2851 	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2852 	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2853 
2854 	/*
2855 	 * Place all the devices on channels
2856 	 *
2857 	 * (for debuging)
2858 	 */
2859 	if (mpt_channel_mapping) {
2860 		ioc->devices_per_bus = 1;
2861 		ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2862 	}
2863 
2864 	return 0;
2865 }
2866 
2867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2868 /**
2869  *	SendIocInit - Send IOCInit request to MPT adapter.
2870  *	@ioc: Pointer to MPT_ADAPTER structure
2871  *	@sleepFlag: Specifies whether the process can sleep
2872  *
2873  *	Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2874  *
2875  *	Returns 0 for success, non-zero for failure.
2876  */
2877 static int
2878 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2879 {
2880 	IOCInit_t		 ioc_init;
2881 	MPIDefaultReply_t	 init_reply;
2882 	u32			 state;
2883 	int			 r;
2884 	int			 count;
2885 	int			 cntdn;
2886 
2887 	memset(&ioc_init, 0, sizeof(ioc_init));
2888 	memset(&init_reply, 0, sizeof(init_reply));
2889 
2890 	ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2891 	ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2892 
2893 	/* If we are in a recovery mode and we uploaded the FW image,
2894 	 * then this pointer is not NULL. Skip the upload a second time.
2895 	 * Set this flag if cached_fw set for either IOC.
2896 	 */
2897 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2898 		ioc->upload_fw = 1;
2899 	else
2900 		ioc->upload_fw = 0;
2901 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2902 		   ioc->name, ioc->upload_fw, ioc->facts.Flags));
2903 
2904 	ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2905 	ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2906 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2907 		   ioc->name, ioc->facts.MsgVersion));
2908 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2909 		// set MsgVersion and HeaderVersion host driver was built with
2910 		ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2911 	        ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2912 
2913 		if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2914 			ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2915 		} else if(mpt_host_page_alloc(ioc, &ioc_init))
2916 			return -99;
2917 	}
2918 	ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);	/* in BYTES */
2919 
2920 	if (sizeof(dma_addr_t) == sizeof(u64)) {
2921 		/* Save the upper 32-bits of the request
2922 		 * (reply) and sense buffers.
2923 		 */
2924 		ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2925 		ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2926 	} else {
2927 		/* Force 32-bit addressing */
2928 		ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2929 		ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2930 	}
2931 
2932 	ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2933 	ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2934 	ioc->facts.MaxDevices = ioc_init.MaxDevices;
2935 	ioc->facts.MaxBuses = ioc_init.MaxBuses;
2936 
2937 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2938 			ioc->name, &ioc_init));
2939 
2940 	r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2941 				sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2942 	if (r != 0) {
2943 		printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2944 		return r;
2945 	}
2946 
2947 	/* No need to byte swap the multibyte fields in the reply
2948 	 * since we don't even look at its contents.
2949 	 */
2950 
2951 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2952 			ioc->name, &ioc_init));
2953 
2954 	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2955 		printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2956 		return r;
2957 	}
2958 
2959 	/* YIKES!  SUPER IMPORTANT!!!
2960 	 *  Poll IocState until _OPERATIONAL while IOC is doing
2961 	 *  LoopInit and TargetDiscovery!
2962 	 */
2963 	count = 0;
2964 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;	/* 60 seconds */
2965 	state = mpt_GetIocState(ioc, 1);
2966 	while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2967 		if (sleepFlag == CAN_SLEEP) {
2968 			msleep(1);
2969 		} else {
2970 			mdelay(1);
2971 		}
2972 
2973 		if (!cntdn) {
2974 			printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2975 					ioc->name, (int)((count+5)/HZ));
2976 			return -9;
2977 		}
2978 
2979 		state = mpt_GetIocState(ioc, 1);
2980 		count++;
2981 	}
2982 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
2983 			ioc->name, count));
2984 
2985 	ioc->aen_event_read_flag=0;
2986 	return r;
2987 }
2988 
2989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2990 /**
2991  *	SendPortEnable - Send PortEnable request to MPT adapter port.
2992  *	@ioc: Pointer to MPT_ADAPTER structure
2993  *	@portnum: Port number to enable
2994  *	@sleepFlag: Specifies whether the process can sleep
2995  *
2996  *	Send PortEnable to bring IOC to OPERATIONAL state.
2997  *
2998  *	Returns 0 for success, non-zero for failure.
2999  */
3000 static int
3001 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3002 {
3003 	PortEnable_t		 port_enable;
3004 	MPIDefaultReply_t	 reply_buf;
3005 	int	 rc;
3006 	int	 req_sz;
3007 	int	 reply_sz;
3008 
3009 	/*  Destination...  */
3010 	reply_sz = sizeof(MPIDefaultReply_t);
3011 	memset(&reply_buf, 0, reply_sz);
3012 
3013 	req_sz = sizeof(PortEnable_t);
3014 	memset(&port_enable, 0, req_sz);
3015 
3016 	port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3017 	port_enable.PortNumber = portnum;
3018 /*	port_enable.ChainOffset = 0;		*/
3019 /*	port_enable.MsgFlags = 0;		*/
3020 /*	port_enable.MsgContext = 0;		*/
3021 
3022 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3023 			ioc->name, portnum, &port_enable));
3024 
3025 	/* RAID FW may take a long time to enable
3026 	 */
3027 	if (ioc->ir_firmware || ioc->bus_type == SAS) {
3028 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3029 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3030 		300 /*seconds*/, sleepFlag);
3031 	} else {
3032 		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3033 		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3034 		30 /*seconds*/, sleepFlag);
3035 	}
3036 	return rc;
3037 }
3038 
3039 /**
3040  *	mpt_alloc_fw_memory - allocate firmware memory
3041  *	@ioc: Pointer to MPT_ADAPTER structure
3042  *      @size: total FW bytes
3043  *
3044  *	If memory has already been allocated, the same (cached) value
3045  *	is returned.
3046  *
3047  *	Return 0 if successfull, or non-zero for failure
3048  **/
3049 int
3050 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3051 {
3052 	int rc;
3053 
3054 	if (ioc->cached_fw) {
3055 		rc = 0;  /* use already allocated memory */
3056 		goto out;
3057 	}
3058 	else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3059 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
3060 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3061 		rc = 0;
3062 		goto out;
3063 	}
3064 	ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3065 	if (!ioc->cached_fw) {
3066 		printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3067 		    ioc->name);
3068 		rc = -1;
3069 	} else {
3070 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3071 		    ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3072 		ioc->alloc_total += size;
3073 		rc = 0;
3074 	}
3075  out:
3076 	return rc;
3077 }
3078 
3079 /**
3080  *	mpt_free_fw_memory - free firmware memory
3081  *	@ioc: Pointer to MPT_ADAPTER structure
3082  *
3083  *	If alt_img is NULL, delete from ioc structure.
3084  *	Else, delete a secondary image in same format.
3085  **/
3086 void
3087 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3088 {
3089 	int sz;
3090 
3091 	if (!ioc->cached_fw)
3092 		return;
3093 
3094 	sz = ioc->facts.FWImageSize;
3095 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3096 		 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3097 	pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3098 	ioc->alloc_total -= sz;
3099 	ioc->cached_fw = NULL;
3100 }
3101 
3102 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3103 /**
3104  *	mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3105  *	@ioc: Pointer to MPT_ADAPTER structure
3106  *	@sleepFlag: Specifies whether the process can sleep
3107  *
3108  *	Returns 0 for success, >0 for handshake failure
3109  *		<0 for fw upload failure.
3110  *
3111  *	Remark: If bound IOC and a successful FWUpload was performed
3112  *	on the bound IOC, the second image is discarded
3113  *	and memory is free'd. Both channels must upload to prevent
3114  *	IOC from running in degraded mode.
3115  */
3116 static int
3117 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3118 {
3119 	u8			 reply[sizeof(FWUploadReply_t)];
3120 	FWUpload_t		*prequest;
3121 	FWUploadReply_t		*preply;
3122 	FWUploadTCSGE_t		*ptcsge;
3123 	int			 sgeoffset;
3124 	u32			 flagsLength;
3125 	int			 ii, sz, reply_sz;
3126 	int			 cmdStatus;
3127 
3128 	/* If the image size is 0, we are done.
3129 	 */
3130 	if ((sz = ioc->facts.FWImageSize) == 0)
3131 		return 0;
3132 
3133 	if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3134 		return -ENOMEM;
3135 
3136 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3137 	    ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3138 
3139 	prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3140 	    kzalloc(ioc->req_sz, GFP_KERNEL);
3141 	if (!prequest) {
3142 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3143 		    "while allocating memory \n", ioc->name));
3144 		mpt_free_fw_memory(ioc);
3145 		return -ENOMEM;
3146 	}
3147 
3148 	preply = (FWUploadReply_t *)&reply;
3149 
3150 	reply_sz = sizeof(reply);
3151 	memset(preply, 0, reply_sz);
3152 
3153 	prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3154 	prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3155 
3156 	ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3157 	ptcsge->DetailsLength = 12;
3158 	ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3159 	ptcsge->ImageSize = cpu_to_le32(sz);
3160 	ptcsge++;
3161 
3162 	sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3163 
3164 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3165 	mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3166 
3167 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3168 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3169 	    ioc->name, prequest, sgeoffset));
3170 	DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3171 
3172 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3173 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3174 
3175 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3176 
3177 	cmdStatus = -EFAULT;
3178 	if (ii == 0) {
3179 		/* Handshake transfer was complete and successful.
3180 		 * Check the Reply Frame.
3181 		 */
3182 		int status, transfer_sz;
3183 		status = le16_to_cpu(preply->IOCStatus);
3184 		if (status == MPI_IOCSTATUS_SUCCESS) {
3185 			transfer_sz = le32_to_cpu(preply->ActualImageSize);
3186 			if (transfer_sz == sz)
3187 				cmdStatus = 0;
3188 		}
3189 	}
3190 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3191 			ioc->name, cmdStatus));
3192 
3193 
3194 	if (cmdStatus) {
3195 
3196 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3197 			ioc->name));
3198 		mpt_free_fw_memory(ioc);
3199 	}
3200 	kfree(prequest);
3201 
3202 	return cmdStatus;
3203 }
3204 
3205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3206 /**
3207  *	mpt_downloadboot - DownloadBoot code
3208  *	@ioc: Pointer to MPT_ADAPTER structure
3209  *	@pFwHeader: Pointer to firmware header info
3210  *	@sleepFlag: Specifies whether the process can sleep
3211  *
3212  *	FwDownloadBoot requires Programmed IO access.
3213  *
3214  *	Returns 0 for success
3215  *		-1 FW Image size is 0
3216  *		-2 No valid cached_fw Pointer
3217  *		<0 for fw upload failure.
3218  */
3219 static int
3220 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3221 {
3222 	MpiExtImageHeader_t	*pExtImage;
3223 	u32			 fwSize;
3224 	u32			 diag0val;
3225 	int			 count;
3226 	u32			*ptrFw;
3227 	u32			 diagRwData;
3228 	u32			 nextImage;
3229 	u32			 load_addr;
3230 	u32 			 ioc_state=0;
3231 
3232 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3233 				ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3234 
3235 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3236 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3237 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3238 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3239 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3240 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3241 
3242 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3243 
3244 	/* wait 1 msec */
3245 	if (sleepFlag == CAN_SLEEP) {
3246 		msleep(1);
3247 	} else {
3248 		mdelay (1);
3249 	}
3250 
3251 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3252 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3253 
3254 	for (count = 0; count < 30; count ++) {
3255 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3256 		if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3257 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3258 				ioc->name, count));
3259 			break;
3260 		}
3261 		/* wait .1 sec */
3262 		if (sleepFlag == CAN_SLEEP) {
3263 			msleep (100);
3264 		} else {
3265 			mdelay (100);
3266 		}
3267 	}
3268 
3269 	if ( count == 30 ) {
3270 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3271 		"Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3272 		ioc->name, diag0val));
3273 		return -3;
3274 	}
3275 
3276 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3277 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3278 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3279 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3280 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3281 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3282 
3283 	/* Set the DiagRwEn and Disable ARM bits */
3284 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3285 
3286 	fwSize = (pFwHeader->ImageSize + 3)/4;
3287 	ptrFw = (u32 *) pFwHeader;
3288 
3289 	/* Write the LoadStartAddress to the DiagRw Address Register
3290 	 * using Programmed IO
3291 	 */
3292 	if (ioc->errata_flag_1064)
3293 		pci_enable_io_access(ioc->pcidev);
3294 
3295 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3296 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3297 		ioc->name, pFwHeader->LoadStartAddress));
3298 
3299 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3300 				ioc->name, fwSize*4, ptrFw));
3301 	while (fwSize--) {
3302 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3303 	}
3304 
3305 	nextImage = pFwHeader->NextImageHeaderOffset;
3306 	while (nextImage) {
3307 		pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3308 
3309 		load_addr = pExtImage->LoadStartAddress;
3310 
3311 		fwSize = (pExtImage->ImageSize + 3) >> 2;
3312 		ptrFw = (u32 *)pExtImage;
3313 
3314 		ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3315 						ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3316 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3317 
3318 		while (fwSize--) {
3319 			CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3320 		}
3321 		nextImage = pExtImage->NextImageHeaderOffset;
3322 	}
3323 
3324 	/* Write the IopResetVectorRegAddr */
3325 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, 	pFwHeader->IopResetRegAddr));
3326 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3327 
3328 	/* Write the IopResetVectorValue */
3329 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3330 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3331 
3332 	/* Clear the internal flash bad bit - autoincrementing register,
3333 	 * so must do two writes.
3334 	 */
3335 	if (ioc->bus_type == SPI) {
3336 		/*
3337 		 * 1030 and 1035 H/W errata, workaround to access
3338 		 * the ClearFlashBadSignatureBit
3339 		 */
3340 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3341 		diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3342 		diagRwData |= 0x40000000;
3343 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3344 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3345 
3346 	} else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3347 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3348 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3349 		    MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3350 
3351 		/* wait 1 msec */
3352 		if (sleepFlag == CAN_SLEEP) {
3353 			msleep (1);
3354 		} else {
3355 			mdelay (1);
3356 		}
3357 	}
3358 
3359 	if (ioc->errata_flag_1064)
3360 		pci_disable_io_access(ioc->pcidev);
3361 
3362 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3363 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3364 		"turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3365 		ioc->name, diag0val));
3366 	diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3367 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3368 		ioc->name, diag0val));
3369 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3370 
3371 	/* Write 0xFF to reset the sequencer */
3372 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3373 
3374 	if (ioc->bus_type == SAS) {
3375 		ioc_state = mpt_GetIocState(ioc, 0);
3376 		if ( (GetIocFacts(ioc, sleepFlag,
3377 				MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3378 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3379 					ioc->name, ioc_state));
3380 			return -EFAULT;
3381 		}
3382 	}
3383 
3384 	for (count=0; count<HZ*20; count++) {
3385 		if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3386 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3387 				"downloadboot successful! (count=%d) IocState=%x\n",
3388 				ioc->name, count, ioc_state));
3389 			if (ioc->bus_type == SAS) {
3390 				return 0;
3391 			}
3392 			if ((SendIocInit(ioc, sleepFlag)) != 0) {
3393 				ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3394 					"downloadboot: SendIocInit failed\n",
3395 					ioc->name));
3396 				return -EFAULT;
3397 			}
3398 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3399 					"downloadboot: SendIocInit successful\n",
3400 					ioc->name));
3401 			return 0;
3402 		}
3403 		if (sleepFlag == CAN_SLEEP) {
3404 			msleep (10);
3405 		} else {
3406 			mdelay (10);
3407 		}
3408 	}
3409 	ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3410 		"downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3411 	return -EFAULT;
3412 }
3413 
3414 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3415 /**
3416  *	KickStart - Perform hard reset of MPT adapter.
3417  *	@ioc: Pointer to MPT_ADAPTER structure
3418  *	@force: Force hard reset
3419  *	@sleepFlag: Specifies whether the process can sleep
3420  *
3421  *	This routine places MPT adapter in diagnostic mode via the
3422  *	WriteSequence register, and then performs a hard reset of adapter
3423  *	via the Diagnostic register.
3424  *
3425  *	Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3426  *			or NO_SLEEP (interrupt thread, use mdelay)
3427  *		  force - 1 if doorbell active, board fault state
3428  *				board operational, IOC_RECOVERY or
3429  *				IOC_BRINGUP and there is an alt_ioc.
3430  *			  0 else
3431  *
3432  *	Returns:
3433  *		 1 - hard reset, READY
3434  *		 0 - no reset due to History bit, READY
3435  *		-1 - no reset due to History bit but not READY
3436  *		     OR reset but failed to come READY
3437  *		-2 - no reset, could not enter DIAG mode
3438  *		-3 - reset but bad FW bit
3439  */
3440 static int
3441 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3442 {
3443 	int hard_reset_done = 0;
3444 	u32 ioc_state=0;
3445 	int cnt,cntdn;
3446 
3447 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3448 	if (ioc->bus_type == SPI) {
3449 		/* Always issue a Msg Unit Reset first. This will clear some
3450 		 * SCSI bus hang conditions.
3451 		 */
3452 		SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3453 
3454 		if (sleepFlag == CAN_SLEEP) {
3455 			msleep (1000);
3456 		} else {
3457 			mdelay (1000);
3458 		}
3459 	}
3460 
3461 	hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3462 	if (hard_reset_done < 0)
3463 		return hard_reset_done;
3464 
3465 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3466 		ioc->name));
3467 
3468 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;	/* 2 seconds */
3469 	for (cnt=0; cnt<cntdn; cnt++) {
3470 		ioc_state = mpt_GetIocState(ioc, 1);
3471 		if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3472 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3473  					ioc->name, cnt));
3474 			return hard_reset_done;
3475 		}
3476 		if (sleepFlag == CAN_SLEEP) {
3477 			msleep (10);
3478 		} else {
3479 			mdelay (10);
3480 		}
3481 	}
3482 
3483 	dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3484 		ioc->name, mpt_GetIocState(ioc, 0)));
3485 	return -1;
3486 }
3487 
3488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3489 /**
3490  *	mpt_diag_reset - Perform hard reset of the adapter.
3491  *	@ioc: Pointer to MPT_ADAPTER structure
3492  *	@ignore: Set if to honor and clear to ignore
3493  *		the reset history bit
3494  *	@sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3495  *		else set to NO_SLEEP (use mdelay instead)
3496  *
3497  *	This routine places the adapter in diagnostic mode via the
3498  *	WriteSequence register and then performs a hard reset of adapter
3499  *	via the Diagnostic register. Adapter should be in ready state
3500  *	upon successful completion.
3501  *
3502  *	Returns:  1  hard reset successful
3503  *		  0  no reset performed because reset history bit set
3504  *		 -2  enabling diagnostic mode failed
3505  *		 -3  diagnostic reset failed
3506  */
3507 static int
3508 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3509 {
3510 	u32 diag0val;
3511 	u32 doorbell;
3512 	int hard_reset_done = 0;
3513 	int count = 0;
3514 	u32 diag1val = 0;
3515 	MpiFwHeader_t *cached_fw;	/* Pointer to FW */
3516 
3517 	/* Clear any existing interrupts */
3518 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3519 
3520 	if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3521 		drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3522 			"address=%p\n",  ioc->name, __FUNCTION__,
3523 			&ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3524 		CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3525 		if (sleepFlag == CAN_SLEEP)
3526 			msleep(1);
3527 		else
3528 			mdelay(1);
3529 
3530 		for (count = 0; count < 60; count ++) {
3531 			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3532 			doorbell &= MPI_IOC_STATE_MASK;
3533 
3534 			drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3535 				"looking for READY STATE: doorbell=%x"
3536 			        " count=%d\n",
3537 				ioc->name, doorbell, count));
3538 			if (doorbell == MPI_IOC_STATE_READY) {
3539 				return 1;
3540 			}
3541 
3542 			/* wait 1 sec */
3543 			if (sleepFlag == CAN_SLEEP)
3544 				msleep(1000);
3545 			else
3546 				mdelay(1000);
3547 		}
3548 		return -1;
3549 	}
3550 
3551 	/* Use "Diagnostic reset" method! (only thing available!) */
3552 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3553 
3554 	if (ioc->debug_level & MPT_DEBUG) {
3555 		if (ioc->alt_ioc)
3556 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3557 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3558 			ioc->name, diag0val, diag1val));
3559 	}
3560 
3561 	/* Do the reset if we are told to ignore the reset history
3562 	 * or if the reset history is 0
3563 	 */
3564 	if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3565 		while ((diag0val & MPI_DIAG_DRWE) == 0) {
3566 			/* Write magic sequence to WriteSequence register
3567 			 * Loop until in diagnostic mode
3568 			 */
3569 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3570 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3571 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3572 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3573 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3574 			CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3575 
3576 			/* wait 100 msec */
3577 			if (sleepFlag == CAN_SLEEP) {
3578 				msleep (100);
3579 			} else {
3580 				mdelay (100);
3581 			}
3582 
3583 			count++;
3584 			if (count > 20) {
3585 				printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3586 						ioc->name, diag0val);
3587 				return -2;
3588 
3589 			}
3590 
3591 			diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3592 
3593 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3594 					ioc->name, diag0val));
3595 		}
3596 
3597 		if (ioc->debug_level & MPT_DEBUG) {
3598 			if (ioc->alt_ioc)
3599 				diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3600 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3601 				ioc->name, diag0val, diag1val));
3602 		}
3603 		/*
3604 		 * Disable the ARM (Bug fix)
3605 		 *
3606 		 */
3607 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3608 		mdelay(1);
3609 
3610 		/*
3611 		 * Now hit the reset bit in the Diagnostic register
3612 		 * (THE BIG HAMMER!) (Clears DRWE bit).
3613 		 */
3614 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3615 		hard_reset_done = 1;
3616 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3617 				ioc->name));
3618 
3619 		/*
3620 		 * Call each currently registered protocol IOC reset handler
3621 		 * with pre-reset indication.
3622 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3623 		 * MptResetHandlers[] registered yet.
3624 		 */
3625 		{
3626 			u8	 cb_idx;
3627 			int	 r = 0;
3628 
3629 			for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3630 				if (MptResetHandlers[cb_idx]) {
3631 					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3632 						"Calling IOC pre_reset handler #%d\n",
3633 						ioc->name, cb_idx));
3634 					r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3635 					if (ioc->alt_ioc) {
3636 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3637 							"Calling alt-%s pre_reset handler #%d\n",
3638 							ioc->name, ioc->alt_ioc->name, cb_idx));
3639 						r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3640 					}
3641 				}
3642 			}
3643 			/* FIXME?  Examine results here? */
3644 		}
3645 
3646 		if (ioc->cached_fw)
3647 			cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3648 		else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3649 			cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3650 		else
3651 			cached_fw = NULL;
3652 		if (cached_fw) {
3653 			/* If the DownloadBoot operation fails, the
3654 			 * IOC will be left unusable. This is a fatal error
3655 			 * case.  _diag_reset will return < 0
3656 			 */
3657 			for (count = 0; count < 30; count ++) {
3658 				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3659 				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3660 					break;
3661 				}
3662 
3663 				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3664 					ioc->name, diag0val, count));
3665 				/* wait 1 sec */
3666 				if (sleepFlag == CAN_SLEEP) {
3667 					msleep (1000);
3668 				} else {
3669 					mdelay (1000);
3670 				}
3671 			}
3672 			if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3673 				printk(MYIOC_s_WARN_FMT
3674 					"firmware downloadboot failure (%d)!\n", ioc->name, count);
3675 			}
3676 
3677 		} else {
3678 			/* Wait for FW to reload and for board
3679 			 * to go to the READY state.
3680 			 * Maximum wait is 60 seconds.
3681 			 * If fail, no error will check again
3682 			 * with calling program.
3683 			 */
3684 			for (count = 0; count < 60; count ++) {
3685 				doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3686 				doorbell &= MPI_IOC_STATE_MASK;
3687 
3688 				if (doorbell == MPI_IOC_STATE_READY) {
3689 					break;
3690 				}
3691 
3692 				/* wait 1 sec */
3693 				if (sleepFlag == CAN_SLEEP) {
3694 					msleep (1000);
3695 				} else {
3696 					mdelay (1000);
3697 				}
3698 			}
3699 		}
3700 	}
3701 
3702 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3703 	if (ioc->debug_level & MPT_DEBUG) {
3704 		if (ioc->alt_ioc)
3705 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3706 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3707 			ioc->name, diag0val, diag1val));
3708 	}
3709 
3710 	/* Clear RESET_HISTORY bit!  Place board in the
3711 	 * diagnostic mode to update the diag register.
3712 	 */
3713 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3714 	count = 0;
3715 	while ((diag0val & MPI_DIAG_DRWE) == 0) {
3716 		/* Write magic sequence to WriteSequence register
3717 		 * Loop until in diagnostic mode
3718 		 */
3719 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3720 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3721 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3722 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3723 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3724 		CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3725 
3726 		/* wait 100 msec */
3727 		if (sleepFlag == CAN_SLEEP) {
3728 			msleep (100);
3729 		} else {
3730 			mdelay (100);
3731 		}
3732 
3733 		count++;
3734 		if (count > 20) {
3735 			printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3736 					ioc->name, diag0val);
3737 			break;
3738 		}
3739 		diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3740 	}
3741 	diag0val &= ~MPI_DIAG_RESET_HISTORY;
3742 	CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3743 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3744 	if (diag0val & MPI_DIAG_RESET_HISTORY) {
3745 		printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3746 				ioc->name);
3747 	}
3748 
3749 	/* Disable Diagnostic Mode
3750 	 */
3751 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3752 
3753 	/* Check FW reload status flags.
3754 	 */
3755 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3756 	if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3757 		printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3758 				ioc->name, diag0val);
3759 		return -3;
3760 	}
3761 
3762 	if (ioc->debug_level & MPT_DEBUG) {
3763 		if (ioc->alt_ioc)
3764 			diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3765 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3766 			ioc->name, diag0val, diag1val));
3767 	}
3768 
3769 	/*
3770 	 * Reset flag that says we've enabled event notification
3771 	 */
3772 	ioc->facts.EventState = 0;
3773 
3774 	if (ioc->alt_ioc)
3775 		ioc->alt_ioc->facts.EventState = 0;
3776 
3777 	return hard_reset_done;
3778 }
3779 
3780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3781 /**
3782  *	SendIocReset - Send IOCReset request to MPT adapter.
3783  *	@ioc: Pointer to MPT_ADAPTER structure
3784  *	@reset_type: reset type, expected values are
3785  *	%MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3786  *	@sleepFlag: Specifies whether the process can sleep
3787  *
3788  *	Send IOCReset request to the MPT adapter.
3789  *
3790  *	Returns 0 for success, non-zero for failure.
3791  */
3792 static int
3793 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3794 {
3795 	int r;
3796 	u32 state;
3797 	int cntdn, count;
3798 
3799 	drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3800 			ioc->name, reset_type));
3801 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3802 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3803 		return r;
3804 
3805 	/* FW ACK'd request, wait for READY state
3806 	 */
3807 	count = 0;
3808 	cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;	/* 15 seconds */
3809 
3810 	while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3811 		cntdn--;
3812 		count++;
3813 		if (!cntdn) {
3814 			if (sleepFlag != CAN_SLEEP)
3815 				count *= 10;
3816 
3817 			printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3818 			    ioc->name, (int)((count+5)/HZ));
3819 			return -ETIME;
3820 		}
3821 
3822 		if (sleepFlag == CAN_SLEEP) {
3823 			msleep(1);
3824 		} else {
3825 			mdelay (1);	/* 1 msec delay */
3826 		}
3827 	}
3828 
3829 	/* TODO!
3830 	 *  Cleanup all event stuff for this IOC; re-issue EventNotification
3831 	 *  request if needed.
3832 	 */
3833 	if (ioc->facts.Function)
3834 		ioc->facts.EventState = 0;
3835 
3836 	return 0;
3837 }
3838 
3839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3840 /**
3841  *	initChainBuffers - Allocate memory for and initialize chain buffers
3842  *	@ioc: Pointer to MPT_ADAPTER structure
3843  *
3844  *	Allocates memory for and initializes chain buffers,
3845  *	chain buffer control arrays and spinlock.
3846  */
3847 static int
3848 initChainBuffers(MPT_ADAPTER *ioc)
3849 {
3850 	u8		*mem;
3851 	int		sz, ii, num_chain;
3852 	int 		scale, num_sge, numSGE;
3853 
3854 	/* ReqToChain size must equal the req_depth
3855 	 * index = req_idx
3856 	 */
3857 	if (ioc->ReqToChain == NULL) {
3858 		sz = ioc->req_depth * sizeof(int);
3859 		mem = kmalloc(sz, GFP_ATOMIC);
3860 		if (mem == NULL)
3861 			return -1;
3862 
3863 		ioc->ReqToChain = (int *) mem;
3864 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
3865 			 	ioc->name, mem, sz));
3866 		mem = kmalloc(sz, GFP_ATOMIC);
3867 		if (mem == NULL)
3868 			return -1;
3869 
3870 		ioc->RequestNB = (int *) mem;
3871 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
3872 			 	ioc->name, mem, sz));
3873 	}
3874 	for (ii = 0; ii < ioc->req_depth; ii++) {
3875 		ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3876 	}
3877 
3878 	/* ChainToChain size must equal the total number
3879 	 * of chain buffers to be allocated.
3880 	 * index = chain_idx
3881 	 *
3882 	 * Calculate the number of chain buffers needed(plus 1) per I/O
3883 	 * then multiply the maximum number of simultaneous cmds
3884 	 *
3885 	 * num_sge = num sge in request frame + last chain buffer
3886 	 * scale = num sge per chain buffer if no chain element
3887 	 */
3888 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3889 	if (sizeof(dma_addr_t) == sizeof(u64))
3890 		num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3891 	else
3892 		num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3893 
3894 	if (sizeof(dma_addr_t) == sizeof(u64)) {
3895 		numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3896 			(ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3897 	} else {
3898 		numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3899 			(ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3900 	}
3901 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3902 		ioc->name, num_sge, numSGE));
3903 
3904 	if ( numSGE > MPT_SCSI_SG_DEPTH	)
3905 		numSGE = MPT_SCSI_SG_DEPTH;
3906 
3907 	num_chain = 1;
3908 	while (numSGE - num_sge > 0) {
3909 		num_chain++;
3910 		num_sge += (scale - 1);
3911 	}
3912 	num_chain++;
3913 
3914 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3915 		ioc->name, numSGE, num_sge, num_chain));
3916 
3917 	if (ioc->bus_type == SPI)
3918 		num_chain *= MPT_SCSI_CAN_QUEUE;
3919 	else
3920 		num_chain *= MPT_FC_CAN_QUEUE;
3921 
3922 	ioc->num_chain = num_chain;
3923 
3924 	sz = num_chain * sizeof(int);
3925 	if (ioc->ChainToChain == NULL) {
3926 		mem = kmalloc(sz, GFP_ATOMIC);
3927 		if (mem == NULL)
3928 			return -1;
3929 
3930 		ioc->ChainToChain = (int *) mem;
3931 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3932 			 	ioc->name, mem, sz));
3933 	} else {
3934 		mem = (u8 *) ioc->ChainToChain;
3935 	}
3936 	memset(mem, 0xFF, sz);
3937 	return num_chain;
3938 }
3939 
3940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3941 /**
3942  *	PrimeIocFifos - Initialize IOC request and reply FIFOs.
3943  *	@ioc: Pointer to MPT_ADAPTER structure
3944  *
3945  *	This routine allocates memory for the MPT reply and request frame
3946  *	pools (if necessary), and primes the IOC reply FIFO with
3947  *	reply frames.
3948  *
3949  *	Returns 0 for success, non-zero for failure.
3950  */
3951 static int
3952 PrimeIocFifos(MPT_ADAPTER *ioc)
3953 {
3954 	MPT_FRAME_HDR *mf;
3955 	unsigned long flags;
3956 	dma_addr_t alloc_dma;
3957 	u8 *mem;
3958 	int i, reply_sz, sz, total_size, num_chain;
3959 
3960 	/*  Prime reply FIFO...  */
3961 
3962 	if (ioc->reply_frames == NULL) {
3963 		if ( (num_chain = initChainBuffers(ioc)) < 0)
3964 			return -1;
3965 
3966 		total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3967 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3968 			 	ioc->name, ioc->reply_sz, ioc->reply_depth));
3969 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3970 			 	ioc->name, reply_sz, reply_sz));
3971 
3972 		sz = (ioc->req_sz * ioc->req_depth);
3973 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3974 			 	ioc->name, ioc->req_sz, ioc->req_depth));
3975 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3976 			 	ioc->name, sz, sz));
3977 		total_size += sz;
3978 
3979 		sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3980 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3981 			 	ioc->name, ioc->req_sz, num_chain));
3982 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3983 			 	ioc->name, sz, sz, num_chain));
3984 
3985 		total_size += sz;
3986 		mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3987 		if (mem == NULL) {
3988 			printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3989 				ioc->name);
3990 			goto out_fail;
3991 		}
3992 
3993 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3994 			 	ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3995 
3996 		memset(mem, 0, total_size);
3997 		ioc->alloc_total += total_size;
3998 		ioc->alloc = mem;
3999 		ioc->alloc_dma = alloc_dma;
4000 		ioc->alloc_sz = total_size;
4001 		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4002 		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4003 
4004 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4005 	 		ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4006 
4007 		alloc_dma += reply_sz;
4008 		mem += reply_sz;
4009 
4010 		/*  Request FIFO - WE manage this!  */
4011 
4012 		ioc->req_frames = (MPT_FRAME_HDR *) mem;
4013 		ioc->req_frames_dma = alloc_dma;
4014 
4015 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4016 			 	ioc->name, mem, (void *)(ulong)alloc_dma));
4017 
4018 		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4019 
4020 #if defined(CONFIG_MTRR) && 0
4021 		/*
4022 		 *  Enable Write Combining MTRR for IOC's memory region.
4023 		 *  (at least as much as we can; "size and base must be
4024 		 *  multiples of 4 kiB"
4025 		 */
4026 		ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4027 					 sz,
4028 					 MTRR_TYPE_WRCOMB, 1);
4029 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4030 				ioc->name, ioc->req_frames_dma, sz));
4031 #endif
4032 
4033 		for (i = 0; i < ioc->req_depth; i++) {
4034 			alloc_dma += ioc->req_sz;
4035 			mem += ioc->req_sz;
4036 		}
4037 
4038 		ioc->ChainBuffer = mem;
4039 		ioc->ChainBufferDMA = alloc_dma;
4040 
4041 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4042 			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4043 
4044 		/* Initialize the free chain Q.
4045 	 	*/
4046 
4047 		INIT_LIST_HEAD(&ioc->FreeChainQ);
4048 
4049 		/* Post the chain buffers to the FreeChainQ.
4050 	 	*/
4051 		mem = (u8 *)ioc->ChainBuffer;
4052 		for (i=0; i < num_chain; i++) {
4053 			mf = (MPT_FRAME_HDR *) mem;
4054 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4055 			mem += ioc->req_sz;
4056 		}
4057 
4058 		/* Initialize Request frames linked list
4059 		 */
4060 		alloc_dma = ioc->req_frames_dma;
4061 		mem = (u8 *) ioc->req_frames;
4062 
4063 		spin_lock_irqsave(&ioc->FreeQlock, flags);
4064 		INIT_LIST_HEAD(&ioc->FreeQ);
4065 		for (i = 0; i < ioc->req_depth; i++) {
4066 			mf = (MPT_FRAME_HDR *) mem;
4067 
4068 			/*  Queue REQUESTs *internally*!  */
4069 			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4070 
4071 			mem += ioc->req_sz;
4072 		}
4073 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4074 
4075 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4076 		ioc->sense_buf_pool =
4077 			pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4078 		if (ioc->sense_buf_pool == NULL) {
4079 			printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4080 				ioc->name);
4081 			goto out_fail;
4082 		}
4083 
4084 		ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4085 		ioc->alloc_total += sz;
4086 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4087  			ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4088 
4089 	}
4090 
4091 	/* Post Reply frames to FIFO
4092 	 */
4093 	alloc_dma = ioc->alloc_dma;
4094 	dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4095 	 	ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4096 
4097 	for (i = 0; i < ioc->reply_depth; i++) {
4098 		/*  Write each address to the IOC!  */
4099 		CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4100 		alloc_dma += ioc->reply_sz;
4101 	}
4102 
4103 	return 0;
4104 
4105 out_fail:
4106 	if (ioc->alloc != NULL) {
4107 		sz = ioc->alloc_sz;
4108 		pci_free_consistent(ioc->pcidev,
4109 				sz,
4110 				ioc->alloc, ioc->alloc_dma);
4111 		ioc->reply_frames = NULL;
4112 		ioc->req_frames = NULL;
4113 		ioc->alloc_total -= sz;
4114 	}
4115 	if (ioc->sense_buf_pool != NULL) {
4116 		sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4117 		pci_free_consistent(ioc->pcidev,
4118 				sz,
4119 				ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4120 		ioc->sense_buf_pool = NULL;
4121 	}
4122 	return -1;
4123 }
4124 
4125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4126 /**
4127  *	mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4128  *	from IOC via doorbell handshake method.
4129  *	@ioc: Pointer to MPT_ADAPTER structure
4130  *	@reqBytes: Size of the request in bytes
4131  *	@req: Pointer to MPT request frame
4132  *	@replyBytes: Expected size of the reply in bytes
4133  *	@u16reply: Pointer to area where reply should be written
4134  *	@maxwait: Max wait time for a reply (in seconds)
4135  *	@sleepFlag: Specifies whether the process can sleep
4136  *
4137  *	NOTES: It is the callers responsibility to byte-swap fields in the
4138  *	request which are greater than 1 byte in size.  It is also the
4139  *	callers responsibility to byte-swap response fields which are
4140  *	greater than 1 byte in size.
4141  *
4142  *	Returns 0 for success, non-zero for failure.
4143  */
4144 static int
4145 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4146 		int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4147 {
4148 	MPIDefaultReply_t *mptReply;
4149 	int failcnt = 0;
4150 	int t;
4151 
4152 	/*
4153 	 * Get ready to cache a handshake reply
4154 	 */
4155 	ioc->hs_reply_idx = 0;
4156 	mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4157 	mptReply->MsgLength = 0;
4158 
4159 	/*
4160 	 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4161 	 * then tell IOC that we want to handshake a request of N words.
4162 	 * (WRITE u32val to Doorbell reg).
4163 	 */
4164 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4165 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
4166 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4167 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4168 
4169 	/*
4170 	 * Wait for IOC's doorbell handshake int
4171 	 */
4172 	if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4173 		failcnt++;
4174 
4175 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4176 			ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4177 
4178 	/* Read doorbell and check for active bit */
4179 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4180 			return -1;
4181 
4182 	/*
4183 	 * Clear doorbell int (WRITE 0 to IntStatus reg),
4184 	 * then wait for IOC to ACKnowledge that it's ready for
4185 	 * our handshake request.
4186 	 */
4187 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4188 	if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4189 		failcnt++;
4190 
4191 	if (!failcnt) {
4192 		int	 ii;
4193 		u8	*req_as_bytes = (u8 *) req;
4194 
4195 		/*
4196 		 * Stuff request words via doorbell handshake,
4197 		 * with ACK from IOC for each.
4198 		 */
4199 		for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4200 			u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4201 				    (req_as_bytes[(ii*4) + 1] <<  8) |
4202 				    (req_as_bytes[(ii*4) + 2] << 16) |
4203 				    (req_as_bytes[(ii*4) + 3] << 24));
4204 
4205 			CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4206 			if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4207 				failcnt++;
4208 		}
4209 
4210 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4211 		DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4212 
4213 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4214 				ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4215 
4216 		/*
4217 		 * Wait for completion of doorbell handshake reply from the IOC
4218 		 */
4219 		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4220 			failcnt++;
4221 
4222 		dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4223 				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4224 
4225 		/*
4226 		 * Copy out the cached reply...
4227 		 */
4228 		for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4229 			u16reply[ii] = ioc->hs_reply[ii];
4230 	} else {
4231 		return -99;
4232 	}
4233 
4234 	return -failcnt;
4235 }
4236 
4237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4238 /**
4239  *	WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4240  *	@ioc: Pointer to MPT_ADAPTER structure
4241  *	@howlong: How long to wait (in seconds)
4242  *	@sleepFlag: Specifies whether the process can sleep
4243  *
4244  *	This routine waits (up to ~2 seconds max) for IOC doorbell
4245  *	handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4246  *	bit in its IntStatus register being clear.
4247  *
4248  *	Returns a negative value on failure, else wait loop count.
4249  */
4250 static int
4251 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4252 {
4253 	int cntdn;
4254 	int count = 0;
4255 	u32 intstat=0;
4256 
4257 	cntdn = 1000 * howlong;
4258 
4259 	if (sleepFlag == CAN_SLEEP) {
4260 		while (--cntdn) {
4261 			msleep (1);
4262 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4263 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4264 				break;
4265 			count++;
4266 		}
4267 	} else {
4268 		while (--cntdn) {
4269 			udelay (1000);
4270 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4271 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4272 				break;
4273 			count++;
4274 		}
4275 	}
4276 
4277 	if (cntdn) {
4278 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4279 				ioc->name, count));
4280 		return count;
4281 	}
4282 
4283 	printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4284 			ioc->name, count, intstat);
4285 	return -1;
4286 }
4287 
4288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4289 /**
4290  *	WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4291  *	@ioc: Pointer to MPT_ADAPTER structure
4292  *	@howlong: How long to wait (in seconds)
4293  *	@sleepFlag: Specifies whether the process can sleep
4294  *
4295  *	This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4296  *	(MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4297  *
4298  *	Returns a negative value on failure, else wait loop count.
4299  */
4300 static int
4301 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4302 {
4303 	int cntdn;
4304 	int count = 0;
4305 	u32 intstat=0;
4306 
4307 	cntdn = 1000 * howlong;
4308 	if (sleepFlag == CAN_SLEEP) {
4309 		while (--cntdn) {
4310 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4311 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4312 				break;
4313 			msleep(1);
4314 			count++;
4315 		}
4316 	} else {
4317 		while (--cntdn) {
4318 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4319 			if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4320 				break;
4321 			udelay (1000);
4322 			count++;
4323 		}
4324 	}
4325 
4326 	if (cntdn) {
4327 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4328 				ioc->name, count, howlong));
4329 		return count;
4330 	}
4331 
4332 	printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4333 			ioc->name, count, intstat);
4334 	return -1;
4335 }
4336 
4337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4338 /**
4339  *	WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4340  *	@ioc: Pointer to MPT_ADAPTER structure
4341  *	@howlong: How long to wait (in seconds)
4342  *	@sleepFlag: Specifies whether the process can sleep
4343  *
4344  *	This routine polls the IOC for a handshake reply, 16 bits at a time.
4345  *	Reply is cached to IOC private area large enough to hold a maximum
4346  *	of 128 bytes of reply data.
4347  *
4348  *	Returns a negative value on failure, else size of reply in WORDS.
4349  */
4350 static int
4351 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4352 {
4353 	int u16cnt = 0;
4354 	int failcnt = 0;
4355 	int t;
4356 	u16 *hs_reply = ioc->hs_reply;
4357 	volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4358 	u16 hword;
4359 
4360 	hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4361 
4362 	/*
4363 	 * Get first two u16's so we can look at IOC's intended reply MsgLength
4364 	 */
4365 	u16cnt=0;
4366 	if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4367 		failcnt++;
4368 	} else {
4369 		hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4370 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4371 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4372 			failcnt++;
4373 		else {
4374 			hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4375 			CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4376 		}
4377 	}
4378 
4379 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4380 			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4381 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4382 
4383 	/*
4384 	 * If no error (and IOC said MsgLength is > 0), piece together
4385 	 * reply 16 bits at a time.
4386 	 */
4387 	for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4388 		if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4389 			failcnt++;
4390 		hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4391 		/* don't overflow our IOC hs_reply[] buffer! */
4392 		if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4393 			hs_reply[u16cnt] = hword;
4394 		CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4395 	}
4396 
4397 	if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4398 		failcnt++;
4399 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4400 
4401 	if (failcnt) {
4402 		printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4403 				ioc->name);
4404 		return -failcnt;
4405 	}
4406 #if 0
4407 	else if (u16cnt != (2 * mptReply->MsgLength)) {
4408 		return -101;
4409 	}
4410 	else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4411 		return -102;
4412 	}
4413 #endif
4414 
4415 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4416 	DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4417 
4418 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4419 			ioc->name, t, u16cnt/2));
4420 	return u16cnt/2;
4421 }
4422 
4423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4424 /**
4425  *	GetLanConfigPages - Fetch LANConfig pages.
4426  *	@ioc: Pointer to MPT_ADAPTER structure
4427  *
4428  *	Return: 0 for success
4429  *	-ENOMEM if no memory available
4430  *		-EPERM if not allowed due to ISR context
4431  *		-EAGAIN if no msg frames currently available
4432  *		-EFAULT for non-successful reply or no reply (timeout)
4433  */
4434 static int
4435 GetLanConfigPages(MPT_ADAPTER *ioc)
4436 {
4437 	ConfigPageHeader_t	 hdr;
4438 	CONFIGPARMS		 cfg;
4439 	LANPage0_t		*ppage0_alloc;
4440 	dma_addr_t		 page0_dma;
4441 	LANPage1_t		*ppage1_alloc;
4442 	dma_addr_t		 page1_dma;
4443 	int			 rc = 0;
4444 	int			 data_sz;
4445 	int			 copy_sz;
4446 
4447 	/* Get LAN Page 0 header */
4448 	hdr.PageVersion = 0;
4449 	hdr.PageLength = 0;
4450 	hdr.PageNumber = 0;
4451 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4452 	cfg.cfghdr.hdr = &hdr;
4453 	cfg.physAddr = -1;
4454 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4455 	cfg.dir = 0;
4456 	cfg.pageAddr = 0;
4457 	cfg.timeout = 0;
4458 
4459 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4460 		return rc;
4461 
4462 	if (hdr.PageLength > 0) {
4463 		data_sz = hdr.PageLength * 4;
4464 		ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4465 		rc = -ENOMEM;
4466 		if (ppage0_alloc) {
4467 			memset((u8 *)ppage0_alloc, 0, data_sz);
4468 			cfg.physAddr = page0_dma;
4469 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4470 
4471 			if ((rc = mpt_config(ioc, &cfg)) == 0) {
4472 				/* save the data */
4473 				copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4474 				memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4475 
4476 			}
4477 
4478 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4479 
4480 			/* FIXME!
4481 			 *	Normalize endianness of structure data,
4482 			 *	by byte-swapping all > 1 byte fields!
4483 			 */
4484 
4485 		}
4486 
4487 		if (rc)
4488 			return rc;
4489 	}
4490 
4491 	/* Get LAN Page 1 header */
4492 	hdr.PageVersion = 0;
4493 	hdr.PageLength = 0;
4494 	hdr.PageNumber = 1;
4495 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4496 	cfg.cfghdr.hdr = &hdr;
4497 	cfg.physAddr = -1;
4498 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4499 	cfg.dir = 0;
4500 	cfg.pageAddr = 0;
4501 
4502 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4503 		return rc;
4504 
4505 	if (hdr.PageLength == 0)
4506 		return 0;
4507 
4508 	data_sz = hdr.PageLength * 4;
4509 	rc = -ENOMEM;
4510 	ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4511 	if (ppage1_alloc) {
4512 		memset((u8 *)ppage1_alloc, 0, data_sz);
4513 		cfg.physAddr = page1_dma;
4514 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4515 
4516 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
4517 			/* save the data */
4518 			copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4519 			memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4520 		}
4521 
4522 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4523 
4524 		/* FIXME!
4525 		 *	Normalize endianness of structure data,
4526 		 *	by byte-swapping all > 1 byte fields!
4527 		 */
4528 
4529 	}
4530 
4531 	return rc;
4532 }
4533 
4534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4535 /**
4536  *	mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4537  *	@ioc: Pointer to MPT_ADAPTER structure
4538  *	@persist_opcode: see below
4539  *
4540  *	MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4541  *		devices not currently present.
4542  *	MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4543  *
4544  *	NOTE: Don't use not this function during interrupt time.
4545  *
4546  *	Returns 0 for success, non-zero error
4547  */
4548 
4549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4550 int
4551 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4552 {
4553 	SasIoUnitControlRequest_t	*sasIoUnitCntrReq;
4554 	SasIoUnitControlReply_t		*sasIoUnitCntrReply;
4555 	MPT_FRAME_HDR			*mf = NULL;
4556 	MPIHeader_t			*mpi_hdr;
4557 
4558 
4559 	/* insure garbage is not sent to fw */
4560 	switch(persist_opcode) {
4561 
4562 	case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4563 	case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4564 		break;
4565 
4566 	default:
4567 		return -1;
4568 		break;
4569 	}
4570 
4571 	printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4572 
4573 	/* Get a MF for this command.
4574 	 */
4575 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4576 		printk("%s: no msg frames!\n",__FUNCTION__);
4577 		return -1;
4578         }
4579 
4580 	mpi_hdr = (MPIHeader_t *) mf;
4581 	sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4582 	memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4583 	sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4584 	sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4585 	sasIoUnitCntrReq->Operation = persist_opcode;
4586 
4587 	init_timer(&ioc->persist_timer);
4588 	ioc->persist_timer.data = (unsigned long) ioc;
4589 	ioc->persist_timer.function = mpt_timer_expired;
4590 	ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4591 	ioc->persist_wait_done=0;
4592 	add_timer(&ioc->persist_timer);
4593 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
4594 	wait_event(mpt_waitq, ioc->persist_wait_done);
4595 
4596 	sasIoUnitCntrReply =
4597 	    (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4598 	if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4599 		printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4600 		    __FUNCTION__,
4601 		    sasIoUnitCntrReply->IOCStatus,
4602 		    sasIoUnitCntrReply->IOCLogInfo);
4603 		return -1;
4604 	}
4605 
4606 	printk("%s: success\n",__FUNCTION__);
4607 	return 0;
4608 }
4609 
4610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4611 
4612 static void
4613 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4614     MpiEventDataRaid_t * pRaidEventData)
4615 {
4616 	int 	volume;
4617 	int 	reason;
4618 	int 	disk;
4619 	int 	status;
4620 	int 	flags;
4621 	int 	state;
4622 
4623 	volume	= pRaidEventData->VolumeID;
4624 	reason	= pRaidEventData->ReasonCode;
4625 	disk	= pRaidEventData->PhysDiskNum;
4626 	status	= le32_to_cpu(pRaidEventData->SettingsStatus);
4627 	flags	= (status >> 0) & 0xff;
4628 	state	= (status >> 8) & 0xff;
4629 
4630 	if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4631 		return;
4632 	}
4633 
4634 	if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4635 	     reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4636 	    (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4637 		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4638 			ioc->name, disk, volume);
4639 	} else {
4640 		printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4641 			ioc->name, volume);
4642 	}
4643 
4644 	switch(reason) {
4645 	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4646 		printk(MYIOC_s_INFO_FMT "  volume has been created\n",
4647 			ioc->name);
4648 		break;
4649 
4650 	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4651 
4652 		printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
4653 			ioc->name);
4654 		break;
4655 
4656 	case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4657 		printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
4658 			ioc->name);
4659 		break;
4660 
4661 	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4662 		printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
4663 			ioc->name,
4664 			state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4665 			 ? "optimal"
4666 			 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4667 			  ? "degraded"
4668 			  : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4669 			   ? "failed"
4670 			   : "state unknown",
4671 			flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4672 			 ? ", enabled" : "",
4673 			flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4674 			 ? ", quiesced" : "",
4675 			flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4676 			 ? ", resync in progress" : "" );
4677 		break;
4678 
4679 	case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4680 		printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
4681 			ioc->name, disk);
4682 		break;
4683 
4684 	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4685 		printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
4686 			ioc->name);
4687 		break;
4688 
4689 	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4690 		printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
4691 			ioc->name);
4692 		break;
4693 
4694 	case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4695 		printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
4696 			ioc->name);
4697 		break;
4698 
4699 	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4700 		printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
4701 			ioc->name,
4702 			state == MPI_PHYSDISK0_STATUS_ONLINE
4703 			 ? "online"
4704 			 : state == MPI_PHYSDISK0_STATUS_MISSING
4705 			  ? "missing"
4706 			  : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4707 			   ? "not compatible"
4708 			   : state == MPI_PHYSDISK0_STATUS_FAILED
4709 			    ? "failed"
4710 			    : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4711 			     ? "initializing"
4712 			     : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4713 			      ? "offline requested"
4714 			      : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4715 			       ? "failed requested"
4716 			       : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4717 			        ? "offline"
4718 			        : "state unknown",
4719 			flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4720 			 ? ", out of sync" : "",
4721 			flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4722 			 ? ", quiesced" : "" );
4723 		break;
4724 
4725 	case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4726 		printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
4727 			ioc->name, disk);
4728 		break;
4729 
4730 	case MPI_EVENT_RAID_RC_SMART_DATA:
4731 		printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4732 			ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4733 		break;
4734 
4735 	case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4736 		printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
4737 			ioc->name, disk);
4738 		break;
4739 	}
4740 }
4741 
4742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4743 /**
4744  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4745  *	@ioc: Pointer to MPT_ADAPTER structure
4746  *
4747  *	Returns: 0 for success
4748  *	-ENOMEM if no memory available
4749  *		-EPERM if not allowed due to ISR context
4750  *		-EAGAIN if no msg frames currently available
4751  *		-EFAULT for non-successful reply or no reply (timeout)
4752  */
4753 static int
4754 GetIoUnitPage2(MPT_ADAPTER *ioc)
4755 {
4756 	ConfigPageHeader_t	 hdr;
4757 	CONFIGPARMS		 cfg;
4758 	IOUnitPage2_t		*ppage_alloc;
4759 	dma_addr_t		 page_dma;
4760 	int			 data_sz;
4761 	int			 rc;
4762 
4763 	/* Get the page header */
4764 	hdr.PageVersion = 0;
4765 	hdr.PageLength = 0;
4766 	hdr.PageNumber = 2;
4767 	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4768 	cfg.cfghdr.hdr = &hdr;
4769 	cfg.physAddr = -1;
4770 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4771 	cfg.dir = 0;
4772 	cfg.pageAddr = 0;
4773 	cfg.timeout = 0;
4774 
4775 	if ((rc = mpt_config(ioc, &cfg)) != 0)
4776 		return rc;
4777 
4778 	if (hdr.PageLength == 0)
4779 		return 0;
4780 
4781 	/* Read the config page */
4782 	data_sz = hdr.PageLength * 4;
4783 	rc = -ENOMEM;
4784 	ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4785 	if (ppage_alloc) {
4786 		memset((u8 *)ppage_alloc, 0, data_sz);
4787 		cfg.physAddr = page_dma;
4788 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4789 
4790 		/* If Good, save data */
4791 		if ((rc = mpt_config(ioc, &cfg)) == 0)
4792 			ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4793 
4794 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4795 	}
4796 
4797 	return rc;
4798 }
4799 
4800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4801 /**
4802  *	mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4803  *	@ioc: Pointer to a Adapter Strucutre
4804  *	@portnum: IOC port number
4805  *
4806  *	Return: -EFAULT if read of config page header fails
4807  *			or if no nvram
4808  *	If read of SCSI Port Page 0 fails,
4809  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4810  *		Adapter settings: async, narrow
4811  *		Return 1
4812  *	If read of SCSI Port Page 2 fails,
4813  *		Adapter settings valid
4814  *		NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4815  *		Return 1
4816  *	Else
4817  *		Both valid
4818  *		Return 0
4819  *	CHECK - what type of locking mechanisms should be used????
4820  */
4821 static int
4822 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4823 {
4824 	u8			*pbuf;
4825 	dma_addr_t		 buf_dma;
4826 	CONFIGPARMS		 cfg;
4827 	ConfigPageHeader_t	 header;
4828 	int			 ii;
4829 	int			 data, rc = 0;
4830 
4831 	/* Allocate memory
4832 	 */
4833 	if (!ioc->spi_data.nvram) {
4834 		int	 sz;
4835 		u8	*mem;
4836 		sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4837 		mem = kmalloc(sz, GFP_ATOMIC);
4838 		if (mem == NULL)
4839 			return -EFAULT;
4840 
4841 		ioc->spi_data.nvram = (int *) mem;
4842 
4843 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4844 			ioc->name, ioc->spi_data.nvram, sz));
4845 	}
4846 
4847 	/* Invalidate NVRAM information
4848 	 */
4849 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4850 		ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4851 	}
4852 
4853 	/* Read SPP0 header, allocate memory, then read page.
4854 	 */
4855 	header.PageVersion = 0;
4856 	header.PageLength = 0;
4857 	header.PageNumber = 0;
4858 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4859 	cfg.cfghdr.hdr = &header;
4860 	cfg.physAddr = -1;
4861 	cfg.pageAddr = portnum;
4862 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4863 	cfg.dir = 0;
4864 	cfg.timeout = 0;	/* use default */
4865 	if (mpt_config(ioc, &cfg) != 0)
4866 		 return -EFAULT;
4867 
4868 	if (header.PageLength > 0) {
4869 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4870 		if (pbuf) {
4871 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4872 			cfg.physAddr = buf_dma;
4873 			if (mpt_config(ioc, &cfg) != 0) {
4874 				ioc->spi_data.maxBusWidth = MPT_NARROW;
4875 				ioc->spi_data.maxSyncOffset = 0;
4876 				ioc->spi_data.minSyncFactor = MPT_ASYNC;
4877 				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4878 				rc = 1;
4879 				ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4880 					"Unable to read PortPage0 minSyncFactor=%x\n",
4881 					ioc->name, ioc->spi_data.minSyncFactor));
4882 			} else {
4883 				/* Save the Port Page 0 data
4884 				 */
4885 				SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4886 				pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4887 				pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4888 
4889 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4890 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4891 					ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4892 						"noQas due to Capabilities=%x\n",
4893 						ioc->name, pPP0->Capabilities));
4894 				}
4895 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4896 				data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4897 				if (data) {
4898 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4899 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4900 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4901 					ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4902 						"PortPage0 minSyncFactor=%x\n",
4903 						ioc->name, ioc->spi_data.minSyncFactor));
4904 				} else {
4905 					ioc->spi_data.maxSyncOffset = 0;
4906 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
4907 				}
4908 
4909 				ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4910 
4911 				/* Update the minSyncFactor based on bus type.
4912 				 */
4913 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4914 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4915 
4916 					if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4917 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
4918 						ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4919 							"HVD or SE detected, minSyncFactor=%x\n",
4920 							ioc->name, ioc->spi_data.minSyncFactor));
4921 					}
4922 				}
4923 			}
4924 			if (pbuf) {
4925 				pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4926 			}
4927 		}
4928 	}
4929 
4930 	/* SCSI Port Page 2 - Read the header then the page.
4931 	 */
4932 	header.PageVersion = 0;
4933 	header.PageLength = 0;
4934 	header.PageNumber = 2;
4935 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4936 	cfg.cfghdr.hdr = &header;
4937 	cfg.physAddr = -1;
4938 	cfg.pageAddr = portnum;
4939 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4940 	cfg.dir = 0;
4941 	if (mpt_config(ioc, &cfg) != 0)
4942 		return -EFAULT;
4943 
4944 	if (header.PageLength > 0) {
4945 		/* Allocate memory and read SCSI Port Page 2
4946 		 */
4947 		pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4948 		if (pbuf) {
4949 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4950 			cfg.physAddr = buf_dma;
4951 			if (mpt_config(ioc, &cfg) != 0) {
4952 				/* Nvram data is left with INVALID mark
4953 				 */
4954 				rc = 1;
4955 			} else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4956 
4957 				/* This is an ATTO adapter, read Page2 accordingly
4958 				*/
4959 				ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t  *) pbuf;
4960 				ATTODeviceInfo_t *pdevice = NULL;
4961 				u16 ATTOFlags;
4962 
4963 				/* Save the Port Page 2 data
4964 				 * (reformat into a 32bit quantity)
4965 				 */
4966 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4967 				  pdevice = &pPP2->DeviceSettings[ii];
4968 				  ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4969 				  data = 0;
4970 
4971 				  /* Translate ATTO device flags to LSI format
4972 				   */
4973 				  if (ATTOFlags & ATTOFLAG_DISC)
4974 				    data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4975 				  if (ATTOFlags & ATTOFLAG_ID_ENB)
4976 				    data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4977 				  if (ATTOFlags & ATTOFLAG_LUN_ENB)
4978 				    data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4979 				  if (ATTOFlags & ATTOFLAG_TAGGED)
4980 				    data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4981 				  if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4982 				    data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4983 
4984 				  data = (data << 16) | (pdevice->Period << 8) | 10;
4985 				  ioc->spi_data.nvram[ii] = data;
4986 				}
4987 			} else {
4988 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4989 				MpiDeviceInfo_t	*pdevice = NULL;
4990 
4991 				/*
4992 				 * Save "Set to Avoid SCSI Bus Resets" flag
4993 				 */
4994 				ioc->spi_data.bus_reset =
4995 				    (le32_to_cpu(pPP2->PortFlags) &
4996 			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4997 				    0 : 1 ;
4998 
4999 				/* Save the Port Page 2 data
5000 				 * (reformat into a 32bit quantity)
5001 				 */
5002 				data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5003 				ioc->spi_data.PortFlags = data;
5004 				for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5005 					pdevice = &pPP2->DeviceSettings[ii];
5006 					data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5007 						(pdevice->SyncFactor << 8) | pdevice->Timeout;
5008 					ioc->spi_data.nvram[ii] = data;
5009 				}
5010 			}
5011 
5012 			pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5013 		}
5014 	}
5015 
5016 	/* Update Adapter limits with those from NVRAM
5017 	 * Comment: Don't need to do this. Target performance
5018 	 * parameters will never exceed the adapters limits.
5019 	 */
5020 
5021 	return rc;
5022 }
5023 
5024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5025 /**
5026  *	mpt_readScsiDevicePageHeaders - save version and length of SDP1
5027  *	@ioc: Pointer to a Adapter Strucutre
5028  *	@portnum: IOC port number
5029  *
5030  *	Return: -EFAULT if read of config page header fails
5031  *		or 0 if success.
5032  */
5033 static int
5034 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5035 {
5036 	CONFIGPARMS		 cfg;
5037 	ConfigPageHeader_t	 header;
5038 
5039 	/* Read the SCSI Device Page 1 header
5040 	 */
5041 	header.PageVersion = 0;
5042 	header.PageLength = 0;
5043 	header.PageNumber = 1;
5044 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5045 	cfg.cfghdr.hdr = &header;
5046 	cfg.physAddr = -1;
5047 	cfg.pageAddr = portnum;
5048 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5049 	cfg.dir = 0;
5050 	cfg.timeout = 0;
5051 	if (mpt_config(ioc, &cfg) != 0)
5052 		 return -EFAULT;
5053 
5054 	ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5055 	ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5056 
5057 	header.PageVersion = 0;
5058 	header.PageLength = 0;
5059 	header.PageNumber = 0;
5060 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5061 	if (mpt_config(ioc, &cfg) != 0)
5062 		 return -EFAULT;
5063 
5064 	ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5065 	ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5066 
5067 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5068 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5069 
5070 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5071 			ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5072 	return 0;
5073 }
5074 
5075 /**
5076  * mpt_inactive_raid_list_free - This clears this link list.
5077  * @ioc : pointer to per adapter structure
5078  **/
5079 static void
5080 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5081 {
5082 	struct inactive_raid_component_info *component_info, *pNext;
5083 
5084 	if (list_empty(&ioc->raid_data.inactive_list))
5085 		return;
5086 
5087 	down(&ioc->raid_data.inactive_list_mutex);
5088 	list_for_each_entry_safe(component_info, pNext,
5089 	    &ioc->raid_data.inactive_list, list) {
5090 		list_del(&component_info->list);
5091 		kfree(component_info);
5092 	}
5093 	up(&ioc->raid_data.inactive_list_mutex);
5094 }
5095 
5096 /**
5097  * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5098  *
5099  * @ioc : pointer to per adapter structure
5100  * @channel : volume channel
5101  * @id : volume target id
5102  **/
5103 static void
5104 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5105 {
5106 	CONFIGPARMS			cfg;
5107 	ConfigPageHeader_t		hdr;
5108 	dma_addr_t			dma_handle;
5109 	pRaidVolumePage0_t		buffer = NULL;
5110 	int				i;
5111 	RaidPhysDiskPage0_t 		phys_disk;
5112 	struct inactive_raid_component_info *component_info;
5113 	int				handle_inactive_volumes;
5114 
5115 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5116 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5117 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5118 	cfg.pageAddr = (channel << 8) + id;
5119 	cfg.cfghdr.hdr = &hdr;
5120 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5121 
5122 	if (mpt_config(ioc, &cfg) != 0)
5123 		goto out;
5124 
5125 	if (!hdr.PageLength)
5126 		goto out;
5127 
5128 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5129 	    &dma_handle);
5130 
5131 	if (!buffer)
5132 		goto out;
5133 
5134 	cfg.physAddr = dma_handle;
5135 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5136 
5137 	if (mpt_config(ioc, &cfg) != 0)
5138 		goto out;
5139 
5140 	if (!buffer->NumPhysDisks)
5141 		goto out;
5142 
5143 	handle_inactive_volumes =
5144 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5145 	   (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5146 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5147 	    buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5148 
5149 	if (!handle_inactive_volumes)
5150 		goto out;
5151 
5152 	down(&ioc->raid_data.inactive_list_mutex);
5153 	for (i = 0; i < buffer->NumPhysDisks; i++) {
5154 		if(mpt_raid_phys_disk_pg0(ioc,
5155 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5156 			continue;
5157 
5158 		if ((component_info = kmalloc(sizeof (*component_info),
5159 		 GFP_KERNEL)) == NULL)
5160 			continue;
5161 
5162 		component_info->volumeID = id;
5163 		component_info->volumeBus = channel;
5164 		component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5165 		component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5166 		component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5167 		component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5168 
5169 		list_add_tail(&component_info->list,
5170 		    &ioc->raid_data.inactive_list);
5171 	}
5172 	up(&ioc->raid_data.inactive_list_mutex);
5173 
5174  out:
5175 	if (buffer)
5176 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5177 		    dma_handle);
5178 }
5179 
5180 /**
5181  *	mpt_raid_phys_disk_pg0 - returns phys disk page zero
5182  *	@ioc: Pointer to a Adapter Structure
5183  *	@phys_disk_num: io unit unique phys disk num generated by the ioc
5184  *	@phys_disk: requested payload data returned
5185  *
5186  *	Return:
5187  *	0 on success
5188  *	-EFAULT if read of config page header fails or data pointer not NULL
5189  *	-ENOMEM if pci_alloc failed
5190  **/
5191 int
5192 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5193 {
5194 	CONFIGPARMS		 	cfg;
5195 	ConfigPageHeader_t	 	hdr;
5196 	dma_addr_t			dma_handle;
5197 	pRaidPhysDiskPage0_t		buffer = NULL;
5198 	int				rc;
5199 
5200 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5201 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5202 
5203 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5204 	cfg.cfghdr.hdr = &hdr;
5205 	cfg.physAddr = -1;
5206 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5207 
5208 	if (mpt_config(ioc, &cfg) != 0) {
5209 		rc = -EFAULT;
5210 		goto out;
5211 	}
5212 
5213 	if (!hdr.PageLength) {
5214 		rc = -EFAULT;
5215 		goto out;
5216 	}
5217 
5218 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5219 	    &dma_handle);
5220 
5221 	if (!buffer) {
5222 		rc = -ENOMEM;
5223 		goto out;
5224 	}
5225 
5226 	cfg.physAddr = dma_handle;
5227 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5228 	cfg.pageAddr = phys_disk_num;
5229 
5230 	if (mpt_config(ioc, &cfg) != 0) {
5231 		rc = -EFAULT;
5232 		goto out;
5233 	}
5234 
5235 	rc = 0;
5236 	memcpy(phys_disk, buffer, sizeof(*buffer));
5237 	phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5238 
5239  out:
5240 
5241 	if (buffer)
5242 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5243 		    dma_handle);
5244 
5245 	return rc;
5246 }
5247 
5248 /**
5249  *	mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5250  *	@ioc: Pointer to a Adapter Strucutre
5251  *	@portnum: IOC port number
5252  *
5253  *	Return:
5254  *	0 on success
5255  *	-EFAULT if read of config page header fails or data pointer not NULL
5256  *	-ENOMEM if pci_alloc failed
5257  **/
5258 int
5259 mpt_findImVolumes(MPT_ADAPTER *ioc)
5260 {
5261 	IOCPage2_t		*pIoc2;
5262 	u8			*mem;
5263 	dma_addr_t		 ioc2_dma;
5264 	CONFIGPARMS		 cfg;
5265 	ConfigPageHeader_t	 header;
5266 	int			 rc = 0;
5267 	int			 iocpage2sz;
5268 	int			 i;
5269 
5270 	if (!ioc->ir_firmware)
5271 		return 0;
5272 
5273 	/* Free the old page
5274 	 */
5275 	kfree(ioc->raid_data.pIocPg2);
5276 	ioc->raid_data.pIocPg2 = NULL;
5277 	mpt_inactive_raid_list_free(ioc);
5278 
5279 	/* Read IOCP2 header then the page.
5280 	 */
5281 	header.PageVersion = 0;
5282 	header.PageLength = 0;
5283 	header.PageNumber = 2;
5284 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5285 	cfg.cfghdr.hdr = &header;
5286 	cfg.physAddr = -1;
5287 	cfg.pageAddr = 0;
5288 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5289 	cfg.dir = 0;
5290 	cfg.timeout = 0;
5291 	if (mpt_config(ioc, &cfg) != 0)
5292 		 return -EFAULT;
5293 
5294 	if (header.PageLength == 0)
5295 		return -EFAULT;
5296 
5297 	iocpage2sz = header.PageLength * 4;
5298 	pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5299 	if (!pIoc2)
5300 		return -ENOMEM;
5301 
5302 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5303 	cfg.physAddr = ioc2_dma;
5304 	if (mpt_config(ioc, &cfg) != 0)
5305 		goto out;
5306 
5307 	mem = kmalloc(iocpage2sz, GFP_KERNEL);
5308 	if (!mem)
5309 		goto out;
5310 
5311 	memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5312 	ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5313 
5314 	mpt_read_ioc_pg_3(ioc);
5315 
5316 	for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5317 		mpt_inactive_raid_volumes(ioc,
5318 		    pIoc2->RaidVolume[i].VolumeBus,
5319 		    pIoc2->RaidVolume[i].VolumeID);
5320 
5321  out:
5322 	pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5323 
5324 	return rc;
5325 }
5326 
5327 static int
5328 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5329 {
5330 	IOCPage3_t		*pIoc3;
5331 	u8			*mem;
5332 	CONFIGPARMS		 cfg;
5333 	ConfigPageHeader_t	 header;
5334 	dma_addr_t		 ioc3_dma;
5335 	int			 iocpage3sz = 0;
5336 
5337 	/* Free the old page
5338 	 */
5339 	kfree(ioc->raid_data.pIocPg3);
5340 	ioc->raid_data.pIocPg3 = NULL;
5341 
5342 	/* There is at least one physical disk.
5343 	 * Read and save IOC Page 3
5344 	 */
5345 	header.PageVersion = 0;
5346 	header.PageLength = 0;
5347 	header.PageNumber = 3;
5348 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5349 	cfg.cfghdr.hdr = &header;
5350 	cfg.physAddr = -1;
5351 	cfg.pageAddr = 0;
5352 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5353 	cfg.dir = 0;
5354 	cfg.timeout = 0;
5355 	if (mpt_config(ioc, &cfg) != 0)
5356 		return 0;
5357 
5358 	if (header.PageLength == 0)
5359 		return 0;
5360 
5361 	/* Read Header good, alloc memory
5362 	 */
5363 	iocpage3sz = header.PageLength * 4;
5364 	pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5365 	if (!pIoc3)
5366 		return 0;
5367 
5368 	/* Read the Page and save the data
5369 	 * into malloc'd memory.
5370 	 */
5371 	cfg.physAddr = ioc3_dma;
5372 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5373 	if (mpt_config(ioc, &cfg) == 0) {
5374 		mem = kmalloc(iocpage3sz, GFP_KERNEL);
5375 		if (mem) {
5376 			memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5377 			ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5378 		}
5379 	}
5380 
5381 	pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5382 
5383 	return 0;
5384 }
5385 
5386 static void
5387 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5388 {
5389 	IOCPage4_t		*pIoc4;
5390 	CONFIGPARMS		 cfg;
5391 	ConfigPageHeader_t	 header;
5392 	dma_addr_t		 ioc4_dma;
5393 	int			 iocpage4sz;
5394 
5395 	/* Read and save IOC Page 4
5396 	 */
5397 	header.PageVersion = 0;
5398 	header.PageLength = 0;
5399 	header.PageNumber = 4;
5400 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5401 	cfg.cfghdr.hdr = &header;
5402 	cfg.physAddr = -1;
5403 	cfg.pageAddr = 0;
5404 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5405 	cfg.dir = 0;
5406 	cfg.timeout = 0;
5407 	if (mpt_config(ioc, &cfg) != 0)
5408 		return;
5409 
5410 	if (header.PageLength == 0)
5411 		return;
5412 
5413 	if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5414 		iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5415 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5416 		if (!pIoc4)
5417 			return;
5418 		ioc->alloc_total += iocpage4sz;
5419 	} else {
5420 		ioc4_dma = ioc->spi_data.IocPg4_dma;
5421 		iocpage4sz = ioc->spi_data.IocPg4Sz;
5422 	}
5423 
5424 	/* Read the Page into dma memory.
5425 	 */
5426 	cfg.physAddr = ioc4_dma;
5427 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5428 	if (mpt_config(ioc, &cfg) == 0) {
5429 		ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5430 		ioc->spi_data.IocPg4_dma = ioc4_dma;
5431 		ioc->spi_data.IocPg4Sz = iocpage4sz;
5432 	} else {
5433 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5434 		ioc->spi_data.pIocPg4 = NULL;
5435 		ioc->alloc_total -= iocpage4sz;
5436 	}
5437 }
5438 
5439 static void
5440 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5441 {
5442 	IOCPage1_t		*pIoc1;
5443 	CONFIGPARMS		 cfg;
5444 	ConfigPageHeader_t	 header;
5445 	dma_addr_t		 ioc1_dma;
5446 	int			 iocpage1sz = 0;
5447 	u32			 tmp;
5448 
5449 	/* Check the Coalescing Timeout in IOC Page 1
5450 	 */
5451 	header.PageVersion = 0;
5452 	header.PageLength = 0;
5453 	header.PageNumber = 1;
5454 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5455 	cfg.cfghdr.hdr = &header;
5456 	cfg.physAddr = -1;
5457 	cfg.pageAddr = 0;
5458 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5459 	cfg.dir = 0;
5460 	cfg.timeout = 0;
5461 	if (mpt_config(ioc, &cfg) != 0)
5462 		return;
5463 
5464 	if (header.PageLength == 0)
5465 		return;
5466 
5467 	/* Read Header good, alloc memory
5468 	 */
5469 	iocpage1sz = header.PageLength * 4;
5470 	pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5471 	if (!pIoc1)
5472 		return;
5473 
5474 	/* Read the Page and check coalescing timeout
5475 	 */
5476 	cfg.physAddr = ioc1_dma;
5477 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5478 	if (mpt_config(ioc, &cfg) == 0) {
5479 
5480 		tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5481 		if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5482 			tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5483 
5484 			dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5485 					ioc->name, tmp));
5486 
5487 			if (tmp > MPT_COALESCING_TIMEOUT) {
5488 				pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5489 
5490 				/* Write NVRAM and current
5491 				 */
5492 				cfg.dir = 1;
5493 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5494 				if (mpt_config(ioc, &cfg) == 0) {
5495 					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5496 							ioc->name, MPT_COALESCING_TIMEOUT));
5497 
5498 					cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5499 					if (mpt_config(ioc, &cfg) == 0) {
5500 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5501 								"Reset NVRAM Coalescing Timeout to = %d\n",
5502 								ioc->name, MPT_COALESCING_TIMEOUT));
5503 					} else {
5504 						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5505 								"Reset NVRAM Coalescing Timeout Failed\n",
5506 								ioc->name));
5507 					}
5508 
5509 				} else {
5510 					dprintk(ioc, printk(MYIOC_s_WARN_FMT
5511 						"Reset of Current Coalescing Timeout Failed!\n",
5512 						ioc->name));
5513 				}
5514 			}
5515 
5516 		} else {
5517 			dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5518 		}
5519 	}
5520 
5521 	pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5522 
5523 	return;
5524 }
5525 
5526 static void
5527 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5528 {
5529 	CONFIGPARMS		cfg;
5530 	ConfigPageHeader_t	hdr;
5531 	dma_addr_t		buf_dma;
5532 	ManufacturingPage0_t	*pbuf = NULL;
5533 
5534 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
5535 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5536 
5537 	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5538 	cfg.cfghdr.hdr = &hdr;
5539 	cfg.physAddr = -1;
5540 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5541 	cfg.timeout = 10;
5542 
5543 	if (mpt_config(ioc, &cfg) != 0)
5544 		goto out;
5545 
5546 	if (!cfg.cfghdr.hdr->PageLength)
5547 		goto out;
5548 
5549 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5550 	pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5551 	if (!pbuf)
5552 		goto out;
5553 
5554 	cfg.physAddr = buf_dma;
5555 
5556 	if (mpt_config(ioc, &cfg) != 0)
5557 		goto out;
5558 
5559 	memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5560 	memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5561 	memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5562 
5563 	out:
5564 
5565 	if (pbuf)
5566 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5567 }
5568 
5569 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5570 /**
5571  *	SendEventNotification - Send EventNotification (on or off) request to adapter
5572  *	@ioc: Pointer to MPT_ADAPTER structure
5573  *	@EvSwitch: Event switch flags
5574  */
5575 static int
5576 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5577 {
5578 	EventNotification_t	*evnp;
5579 
5580 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5581 	if (evnp == NULL) {
5582 		devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5583 				ioc->name));
5584 		return 0;
5585 	}
5586 	memset(evnp, 0, sizeof(*evnp));
5587 
5588 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5589 
5590 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5591 	evnp->ChainOffset = 0;
5592 	evnp->MsgFlags = 0;
5593 	evnp->Switch = EvSwitch;
5594 
5595 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5596 
5597 	return 0;
5598 }
5599 
5600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5601 /**
5602  *	SendEventAck - Send EventAck request to MPT adapter.
5603  *	@ioc: Pointer to MPT_ADAPTER structure
5604  *	@evnp: Pointer to original EventNotification request
5605  */
5606 static int
5607 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5608 {
5609 	EventAck_t	*pAck;
5610 
5611 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5612 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5613 		    ioc->name,__FUNCTION__));
5614 		return -1;
5615 	}
5616 
5617 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5618 
5619 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
5620 	pAck->ChainOffset  = 0;
5621 	pAck->Reserved[0]  = pAck->Reserved[1] = 0;
5622 	pAck->MsgFlags     = 0;
5623 	pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5624 	pAck->Event        = evnp->Event;
5625 	pAck->EventContext = evnp->EventContext;
5626 
5627 	mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5628 
5629 	return 0;
5630 }
5631 
5632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5633 /**
5634  *	mpt_config - Generic function to issue config message
5635  *	@ioc:   Pointer to an adapter structure
5636  *	@pCfg:  Pointer to a configuration structure. Struct contains
5637  *		action, page address, direction, physical address
5638  *		and pointer to a configuration page header
5639  *		Page header is updated.
5640  *
5641  *	Returns 0 for success
5642  *	-EPERM if not allowed due to ISR context
5643  *	-EAGAIN if no msg frames currently available
5644  *	-EFAULT for non-successful reply or no reply (timeout)
5645  */
5646 int
5647 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5648 {
5649 	Config_t	*pReq;
5650 	ConfigExtendedPageHeader_t  *pExtHdr = NULL;
5651 	MPT_FRAME_HDR	*mf;
5652 	unsigned long	 flags;
5653 	int		 ii, rc;
5654 	int		 flagsLength;
5655 	int		 in_isr;
5656 
5657 	/*	Prevent calling wait_event() (below), if caller happens
5658 	 *	to be in ISR context, because that is fatal!
5659 	 */
5660 	in_isr = in_interrupt();
5661 	if (in_isr) {
5662 		dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5663 				ioc->name));
5664 		return -EPERM;
5665 	}
5666 
5667 	/* Get and Populate a free Frame
5668 	 */
5669 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5670 		dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5671 				ioc->name));
5672 		return -EAGAIN;
5673 	}
5674 	pReq = (Config_t *)mf;
5675 	pReq->Action = pCfg->action;
5676 	pReq->Reserved = 0;
5677 	pReq->ChainOffset = 0;
5678 	pReq->Function = MPI_FUNCTION_CONFIG;
5679 
5680 	/* Assume page type is not extended and clear "reserved" fields. */
5681 	pReq->ExtPageLength = 0;
5682 	pReq->ExtPageType = 0;
5683 	pReq->MsgFlags = 0;
5684 
5685 	for (ii=0; ii < 8; ii++)
5686 		pReq->Reserved2[ii] = 0;
5687 
5688 	pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5689 	pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5690 	pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5691 	pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5692 
5693 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5694 		pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5695 		pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5696 		pReq->ExtPageType = pExtHdr->ExtPageType;
5697 		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5698 
5699 		/* Page Length must be treated as a reserved field for the extended header. */
5700 		pReq->Header.PageLength = 0;
5701 	}
5702 
5703 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5704 
5705 	/* Add a SGE to the config request.
5706 	 */
5707 	if (pCfg->dir)
5708 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5709 	else
5710 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5711 
5712 	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5713 		flagsLength |= pExtHdr->ExtPageLength * 4;
5714 
5715 		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5716 			ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5717 	}
5718 	else {
5719 		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5720 
5721 		dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5722 			ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5723 	}
5724 
5725 	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5726 
5727 	/* Append pCfg pointer to end of mf
5728 	 */
5729 	*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
5730 
5731 	/* Initalize the timer
5732 	 */
5733 	init_timer(&pCfg->timer);
5734 	pCfg->timer.data = (unsigned long) ioc;
5735 	pCfg->timer.function = mpt_timer_expired;
5736 	pCfg->wait_done = 0;
5737 
5738 	/* Set the timer; ensure 10 second minimum */
5739 	if (pCfg->timeout < 10)
5740 		pCfg->timer.expires = jiffies + HZ*10;
5741 	else
5742 		pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5743 
5744 	/* Add to end of Q, set timer and then issue this command */
5745 	spin_lock_irqsave(&ioc->FreeQlock, flags);
5746 	list_add_tail(&pCfg->linkage, &ioc->configQ);
5747 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5748 
5749 	add_timer(&pCfg->timer);
5750 	mpt_put_msg_frame(mpt_base_index, ioc, mf);
5751 	wait_event(mpt_waitq, pCfg->wait_done);
5752 
5753 	/* mf has been freed - do not access */
5754 
5755 	rc = pCfg->status;
5756 
5757 	return rc;
5758 }
5759 
5760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5761 /**
5762  *	mpt_timer_expired - Callback for timer process.
5763  *	Used only internal config functionality.
5764  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5765  */
5766 static void
5767 mpt_timer_expired(unsigned long data)
5768 {
5769 	MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5770 
5771 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5772 
5773 	/* Perform a FW reload */
5774 	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5775 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5776 
5777 	/* No more processing.
5778 	 * Hard reset clean-up will wake up
5779 	 * process and free all resources.
5780 	 */
5781 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5782 
5783 	return;
5784 }
5785 
5786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5787 /**
5788  *	mpt_ioc_reset - Base cleanup for hard reset
5789  *	@ioc: Pointer to the adapter structure
5790  *	@reset_phase: Indicates pre- or post-reset functionality
5791  *
5792  *	Remark: Frees resources with internally generated commands.
5793  */
5794 static int
5795 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5796 {
5797 	CONFIGPARMS *pCfg;
5798 	unsigned long flags;
5799 
5800 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5801 	    ": IOC %s_reset routed to MPT base driver!\n",
5802 	    ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5803 	    reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5804 
5805 	if (reset_phase == MPT_IOC_SETUP_RESET) {
5806 		;
5807 	} else if (reset_phase == MPT_IOC_PRE_RESET) {
5808 		/* If the internal config Q is not empty -
5809 		 * delete timer. MF resources will be freed when
5810 		 * the FIFO's are primed.
5811 		 */
5812 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5813 		list_for_each_entry(pCfg, &ioc->configQ, linkage)
5814 			del_timer(&pCfg->timer);
5815 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5816 
5817 	} else {
5818 		CONFIGPARMS *pNext;
5819 
5820 		/* Search the configQ for internal commands.
5821 		 * Flush the Q, and wake up all suspended threads.
5822 		 */
5823 		spin_lock_irqsave(&ioc->FreeQlock, flags);
5824 		list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5825 			list_del(&pCfg->linkage);
5826 
5827 			pCfg->status = MPT_CONFIG_ERROR;
5828 			pCfg->wait_done = 1;
5829 			wake_up(&mpt_waitq);
5830 		}
5831 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5832 	}
5833 
5834 	return 1;		/* currently means nothing really */
5835 }
5836 
5837 
5838 #ifdef CONFIG_PROC_FS		/* { */
5839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5840 /*
5841  *	procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5842  */
5843 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5844 /**
5845  *	procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5846  *
5847  *	Returns 0 for success, non-zero for failure.
5848  */
5849 static int
5850 procmpt_create(void)
5851 {
5852 	struct proc_dir_entry	*ent;
5853 
5854 	mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5855 	if (mpt_proc_root_dir == NULL)
5856 		return -ENOTDIR;
5857 
5858 	ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5859 	if (ent)
5860 		ent->read_proc = procmpt_summary_read;
5861 
5862 	ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5863 	if (ent)
5864 		ent->read_proc = procmpt_version_read;
5865 
5866 	return 0;
5867 }
5868 
5869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5870 /**
5871  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5872  *
5873  *	Returns 0 for success, non-zero for failure.
5874  */
5875 static void
5876 procmpt_destroy(void)
5877 {
5878 	remove_proc_entry("version", mpt_proc_root_dir);
5879 	remove_proc_entry("summary", mpt_proc_root_dir);
5880 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5881 }
5882 
5883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5884 /**
5885  *	procmpt_summary_read - Handle read request of a summary file
5886  *	@buf: Pointer to area to write information
5887  *	@start: Pointer to start pointer
5888  *	@offset: Offset to start writing
5889  *	@request: Amount of read data requested
5890  *	@eof: Pointer to EOF integer
5891  *	@data: Pointer
5892  *
5893  *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5894  *	Returns number of characters written to process performing the read.
5895  */
5896 static int
5897 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5898 {
5899 	MPT_ADAPTER *ioc;
5900 	char *out = buf;
5901 	int len;
5902 
5903 	if (data) {
5904 		int more = 0;
5905 
5906 		ioc = data;
5907 		mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5908 
5909 		out += more;
5910 	} else {
5911 		list_for_each_entry(ioc, &ioc_list, list) {
5912 			int	more = 0;
5913 
5914 			mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5915 
5916 			out += more;
5917 			if ((out-buf) >= request)
5918 				break;
5919 		}
5920 	}
5921 
5922 	len = out - buf;
5923 
5924 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5925 }
5926 
5927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5928 /**
5929  *	procmpt_version_read - Handle read request from /proc/mpt/version.
5930  *	@buf: Pointer to area to write information
5931  *	@start: Pointer to start pointer
5932  *	@offset: Offset to start writing
5933  *	@request: Amount of read data requested
5934  *	@eof: Pointer to EOF integer
5935  *	@data: Pointer
5936  *
5937  *	Returns number of characters written to process performing the read.
5938  */
5939 static int
5940 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5941 {
5942 	u8	 cb_idx;
5943 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
5944 	char	*drvname;
5945 	int	 len;
5946 
5947 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5948 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
5949 
5950 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
5951 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5952 		drvname = NULL;
5953 		if (MptCallbacks[cb_idx]) {
5954 			switch (MptDriverClass[cb_idx]) {
5955 			case MPTSPI_DRIVER:
5956 				if (!scsi++) drvname = "SPI host";
5957 				break;
5958 			case MPTFC_DRIVER:
5959 				if (!fc++) drvname = "FC host";
5960 				break;
5961 			case MPTSAS_DRIVER:
5962 				if (!sas++) drvname = "SAS host";
5963 				break;
5964 			case MPTLAN_DRIVER:
5965 				if (!lan++) drvname = "LAN";
5966 				break;
5967 			case MPTSTM_DRIVER:
5968 				if (!targ++) drvname = "SCSI target";
5969 				break;
5970 			case MPTCTL_DRIVER:
5971 				if (!ctl++) drvname = "ioctl";
5972 				break;
5973 			}
5974 
5975 			if (drvname)
5976 				len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5977 		}
5978 	}
5979 
5980 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5981 }
5982 
5983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5984 /**
5985  *	procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5986  *	@buf: Pointer to area to write information
5987  *	@start: Pointer to start pointer
5988  *	@offset: Offset to start writing
5989  *	@request: Amount of read data requested
5990  *	@eof: Pointer to EOF integer
5991  *	@data: Pointer
5992  *
5993  *	Returns number of characters written to process performing the read.
5994  */
5995 static int
5996 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5997 {
5998 	MPT_ADAPTER	*ioc = data;
5999 	int		 len;
6000 	char		 expVer[32];
6001 	int		 sz;
6002 	int		 p;
6003 
6004 	mpt_get_fw_exp_ver(expVer, ioc);
6005 
6006 	len = sprintf(buf, "%s:", ioc->name);
6007 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6008 		len += sprintf(buf+len, "  (f/w download boot flag set)");
6009 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6010 //		len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
6011 
6012 	len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
6013 			ioc->facts.ProductID,
6014 			ioc->prod_name);
6015 	len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6016 	if (ioc->facts.FWImageSize)
6017 		len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6018 	len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6019 	len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6020 	len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
6021 
6022 	len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
6023 			ioc->facts.CurrentHostMfaHighAddr);
6024 	len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6025 			ioc->facts.CurrentSenseBufferHighAddr);
6026 
6027 	len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6028 	len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6029 
6030 	len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6031 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6032 	/*
6033 	 *  Rounding UP to nearest 4-kB boundary here...
6034 	 */
6035 	sz = (ioc->req_sz * ioc->req_depth) + 128;
6036 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6037 	len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6038 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6039 	len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6040 					4*ioc->facts.RequestFrameSize,
6041 					ioc->facts.GlobalCredits);
6042 
6043 	len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6044 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6045 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6046 	len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6047 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6048 	len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6049 					ioc->facts.CurReplyFrameSize,
6050 					ioc->facts.ReplyQueueDepth);
6051 
6052 	len += sprintf(buf+len, "  MaxDevices = %d\n",
6053 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6054 	len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6055 
6056 	/* per-port info */
6057 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6058 		len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
6059 				p+1,
6060 				ioc->facts.NumberOfPorts);
6061 		if (ioc->bus_type == FC) {
6062 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6063 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6064 				len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6065 						a[5], a[4], a[3], a[2], a[1], a[0]);
6066 			}
6067 			len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
6068 					ioc->fc_port_page0[p].WWNN.High,
6069 					ioc->fc_port_page0[p].WWNN.Low,
6070 					ioc->fc_port_page0[p].WWPN.High,
6071 					ioc->fc_port_page0[p].WWPN.Low);
6072 		}
6073 	}
6074 
6075 	MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6076 }
6077 
6078 #endif		/* CONFIG_PROC_FS } */
6079 
6080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6081 static void
6082 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6083 {
6084 	buf[0] ='\0';
6085 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6086 		sprintf(buf, " (Exp %02d%02d)",
6087 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
6088 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
6089 
6090 		/* insider hack! */
6091 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6092 			strcat(buf, " [MDBG]");
6093 	}
6094 }
6095 
6096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6097 /**
6098  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6099  *	@ioc: Pointer to MPT_ADAPTER structure
6100  *	@buffer: Pointer to buffer where IOC summary info should be written
6101  *	@size: Pointer to number of bytes we wrote (set by this routine)
6102  *	@len: Offset at which to start writing in buffer
6103  *	@showlan: Display LAN stuff?
6104  *
6105  *	This routine writes (english readable) ASCII text, which represents
6106  *	a summary of IOC information, to a buffer.
6107  */
6108 void
6109 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6110 {
6111 	char expVer[32];
6112 	int y;
6113 
6114 	mpt_get_fw_exp_ver(expVer, ioc);
6115 
6116 	/*
6117 	 *  Shorter summary of attached ioc's...
6118 	 */
6119 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6120 			ioc->name,
6121 			ioc->prod_name,
6122 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6123 			ioc->facts.FWVersion.Word,
6124 			expVer,
6125 			ioc->facts.NumberOfPorts,
6126 			ioc->req_depth);
6127 
6128 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6129 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6130 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6131 			a[5], a[4], a[3], a[2], a[1], a[0]);
6132 	}
6133 
6134 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6135 
6136 	if (!ioc->active)
6137 		y += sprintf(buffer+len+y, " (disabled)");
6138 
6139 	y += sprintf(buffer+len+y, "\n");
6140 
6141 	*size = y;
6142 }
6143 
6144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6145 /*
6146  *	Reset Handling
6147  */
6148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6149 /**
6150  *	mpt_HardResetHandler - Generic reset handler
6151  *	@ioc: Pointer to MPT_ADAPTER structure
6152  *	@sleepFlag: Indicates if sleep or schedule must be called.
6153  *
6154  *	Issues SCSI Task Management call based on input arg values.
6155  *	If TaskMgmt fails, returns associated SCSI request.
6156  *
6157  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6158  *	or a non-interrupt thread.  In the former, must not call schedule().
6159  *
6160  *	Note: A return of -1 is a FATAL error case, as it means a
6161  *	FW reload/initialization failed.
6162  *
6163  *	Returns 0 for SUCCESS or -1 if FAILED.
6164  */
6165 int
6166 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6167 {
6168 	int		 rc;
6169 	unsigned long	 flags;
6170 
6171 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6172 #ifdef MFCNT
6173 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6174 	printk("MF count 0x%x !\n", ioc->mfcnt);
6175 #endif
6176 
6177 	/* Reset the adapter. Prevent more than 1 call to
6178 	 * mpt_do_ioc_recovery at any instant in time.
6179 	 */
6180 	spin_lock_irqsave(&ioc->diagLock, flags);
6181 	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6182 		spin_unlock_irqrestore(&ioc->diagLock, flags);
6183 		return 0;
6184 	} else {
6185 		ioc->diagPending = 1;
6186 	}
6187 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6188 
6189 	/* FIXME: If do_ioc_recovery fails, repeat....
6190 	 */
6191 
6192 	/* The SCSI driver needs to adjust timeouts on all current
6193 	 * commands prior to the diagnostic reset being issued.
6194 	 * Prevents timeouts occurring during a diagnostic reset...very bad.
6195 	 * For all other protocol drivers, this is a no-op.
6196 	 */
6197 	{
6198 		u8	 cb_idx;
6199 		int	 r = 0;
6200 
6201 		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6202 			if (MptResetHandlers[cb_idx]) {
6203 				dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6204 						ioc->name, cb_idx));
6205 				r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6206 				if (ioc->alt_ioc) {
6207 					dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6208 							ioc->name, ioc->alt_ioc->name, cb_idx));
6209 					r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6210 				}
6211 			}
6212 		}
6213 	}
6214 
6215 	if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6216 		printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6217 	}
6218 	ioc->reload_fw = 0;
6219 	if (ioc->alt_ioc)
6220 		ioc->alt_ioc->reload_fw = 0;
6221 
6222 	spin_lock_irqsave(&ioc->diagLock, flags);
6223 	ioc->diagPending = 0;
6224 	if (ioc->alt_ioc)
6225 		ioc->alt_ioc->diagPending = 0;
6226 	spin_unlock_irqrestore(&ioc->diagLock, flags);
6227 
6228 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6229 
6230 	return rc;
6231 }
6232 
6233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6234 static void
6235 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6236 {
6237 	char *ds = NULL;
6238 
6239 	switch(event) {
6240 	case MPI_EVENT_NONE:
6241 		ds = "None";
6242 		break;
6243 	case MPI_EVENT_LOG_DATA:
6244 		ds = "Log Data";
6245 		break;
6246 	case MPI_EVENT_STATE_CHANGE:
6247 		ds = "State Change";
6248 		break;
6249 	case MPI_EVENT_UNIT_ATTENTION:
6250 		ds = "Unit Attention";
6251 		break;
6252 	case MPI_EVENT_IOC_BUS_RESET:
6253 		ds = "IOC Bus Reset";
6254 		break;
6255 	case MPI_EVENT_EXT_BUS_RESET:
6256 		ds = "External Bus Reset";
6257 		break;
6258 	case MPI_EVENT_RESCAN:
6259 		ds = "Bus Rescan Event";
6260 		break;
6261 	case MPI_EVENT_LINK_STATUS_CHANGE:
6262 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6263 			ds = "Link Status(FAILURE) Change";
6264 		else
6265 			ds = "Link Status(ACTIVE) Change";
6266 		break;
6267 	case MPI_EVENT_LOOP_STATE_CHANGE:
6268 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6269 			ds = "Loop State(LIP) Change";
6270 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6271 			ds = "Loop State(LPE) Change";		/* ??? */
6272 		else
6273 			ds = "Loop State(LPB) Change";		/* ??? */
6274 		break;
6275 	case MPI_EVENT_LOGOUT:
6276 		ds = "Logout";
6277 		break;
6278 	case MPI_EVENT_EVENT_CHANGE:
6279 		if (evData0)
6280 			ds = "Events ON";
6281 		else
6282 			ds = "Events OFF";
6283 		break;
6284 	case MPI_EVENT_INTEGRATED_RAID:
6285 	{
6286 		u8 ReasonCode = (u8)(evData0 >> 16);
6287 		switch (ReasonCode) {
6288 		case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6289 			ds = "Integrated Raid: Volume Created";
6290 			break;
6291 		case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6292 			ds = "Integrated Raid: Volume Deleted";
6293 			break;
6294 		case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6295 			ds = "Integrated Raid: Volume Settings Changed";
6296 			break;
6297 		case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6298 			ds = "Integrated Raid: Volume Status Changed";
6299 			break;
6300 		case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6301 			ds = "Integrated Raid: Volume Physdisk Changed";
6302 			break;
6303 		case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6304 			ds = "Integrated Raid: Physdisk Created";
6305 			break;
6306 		case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6307 			ds = "Integrated Raid: Physdisk Deleted";
6308 			break;
6309 		case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6310 			ds = "Integrated Raid: Physdisk Settings Changed";
6311 			break;
6312 		case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6313 			ds = "Integrated Raid: Physdisk Status Changed";
6314 			break;
6315 		case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6316 			ds = "Integrated Raid: Domain Validation Needed";
6317 			break;
6318 		case MPI_EVENT_RAID_RC_SMART_DATA :
6319 			ds = "Integrated Raid; Smart Data";
6320 			break;
6321 		case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6322 			ds = "Integrated Raid: Replace Action Started";
6323 			break;
6324 		default:
6325 			ds = "Integrated Raid";
6326 		break;
6327 		}
6328 		break;
6329 	}
6330 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6331 		ds = "SCSI Device Status Change";
6332 		break;
6333 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6334 	{
6335 		u8 id = (u8)(evData0);
6336 		u8 channel = (u8)(evData0 >> 8);
6337 		u8 ReasonCode = (u8)(evData0 >> 16);
6338 		switch (ReasonCode) {
6339 		case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6340 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6341 			    "SAS Device Status Change: Added: "
6342 			    "id=%d channel=%d", id, channel);
6343 			break;
6344 		case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6345 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6346 			    "SAS Device Status Change: Deleted: "
6347 			    "id=%d channel=%d", id, channel);
6348 			break;
6349 		case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6350 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6351 			    "SAS Device Status Change: SMART Data: "
6352 			    "id=%d channel=%d", id, channel);
6353 			break;
6354 		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6355 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6356 			    "SAS Device Status Change: No Persistancy: "
6357 			    "id=%d channel=%d", id, channel);
6358 			break;
6359 		case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6360 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6361 			    "SAS Device Status Change: Unsupported Device "
6362 			    "Discovered : id=%d channel=%d", id, channel);
6363 			break;
6364 		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6365 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6366 			    "SAS Device Status Change: Internal Device "
6367 			    "Reset : id=%d channel=%d", id, channel);
6368 			break;
6369 		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6370 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6371 			    "SAS Device Status Change: Internal Task "
6372 			    "Abort : id=%d channel=%d", id, channel);
6373 			break;
6374 		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6375 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6376 			    "SAS Device Status Change: Internal Abort "
6377 			    "Task Set : id=%d channel=%d", id, channel);
6378 			break;
6379 		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6380 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6381 			    "SAS Device Status Change: Internal Clear "
6382 			    "Task Set : id=%d channel=%d", id, channel);
6383 			break;
6384 		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6385 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6386 			    "SAS Device Status Change: Internal Query "
6387 			    "Task : id=%d channel=%d", id, channel);
6388 			break;
6389 		default:
6390 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6391 			    "SAS Device Status Change: Unknown: "
6392 			    "id=%d channel=%d", id, channel);
6393 			break;
6394 		}
6395 		break;
6396 	}
6397 	case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6398 		ds = "Bus Timer Expired";
6399 		break;
6400 	case MPI_EVENT_QUEUE_FULL:
6401 	{
6402 		u16 curr_depth = (u16)(evData0 >> 16);
6403 		u8 channel = (u8)(evData0 >> 8);
6404 		u8 id = (u8)(evData0);
6405 
6406 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6407 		   "Queue Full: channel=%d id=%d depth=%d",
6408 		   channel, id, curr_depth);
6409 		break;
6410 	}
6411 	case MPI_EVENT_SAS_SES:
6412 		ds = "SAS SES Event";
6413 		break;
6414 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
6415 		ds = "Persistent Table Full";
6416 		break;
6417 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
6418 	{
6419 		u8 LinkRates = (u8)(evData0 >> 8);
6420 		u8 PhyNumber = (u8)(evData0);
6421 		LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6422 			MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6423 		switch (LinkRates) {
6424 		case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6425 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6426 			   "SAS PHY Link Status: Phy=%d:"
6427 			   " Rate Unknown",PhyNumber);
6428 			break;
6429 		case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6430 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6431 			   "SAS PHY Link Status: Phy=%d:"
6432 			   " Phy Disabled",PhyNumber);
6433 			break;
6434 		case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6435 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6436 			   "SAS PHY Link Status: Phy=%d:"
6437 			   " Failed Speed Nego",PhyNumber);
6438 			break;
6439 		case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6440 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6441 			   "SAS PHY Link Status: Phy=%d:"
6442 			   " Sata OOB Completed",PhyNumber);
6443 			break;
6444 		case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6445 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6446 			   "SAS PHY Link Status: Phy=%d:"
6447 			   " Rate 1.5 Gbps",PhyNumber);
6448 			break;
6449 		case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6450 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6451 			   "SAS PHY Link Status: Phy=%d:"
6452 			   " Rate 3.0 Gpbs",PhyNumber);
6453 			break;
6454 		default:
6455 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6456 			   "SAS PHY Link Status: Phy=%d", PhyNumber);
6457 			break;
6458 		}
6459 		break;
6460 	}
6461 	case MPI_EVENT_SAS_DISCOVERY_ERROR:
6462 		ds = "SAS Discovery Error";
6463 		break;
6464 	case MPI_EVENT_IR_RESYNC_UPDATE:
6465 	{
6466 		u8 resync_complete = (u8)(evData0 >> 16);
6467 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6468 		    "IR Resync Update: Complete = %d:",resync_complete);
6469 		break;
6470 	}
6471 	case MPI_EVENT_IR2:
6472 	{
6473 		u8 ReasonCode = (u8)(evData0 >> 16);
6474 		switch (ReasonCode) {
6475 		case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6476 			ds = "IR2: LD State Changed";
6477 			break;
6478 		case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6479 			ds = "IR2: PD State Changed";
6480 			break;
6481 		case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6482 			ds = "IR2: Bad Block Table Full";
6483 			break;
6484 		case MPI_EVENT_IR2_RC_PD_INSERTED:
6485 			ds = "IR2: PD Inserted";
6486 			break;
6487 		case MPI_EVENT_IR2_RC_PD_REMOVED:
6488 			ds = "IR2: PD Removed";
6489 			break;
6490 		case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6491 			ds = "IR2: Foreign CFG Detected";
6492 			break;
6493 		case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6494 			ds = "IR2: Rebuild Medium Error";
6495 			break;
6496 		default:
6497 			ds = "IR2";
6498 		break;
6499 		}
6500 		break;
6501 	}
6502 	case MPI_EVENT_SAS_DISCOVERY:
6503 	{
6504 		if (evData0)
6505 			ds = "SAS Discovery: Start";
6506 		else
6507 			ds = "SAS Discovery: Stop";
6508 		break;
6509 	}
6510 	case MPI_EVENT_LOG_ENTRY_ADDED:
6511 		ds = "SAS Log Entry Added";
6512 		break;
6513 
6514 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6515 	{
6516 		u8 phy_num = (u8)(evData0);
6517 		u8 port_num = (u8)(evData0 >> 8);
6518 		u8 port_width = (u8)(evData0 >> 16);
6519 		u8 primative = (u8)(evData0 >> 24);
6520 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6521 		    "SAS Broadcase Primative: phy=%d port=%d "
6522 		    "width=%d primative=0x%02x",
6523 		    phy_num, port_num, port_width, primative);
6524 		break;
6525 	}
6526 
6527 	case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6528 	{
6529 		u8 reason = (u8)(evData0);
6530 		u8 port_num = (u8)(evData0 >> 8);
6531 		u16 handle = le16_to_cpu(evData0 >> 16);
6532 
6533 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6534 		    "SAS Initiator Device Status Change: reason=0x%02x "
6535 		    "port=%d handle=0x%04x",
6536 		    reason, port_num, handle);
6537 		break;
6538 	}
6539 
6540 	case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6541 	{
6542 		u8 max_init = (u8)(evData0);
6543 		u8 current_init = (u8)(evData0 >> 8);
6544 
6545 		snprintf(evStr, EVENT_DESCR_STR_SZ,
6546 		    "SAS Initiator Device Table Overflow: max initiators=%02d "
6547 		    "current initators=%02d",
6548 		    max_init, current_init);
6549 		break;
6550 	}
6551 	case MPI_EVENT_SAS_SMP_ERROR:
6552 	{
6553 		u8 status = (u8)(evData0);
6554 		u8 port_num = (u8)(evData0 >> 8);
6555 		u8 result = (u8)(evData0 >> 16);
6556 
6557 		if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6558 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6559 			    "SAS SMP Error: port=%d result=0x%02x",
6560 			    port_num, result);
6561 		else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6562 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6563 			    "SAS SMP Error: port=%d : CRC Error",
6564 			    port_num);
6565 		else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6566 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6567 			    "SAS SMP Error: port=%d : Timeout",
6568 			    port_num);
6569 		else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6570 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6571 			    "SAS SMP Error: port=%d : No Destination",
6572 			    port_num);
6573 		else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6574 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6575 			    "SAS SMP Error: port=%d : Bad Destination",
6576 			    port_num);
6577 		else
6578 			snprintf(evStr, EVENT_DESCR_STR_SZ,
6579 			    "SAS SMP Error: port=%d : status=0x%02x",
6580 			    port_num, status);
6581 		break;
6582 	}
6583 
6584 	/*
6585 	 *  MPT base "custom" events may be added here...
6586 	 */
6587 	default:
6588 		ds = "Unknown";
6589 		break;
6590 	}
6591 	if (ds)
6592 		strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6593 }
6594 
6595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6596 /**
6597  *	ProcessEventNotification - Route EventNotificationReply to all event handlers
6598  *	@ioc: Pointer to MPT_ADAPTER structure
6599  *	@pEventReply: Pointer to EventNotification reply frame
6600  *	@evHandlers: Pointer to integer, number of event handlers
6601  *
6602  *	Routes a received EventNotificationReply to all currently registered
6603  *	event handlers.
6604  *	Returns sum of event handlers return values.
6605  */
6606 static int
6607 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6608 {
6609 	u16 evDataLen;
6610 	u32 evData0 = 0;
6611 //	u32 evCtx;
6612 	int ii;
6613 	u8 cb_idx;
6614 	int r = 0;
6615 	int handlers = 0;
6616 	char evStr[EVENT_DESCR_STR_SZ];
6617 	u8 event;
6618 
6619 	/*
6620 	 *  Do platform normalization of values
6621 	 */
6622 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
6623 //	evCtx = le32_to_cpu(pEventReply->EventContext);
6624 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6625 	if (evDataLen) {
6626 		evData0 = le32_to_cpu(pEventReply->Data[0]);
6627 	}
6628 
6629 	EventDescriptionStr(event, evData0, evStr);
6630 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6631 			ioc->name,
6632 			event,
6633 			evStr));
6634 
6635 #ifdef CONFIG_FUSION_LOGGING
6636 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6637 	    ": Event data:\n", ioc->name));
6638 	for (ii = 0; ii < evDataLen; ii++)
6639 		devtverboseprintk(ioc, printk(" %08x",
6640 		    le32_to_cpu(pEventReply->Data[ii])));
6641 	devtverboseprintk(ioc, printk("\n"));
6642 #endif
6643 
6644 	/*
6645 	 *  Do general / base driver event processing
6646 	 */
6647 	switch(event) {
6648 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
6649 		if (evDataLen) {
6650 			u8 evState = evData0 & 0xFF;
6651 
6652 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
6653 
6654 			/* Update EventState field in cached IocFacts */
6655 			if (ioc->facts.Function) {
6656 				ioc->facts.EventState = evState;
6657 			}
6658 		}
6659 		break;
6660 	case MPI_EVENT_INTEGRATED_RAID:
6661 		mptbase_raid_process_event_data(ioc,
6662 		    (MpiEventDataRaid_t *)pEventReply->Data);
6663 		break;
6664 	default:
6665 		break;
6666 	}
6667 
6668 	/*
6669 	 * Should this event be logged? Events are written sequentially.
6670 	 * When buffer is full, start again at the top.
6671 	 */
6672 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6673 		int idx;
6674 
6675 		idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6676 
6677 		ioc->events[idx].event = event;
6678 		ioc->events[idx].eventContext = ioc->eventContext;
6679 
6680 		for (ii = 0; ii < 2; ii++) {
6681 			if (ii < evDataLen)
6682 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6683 			else
6684 				ioc->events[idx].data[ii] =  0;
6685 		}
6686 
6687 		ioc->eventContext++;
6688 	}
6689 
6690 
6691 	/*
6692 	 *  Call each currently registered protocol event handler.
6693 	 */
6694 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6695 		if (MptEvHandlers[cb_idx]) {
6696 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6697 					ioc->name, cb_idx));
6698 			r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6699 			handlers++;
6700 		}
6701 	}
6702 	/* FIXME?  Examine results here? */
6703 
6704 	/*
6705 	 *  If needed, send (a single) EventAck.
6706 	 */
6707 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6708 		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6709 			"EventAck required\n",ioc->name));
6710 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6711 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6712 					ioc->name, ii));
6713 		}
6714 	}
6715 
6716 	*evHandlers = handlers;
6717 	return r;
6718 }
6719 
6720 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6721 /**
6722  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6723  *	@ioc: Pointer to MPT_ADAPTER structure
6724  *	@log_info: U32 LogInfo reply word from the IOC
6725  *
6726  *	Refer to lsi/mpi_log_fc.h.
6727  */
6728 static void
6729 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6730 {
6731 	char *desc = "unknown";
6732 
6733 	switch (log_info & 0xFF000000) {
6734 	case MPI_IOCLOGINFO_FC_INIT_BASE:
6735 		desc = "FCP Initiator";
6736 		break;
6737 	case MPI_IOCLOGINFO_FC_TARGET_BASE:
6738 		desc = "FCP Target";
6739 		break;
6740 	case MPI_IOCLOGINFO_FC_LAN_BASE:
6741 		desc = "LAN";
6742 		break;
6743 	case MPI_IOCLOGINFO_FC_MSG_BASE:
6744 		desc = "MPI Message Layer";
6745 		break;
6746 	case MPI_IOCLOGINFO_FC_LINK_BASE:
6747 		desc = "FC Link";
6748 		break;
6749 	case MPI_IOCLOGINFO_FC_CTX_BASE:
6750 		desc = "Context Manager";
6751 		break;
6752 	case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6753 		desc = "Invalid Field Offset";
6754 		break;
6755 	case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6756 		desc = "State Change Info";
6757 		break;
6758 	}
6759 
6760 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6761 			ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6762 }
6763 
6764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6765 /**
6766  *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6767  *	@ioc: Pointer to MPT_ADAPTER structure
6768  *	@mr: Pointer to MPT reply frame
6769  *	@log_info: U32 LogInfo word from the IOC
6770  *
6771  *	Refer to lsi/sp_log.h.
6772  */
6773 static void
6774 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6775 {
6776 	u32 info = log_info & 0x00FF0000;
6777 	char *desc = "unknown";
6778 
6779 	switch (info) {
6780 	case 0x00010000:
6781 		desc = "bug! MID not found";
6782 		if (ioc->reload_fw == 0)
6783 			ioc->reload_fw++;
6784 		break;
6785 
6786 	case 0x00020000:
6787 		desc = "Parity Error";
6788 		break;
6789 
6790 	case 0x00030000:
6791 		desc = "ASYNC Outbound Overrun";
6792 		break;
6793 
6794 	case 0x00040000:
6795 		desc = "SYNC Offset Error";
6796 		break;
6797 
6798 	case 0x00050000:
6799 		desc = "BM Change";
6800 		break;
6801 
6802 	case 0x00060000:
6803 		desc = "Msg In Overflow";
6804 		break;
6805 
6806 	case 0x00070000:
6807 		desc = "DMA Error";
6808 		break;
6809 
6810 	case 0x00080000:
6811 		desc = "Outbound DMA Overrun";
6812 		break;
6813 
6814 	case 0x00090000:
6815 		desc = "Task Management";
6816 		break;
6817 
6818 	case 0x000A0000:
6819 		desc = "Device Problem";
6820 		break;
6821 
6822 	case 0x000B0000:
6823 		desc = "Invalid Phase Change";
6824 		break;
6825 
6826 	case 0x000C0000:
6827 		desc = "Untagged Table Size";
6828 		break;
6829 
6830 	}
6831 
6832 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6833 }
6834 
6835 /* strings for sas loginfo */
6836 	static char *originator_str[] = {
6837 		"IOP",						/* 00h */
6838 		"PL",						/* 01h */
6839 		"IR"						/* 02h */
6840 	};
6841 	static char *iop_code_str[] = {
6842 		NULL,						/* 00h */
6843 		"Invalid SAS Address",				/* 01h */
6844 		NULL,						/* 02h */
6845 		"Invalid Page",					/* 03h */
6846 		"Diag Message Error",				/* 04h */
6847 		"Task Terminated",				/* 05h */
6848 		"Enclosure Management",				/* 06h */
6849 		"Target Mode"					/* 07h */
6850 	};
6851 	static char *pl_code_str[] = {
6852 		NULL,						/* 00h */
6853 		"Open Failure",					/* 01h */
6854 		"Invalid Scatter Gather List",			/* 02h */
6855 		"Wrong Relative Offset or Frame Length",	/* 03h */
6856 		"Frame Transfer Error",				/* 04h */
6857 		"Transmit Frame Connected Low",			/* 05h */
6858 		"SATA Non-NCQ RW Error Bit Set",		/* 06h */
6859 		"SATA Read Log Receive Data Error",		/* 07h */
6860 		"SATA NCQ Fail All Commands After Error",	/* 08h */
6861 		"SATA Error in Receive Set Device Bit FIS",	/* 09h */
6862 		"Receive Frame Invalid Message",		/* 0Ah */
6863 		"Receive Context Message Valid Error",		/* 0Bh */
6864 		"Receive Frame Current Frame Error",		/* 0Ch */
6865 		"SATA Link Down",				/* 0Dh */
6866 		"Discovery SATA Init W IOS",			/* 0Eh */
6867 		"Config Invalid Page",				/* 0Fh */
6868 		"Discovery SATA Init Timeout",			/* 10h */
6869 		"Reset",					/* 11h */
6870 		"Abort",					/* 12h */
6871 		"IO Not Yet Executed",				/* 13h */
6872 		"IO Executed",					/* 14h */
6873 		"Persistent Reservation Out Not Affiliation "
6874 		    "Owner", 					/* 15h */
6875 		"Open Transmit DMA Abort",			/* 16h */
6876 		"IO Device Missing Delay Retry",		/* 17h */
6877 		"IO Cancelled Due to Recieve Error",		/* 18h */
6878 		NULL,						/* 19h */
6879 		NULL,						/* 1Ah */
6880 		NULL,						/* 1Bh */
6881 		NULL,						/* 1Ch */
6882 		NULL,						/* 1Dh */
6883 		NULL,						/* 1Eh */
6884 		NULL,						/* 1Fh */
6885 		"Enclosure Management"				/* 20h */
6886 	};
6887 	static char *ir_code_str[] = {
6888 		"Raid Action Error",				/* 00h */
6889 		NULL,						/* 00h */
6890 		NULL,						/* 01h */
6891 		NULL,						/* 02h */
6892 		NULL,						/* 03h */
6893 		NULL,						/* 04h */
6894 		NULL,						/* 05h */
6895 		NULL,						/* 06h */
6896 		NULL						/* 07h */
6897 	};
6898 	static char *raid_sub_code_str[] = {
6899 		NULL, 						/* 00h */
6900 		"Volume Creation Failed: Data Passed too "
6901 		    "Large", 					/* 01h */
6902 		"Volume Creation Failed: Duplicate Volumes "
6903 		    "Attempted", 				/* 02h */
6904 		"Volume Creation Failed: Max Number "
6905 		    "Supported Volumes Exceeded",		/* 03h */
6906 		"Volume Creation Failed: DMA Error",		/* 04h */
6907 		"Volume Creation Failed: Invalid Volume Type",	/* 05h */
6908 		"Volume Creation Failed: Error Reading "
6909 		    "MFG Page 4", 				/* 06h */
6910 		"Volume Creation Failed: Creating Internal "
6911 		    "Structures", 				/* 07h */
6912 		NULL,						/* 08h */
6913 		NULL,						/* 09h */
6914 		NULL,						/* 0Ah */
6915 		NULL,						/* 0Bh */
6916 		NULL,						/* 0Ch */
6917 		NULL,						/* 0Dh */
6918 		NULL,						/* 0Eh */
6919 		NULL,						/* 0Fh */
6920 		"Activation failed: Already Active Volume", 	/* 10h */
6921 		"Activation failed: Unsupported Volume Type", 	/* 11h */
6922 		"Activation failed: Too Many Active Volumes", 	/* 12h */
6923 		"Activation failed: Volume ID in Use", 		/* 13h */
6924 		"Activation failed: Reported Failure", 		/* 14h */
6925 		"Activation failed: Importing a Volume", 	/* 15h */
6926 		NULL,						/* 16h */
6927 		NULL,						/* 17h */
6928 		NULL,						/* 18h */
6929 		NULL,						/* 19h */
6930 		NULL,						/* 1Ah */
6931 		NULL,						/* 1Bh */
6932 		NULL,						/* 1Ch */
6933 		NULL,						/* 1Dh */
6934 		NULL,						/* 1Eh */
6935 		NULL,						/* 1Fh */
6936 		"Phys Disk failed: Too Many Phys Disks", 	/* 20h */
6937 		"Phys Disk failed: Data Passed too Large",	/* 21h */
6938 		"Phys Disk failed: DMA Error", 			/* 22h */
6939 		"Phys Disk failed: Invalid <channel:id>", 	/* 23h */
6940 		"Phys Disk failed: Creating Phys Disk Config "
6941 		    "Page", 					/* 24h */
6942 		NULL,						/* 25h */
6943 		NULL,						/* 26h */
6944 		NULL,						/* 27h */
6945 		NULL,						/* 28h */
6946 		NULL,						/* 29h */
6947 		NULL,						/* 2Ah */
6948 		NULL,						/* 2Bh */
6949 		NULL,						/* 2Ch */
6950 		NULL,						/* 2Dh */
6951 		NULL,						/* 2Eh */
6952 		NULL,						/* 2Fh */
6953 		"Compatibility Error: IR Disabled",		/* 30h */
6954 		"Compatibility Error: Inquiry Comand Failed",	/* 31h */
6955 		"Compatibility Error: Device not Direct Access "
6956 		    "Device ",					/* 32h */
6957 		"Compatibility Error: Removable Device Found",	/* 33h */
6958 		"Compatibility Error: Device SCSI Version not "
6959 		    "2 or Higher", 				/* 34h */
6960 		"Compatibility Error: SATA Device, 48 BIT LBA "
6961 		    "not Supported", 				/* 35h */
6962 		"Compatibility Error: Device doesn't have "
6963 		    "512 Byte Block Sizes", 			/* 36h */
6964 		"Compatibility Error: Volume Type Check Failed", /* 37h */
6965 		"Compatibility Error: Volume Type is "
6966 		    "Unsupported by FW", 			/* 38h */
6967 		"Compatibility Error: Disk Drive too Small for "
6968 		    "use in Volume", 				/* 39h */
6969 		"Compatibility Error: Phys Disk for Create "
6970 		    "Volume not Found", 			/* 3Ah */
6971 		"Compatibility Error: Too Many or too Few "
6972 		    "Disks for Volume Type", 			/* 3Bh */
6973 		"Compatibility Error: Disk stripe Sizes "
6974 		    "Must be 64KB", 				/* 3Ch */
6975 		"Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6976 	};
6977 
6978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6979 /**
6980  *	mpt_sas_log_info - Log information returned from SAS IOC.
6981  *	@ioc: Pointer to MPT_ADAPTER structure
6982  *	@log_info: U32 LogInfo reply word from the IOC
6983  *
6984  *	Refer to lsi/mpi_log_sas.h.
6985  **/
6986 static void
6987 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6988 {
6989 union loginfo_type {
6990 	u32	loginfo;
6991 	struct {
6992 		u32	subcode:16;
6993 		u32	code:8;
6994 		u32	originator:4;
6995 		u32	bus_type:4;
6996 	}dw;
6997 };
6998 	union loginfo_type sas_loginfo;
6999 	char *originator_desc = NULL;
7000 	char *code_desc = NULL;
7001 	char *sub_code_desc = NULL;
7002 
7003 	sas_loginfo.loginfo = log_info;
7004 	if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7005 	    (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7006 		return;
7007 
7008 	originator_desc = originator_str[sas_loginfo.dw.originator];
7009 
7010 	switch (sas_loginfo.dw.originator) {
7011 
7012 		case 0:  /* IOP */
7013 			if (sas_loginfo.dw.code <
7014 			    sizeof(iop_code_str)/sizeof(char*))
7015 				code_desc = iop_code_str[sas_loginfo.dw.code];
7016 			break;
7017 		case 1:  /* PL */
7018 			if (sas_loginfo.dw.code <
7019 			    sizeof(pl_code_str)/sizeof(char*))
7020 				code_desc = pl_code_str[sas_loginfo.dw.code];
7021 			break;
7022 		case 2:  /* IR */
7023 			if (sas_loginfo.dw.code >=
7024 			    sizeof(ir_code_str)/sizeof(char*))
7025 				break;
7026 			code_desc = ir_code_str[sas_loginfo.dw.code];
7027 			if (sas_loginfo.dw.subcode >=
7028 			    sizeof(raid_sub_code_str)/sizeof(char*))
7029 			break;
7030 			if (sas_loginfo.dw.code == 0)
7031 				sub_code_desc =
7032 				    raid_sub_code_str[sas_loginfo.dw.subcode];
7033 			break;
7034 		default:
7035 			return;
7036 	}
7037 
7038 	if (sub_code_desc != NULL)
7039 		printk(MYIOC_s_INFO_FMT
7040 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
7041 			" SubCode={%s}\n",
7042 			ioc->name, log_info, originator_desc, code_desc,
7043 			sub_code_desc);
7044 	else if (code_desc != NULL)
7045 		printk(MYIOC_s_INFO_FMT
7046 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
7047 			" SubCode(0x%04x)\n",
7048 			ioc->name, log_info, originator_desc, code_desc,
7049 			sas_loginfo.dw.subcode);
7050 	else
7051 		printk(MYIOC_s_INFO_FMT
7052 			"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7053 			" SubCode(0x%04x)\n",
7054 			ioc->name, log_info, originator_desc,
7055 			sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7056 }
7057 
7058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7059 /**
7060  *	mpt_iocstatus_info_config - IOCSTATUS information for config pages
7061  *	@ioc: Pointer to MPT_ADAPTER structure
7062  *	@ioc_status: U32 IOCStatus word from IOC
7063  *	@mf: Pointer to MPT request frame
7064  *
7065  *	Refer to lsi/mpi.h.
7066  **/
7067 static void
7068 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7069 {
7070 	Config_t *pReq = (Config_t *)mf;
7071 	char extend_desc[EVENT_DESCR_STR_SZ];
7072 	char *desc = NULL;
7073 	u32 form;
7074 	u8 page_type;
7075 
7076 	if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7077 		page_type = pReq->ExtPageType;
7078 	else
7079 		page_type = pReq->Header.PageType;
7080 
7081 	/*
7082 	 * ignore invalid page messages for GET_NEXT_HANDLE
7083 	 */
7084 	form = le32_to_cpu(pReq->PageAddress);
7085 	if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7086 		if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7087 		    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7088 		    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7089 			if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7090 				MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7091 				return;
7092 		}
7093 		if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7094 			if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7095 				MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7096 				return;
7097 	}
7098 
7099 	snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7100 	    "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7101 	    page_type, pReq->Header.PageNumber, pReq->Action, form);
7102 
7103 	switch (ioc_status) {
7104 
7105 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7106 		desc = "Config Page Invalid Action";
7107 		break;
7108 
7109 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
7110 		desc = "Config Page Invalid Type";
7111 		break;
7112 
7113 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
7114 		desc = "Config Page Invalid Page";
7115 		break;
7116 
7117 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
7118 		desc = "Config Page Invalid Data";
7119 		break;
7120 
7121 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7122 		desc = "Config Page No Defaults";
7123 		break;
7124 
7125 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7126 		desc = "Config Page Can't Commit";
7127 		break;
7128 	}
7129 
7130 	if (!desc)
7131 		return;
7132 
7133 	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7134 	    ioc->name, ioc_status, desc, extend_desc));
7135 }
7136 
7137 /**
7138  *	mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7139  *	@ioc: Pointer to MPT_ADAPTER structure
7140  *	@ioc_status: U32 IOCStatus word from IOC
7141  *	@mf: Pointer to MPT request frame
7142  *
7143  *	Refer to lsi/mpi.h.
7144  **/
7145 static void
7146 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7147 {
7148 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7149 	char *desc = NULL;
7150 
7151 	switch (status) {
7152 
7153 /****************************************************************************/
7154 /*  Common IOCStatus values for all replies                                 */
7155 /****************************************************************************/
7156 
7157 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7158 		desc = "Invalid Function";
7159 		break;
7160 
7161 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7162 		desc = "Busy";
7163 		break;
7164 
7165 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7166 		desc = "Invalid SGL";
7167 		break;
7168 
7169 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7170 		desc = "Internal Error";
7171 		break;
7172 
7173 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7174 		desc = "Reserved";
7175 		break;
7176 
7177 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7178 		desc = "Insufficient Resources";
7179 		break;
7180 
7181 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7182 		desc = "Invalid Field";
7183 		break;
7184 
7185 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7186 		desc = "Invalid State";
7187 		break;
7188 
7189 /****************************************************************************/
7190 /*  Config IOCStatus values                                                 */
7191 /****************************************************************************/
7192 
7193 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7194 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
7195 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
7196 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
7197 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
7198 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
7199 		mpt_iocstatus_info_config(ioc, status, mf);
7200 		break;
7201 
7202 /****************************************************************************/
7203 /*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
7204 /*                                                                          */
7205 /*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7206 /*                                                                          */
7207 /****************************************************************************/
7208 
7209 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7210 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7211 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7212 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7213 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7214 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7215 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7216 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7217 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7218 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7219 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7220 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7221 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7222 		break;
7223 
7224 /****************************************************************************/
7225 /*  SCSI Target values                                                      */
7226 /****************************************************************************/
7227 
7228 	case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7229 		desc = "Target: Priority IO";
7230 		break;
7231 
7232 	case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7233 		desc = "Target: Invalid Port";
7234 		break;
7235 
7236 	case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7237 		desc = "Target Invalid IO Index:";
7238 		break;
7239 
7240 	case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7241 		desc = "Target: Aborted";
7242 		break;
7243 
7244 	case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7245 		desc = "Target: No Conn Retryable";
7246 		break;
7247 
7248 	case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7249 		desc = "Target: No Connection";
7250 		break;
7251 
7252 	case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7253 		desc = "Target: Transfer Count Mismatch";
7254 		break;
7255 
7256 	case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7257 		desc = "Target: STS Data not Sent";
7258 		break;
7259 
7260 	case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7261 		desc = "Target: Data Offset Error";
7262 		break;
7263 
7264 	case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7265 		desc = "Target: Too Much Write Data";
7266 		break;
7267 
7268 	case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7269 		desc = "Target: IU Too Short";
7270 		break;
7271 
7272 	case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7273 		desc = "Target: ACK NAK Timeout";
7274 		break;
7275 
7276 	case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7277 		desc = "Target: Nak Received";
7278 		break;
7279 
7280 /****************************************************************************/
7281 /*  Fibre Channel Direct Access values                                      */
7282 /****************************************************************************/
7283 
7284 	case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7285 		desc = "FC: Aborted";
7286 		break;
7287 
7288 	case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7289 		desc = "FC: RX ID Invalid";
7290 		break;
7291 
7292 	case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7293 		desc = "FC: DID Invalid";
7294 		break;
7295 
7296 	case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7297 		desc = "FC: Node Logged Out";
7298 		break;
7299 
7300 	case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7301 		desc = "FC: Exchange Canceled";
7302 		break;
7303 
7304 /****************************************************************************/
7305 /*  LAN values                                                              */
7306 /****************************************************************************/
7307 
7308 	case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7309 		desc = "LAN: Device not Found";
7310 		break;
7311 
7312 	case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7313 		desc = "LAN: Device Failure";
7314 		break;
7315 
7316 	case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7317 		desc = "LAN: Transmit Error";
7318 		break;
7319 
7320 	case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7321 		desc = "LAN: Transmit Aborted";
7322 		break;
7323 
7324 	case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7325 		desc = "LAN: Receive Error";
7326 		break;
7327 
7328 	case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7329 		desc = "LAN: Receive Aborted";
7330 		break;
7331 
7332 	case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7333 		desc = "LAN: Partial Packet";
7334 		break;
7335 
7336 	case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7337 		desc = "LAN: Canceled";
7338 		break;
7339 
7340 /****************************************************************************/
7341 /*  Serial Attached SCSI values                                             */
7342 /****************************************************************************/
7343 
7344 	case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7345 		desc = "SAS: SMP Request Failed";
7346 		break;
7347 
7348 	case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7349 		desc = "SAS: SMP Data Overrun";
7350 		break;
7351 
7352 	default:
7353 		desc = "Others";
7354 		break;
7355 	}
7356 
7357 	if (!desc)
7358 		return;
7359 
7360 	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7361 	    ioc->name, status, desc));
7362 }
7363 
7364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7365 EXPORT_SYMBOL(mpt_attach);
7366 EXPORT_SYMBOL(mpt_detach);
7367 #ifdef CONFIG_PM
7368 EXPORT_SYMBOL(mpt_resume);
7369 EXPORT_SYMBOL(mpt_suspend);
7370 #endif
7371 EXPORT_SYMBOL(ioc_list);
7372 EXPORT_SYMBOL(mpt_proc_root_dir);
7373 EXPORT_SYMBOL(mpt_register);
7374 EXPORT_SYMBOL(mpt_deregister);
7375 EXPORT_SYMBOL(mpt_event_register);
7376 EXPORT_SYMBOL(mpt_event_deregister);
7377 EXPORT_SYMBOL(mpt_reset_register);
7378 EXPORT_SYMBOL(mpt_reset_deregister);
7379 EXPORT_SYMBOL(mpt_device_driver_register);
7380 EXPORT_SYMBOL(mpt_device_driver_deregister);
7381 EXPORT_SYMBOL(mpt_get_msg_frame);
7382 EXPORT_SYMBOL(mpt_put_msg_frame);
7383 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7384 EXPORT_SYMBOL(mpt_free_msg_frame);
7385 EXPORT_SYMBOL(mpt_add_sge);
7386 EXPORT_SYMBOL(mpt_send_handshake_request);
7387 EXPORT_SYMBOL(mpt_verify_adapter);
7388 EXPORT_SYMBOL(mpt_GetIocState);
7389 EXPORT_SYMBOL(mpt_print_ioc_summary);
7390 EXPORT_SYMBOL(mpt_HardResetHandler);
7391 EXPORT_SYMBOL(mpt_config);
7392 EXPORT_SYMBOL(mpt_findImVolumes);
7393 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7394 EXPORT_SYMBOL(mpt_free_fw_memory);
7395 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7396 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7397 
7398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7399 /**
7400  *	fusion_init - Fusion MPT base driver initialization routine.
7401  *
7402  *	Returns 0 for success, non-zero for failure.
7403  */
7404 static int __init
7405 fusion_init(void)
7406 {
7407 	u8 cb_idx;
7408 
7409 	show_mptmod_ver(my_NAME, my_VERSION);
7410 	printk(KERN_INFO COPYRIGHT "\n");
7411 
7412 	for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7413 		MptCallbacks[cb_idx] = NULL;
7414 		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7415 		MptEvHandlers[cb_idx] = NULL;
7416 		MptResetHandlers[cb_idx] = NULL;
7417 	}
7418 
7419 	/*  Register ourselves (mptbase) in order to facilitate
7420 	 *  EventNotification handling.
7421 	 */
7422 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7423 
7424 	/* Register for hard reset handling callbacks.
7425 	 */
7426 	mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7427 
7428 #ifdef CONFIG_PROC_FS
7429 	(void) procmpt_create();
7430 #endif
7431 	return 0;
7432 }
7433 
7434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7435 /**
7436  *	fusion_exit - Perform driver unload cleanup.
7437  *
7438  *	This routine frees all resources associated with each MPT adapter
7439  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
7440  */
7441 static void __exit
7442 fusion_exit(void)
7443 {
7444 
7445 	mpt_reset_deregister(mpt_base_index);
7446 
7447 #ifdef CONFIG_PROC_FS
7448 	procmpt_destroy();
7449 #endif
7450 }
7451 
7452 module_init(fusion_init);
7453 module_exit(fusion_exit);
7454