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