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