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