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