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