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