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