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