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