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