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