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