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