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