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