xref: /linux/drivers/message/fusion/mptbase.c (revision 98838d95075a5295f3478ceba18bcccf472e30f4)
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, 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 const struct file_operations mpt_summary_proc_fops;
201 static const struct file_operations mpt_version_proc_fops;
202 static const struct file_operations mpt_iocinfo_proc_fops;
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, 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 		pChain->Length = cpu_to_le16(length);
1133 		pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1134 		pChain->NextChainOffset = next;
1135 		pChain->Address = cpu_to_le32(dma_addr);
1136 }
1137 
1138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1139 /**
1140  *	mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1141  *	@pAddr: virtual address for SGE
1142  *	@next: nextChainOffset value (u32's)
1143  *	@length: length of next SGL segment
1144  *	@dma_addr: Physical address
1145  *
1146  */
1147 static void
1148 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1149 {
1150 		SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1151 		u32 tmp = dma_addr & 0xFFFFFFFF;
1152 
1153 		pChain->Length = cpu_to_le16(length);
1154 		pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1155 				 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1156 
1157 		pChain->NextChainOffset = next;
1158 
1159 		pChain->Address.Low = cpu_to_le32(tmp);
1160 		tmp = (u32)(upper_32_bits(dma_addr));
1161 		pChain->Address.High = cpu_to_le32(tmp);
1162 }
1163 
1164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1165 /**
1166  *	mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1167  *	@cb_idx: Handle of registered MPT protocol driver
1168  *	@ioc: Pointer to MPT adapter structure
1169  *	@reqBytes: Size of the request in bytes
1170  *	@req: Pointer to MPT request frame
1171  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1172  *
1173  *	This routine is used exclusively to send MptScsiTaskMgmt
1174  *	requests since they are required to be sent via doorbell handshake.
1175  *
1176  *	NOTE: It is the callers responsibility to byte-swap fields in the
1177  *	request which are greater than 1 byte in size.
1178  *
1179  *	Returns 0 for success, non-zero for failure.
1180  */
1181 int
1182 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1183 {
1184 	int	r = 0;
1185 	u8	*req_as_bytes;
1186 	int	 ii;
1187 
1188 	/* State is known to be good upon entering
1189 	 * this function so issue the bus reset
1190 	 * request.
1191 	 */
1192 
1193 	/*
1194 	 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1195 	 * setting cb_idx/req_idx.  But ONLY if this request
1196 	 * is in proper (pre-alloc'd) request buffer range...
1197 	 */
1198 	ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1199 	if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1200 		MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1201 		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1202 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1203 	}
1204 
1205 	/* Make sure there are no doorbells */
1206 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1207 
1208 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1209 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1210 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1211 
1212 	/* Wait for IOC doorbell int */
1213 	if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1214 		return ii;
1215 	}
1216 
1217 	/* Read doorbell and check for active bit */
1218 	if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1219 		return -5;
1220 
1221 	dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1222 		ioc->name, ii));
1223 
1224 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1225 
1226 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1227 		return -2;
1228 	}
1229 
1230 	/* Send request via doorbell handshake */
1231 	req_as_bytes = (u8 *) req;
1232 	for (ii = 0; ii < reqBytes/4; ii++) {
1233 		u32 word;
1234 
1235 		word = ((req_as_bytes[(ii*4) + 0] <<  0) |
1236 			(req_as_bytes[(ii*4) + 1] <<  8) |
1237 			(req_as_bytes[(ii*4) + 2] << 16) |
1238 			(req_as_bytes[(ii*4) + 3] << 24));
1239 		CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1240 		if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1241 			r = -3;
1242 			break;
1243 		}
1244 	}
1245 
1246 	if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1247 		r = 0;
1248 	else
1249 		r = -4;
1250 
1251 	/* Make sure there are no doorbells */
1252 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1253 
1254 	return r;
1255 }
1256 
1257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1258 /**
1259  * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1260  * @ioc: Pointer to MPT adapter structure
1261  * @access_control_value: define bits below
1262  * @sleepFlag: Specifies whether the process can sleep
1263  *
1264  * Provides mechanism for the host driver to control the IOC's
1265  * Host Page Buffer access.
1266  *
1267  * Access Control Value - bits[15:12]
1268  * 0h Reserved
1269  * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1270  * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1271  * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1272  *
1273  * Returns 0 for success, non-zero for failure.
1274  */
1275 
1276 static int
1277 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1278 {
1279 	int	 r = 0;
1280 
1281 	/* return if in use */
1282 	if (CHIPREG_READ32(&ioc->chip->Doorbell)
1283 	    & MPI_DOORBELL_ACTIVE)
1284 	    return -1;
1285 
1286 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1287 
1288 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
1289 		((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1290 		 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1291 		 (access_control_value<<12)));
1292 
1293 	/* Wait for IOC to clear Doorbell Status bit */
1294 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1295 		return -2;
1296 	}else
1297 		return 0;
1298 }
1299 
1300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1301 /**
1302  *	mpt_host_page_alloc - allocate system memory for the fw
1303  *	@ioc: Pointer to pointer to IOC adapter
1304  *	@ioc_init: Pointer to ioc init config page
1305  *
1306  *	If we already allocated memory in past, then resend the same pointer.
1307  *	Returns 0 for success, non-zero for failure.
1308  */
1309 static int
1310 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1311 {
1312 	char	*psge;
1313 	int	flags_length;
1314 	u32	host_page_buffer_sz=0;
1315 
1316 	if(!ioc->HostPageBuffer) {
1317 
1318 		host_page_buffer_sz =
1319 		    le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1320 
1321 		if(!host_page_buffer_sz)
1322 			return 0; /* fw doesn't need any host buffers */
1323 
1324 		/* spin till we get enough memory */
1325 		while(host_page_buffer_sz > 0) {
1326 
1327 			if((ioc->HostPageBuffer = pci_alloc_consistent(
1328 			    ioc->pcidev,
1329 			    host_page_buffer_sz,
1330 			    &ioc->HostPageBuffer_dma)) != NULL) {
1331 
1332 				dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1333 				    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1334 				    ioc->name, ioc->HostPageBuffer,
1335 				    (u32)ioc->HostPageBuffer_dma,
1336 				    host_page_buffer_sz));
1337 				ioc->alloc_total += host_page_buffer_sz;
1338 				ioc->HostPageBuffer_sz = host_page_buffer_sz;
1339 				break;
1340 			}
1341 
1342 			host_page_buffer_sz -= (4*1024);
1343 		}
1344 	}
1345 
1346 	if(!ioc->HostPageBuffer) {
1347 		printk(MYIOC_s_ERR_FMT
1348 		    "Failed to alloc memory for host_page_buffer!\n",
1349 		    ioc->name);
1350 		return -999;
1351 	}
1352 
1353 	psge = (char *)&ioc_init->HostPageBufferSGE;
1354 	flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1355 	    MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1356 	    MPI_SGE_FLAGS_HOST_TO_IOC |
1357 	    MPI_SGE_FLAGS_END_OF_BUFFER;
1358 	flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1359 	flags_length |= ioc->HostPageBuffer_sz;
1360 	ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1361 	ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1362 
1363 return 0;
1364 }
1365 
1366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1367 /**
1368  *	mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1369  *	@iocid: IOC unique identifier (integer)
1370  *	@iocpp: Pointer to pointer to IOC adapter
1371  *
1372  *	Given a unique IOC identifier, set pointer to the associated MPT
1373  *	adapter structure.
1374  *
1375  *	Returns iocid and sets iocpp if iocid is found.
1376  *	Returns -1 if iocid is not found.
1377  */
1378 int
1379 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1380 {
1381 	MPT_ADAPTER *ioc;
1382 
1383 	list_for_each_entry(ioc,&ioc_list,list) {
1384 		if (ioc->id == iocid) {
1385 			*iocpp =ioc;
1386 			return iocid;
1387 		}
1388 	}
1389 
1390 	*iocpp = NULL;
1391 	return -1;
1392 }
1393 
1394 /**
1395  *	mpt_get_product_name - returns product string
1396  *	@vendor: pci vendor id
1397  *	@device: pci device id
1398  *	@revision: pci revision id
1399  *
1400  *	Returns product string displayed when driver loads,
1401  *	in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1402  *
1403  **/
1404 static const char*
1405 mpt_get_product_name(u16 vendor, u16 device, u8 revision)
1406 {
1407 	char *product_str = NULL;
1408 
1409 	if (vendor == PCI_VENDOR_ID_BROCADE) {
1410 		switch (device)
1411 		{
1412 		case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1413 			switch (revision)
1414 			{
1415 			case 0x00:
1416 				product_str = "BRE040 A0";
1417 				break;
1418 			case 0x01:
1419 				product_str = "BRE040 A1";
1420 				break;
1421 			default:
1422 				product_str = "BRE040";
1423 				break;
1424 			}
1425 			break;
1426 		}
1427 		goto out;
1428 	}
1429 
1430 	switch (device)
1431 	{
1432 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1433 		product_str = "LSIFC909 B1";
1434 		break;
1435 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1436 		product_str = "LSIFC919 B0";
1437 		break;
1438 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1439 		product_str = "LSIFC929 B0";
1440 		break;
1441 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1442 		if (revision < 0x80)
1443 			product_str = "LSIFC919X A0";
1444 		else
1445 			product_str = "LSIFC919XL A1";
1446 		break;
1447 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1448 		if (revision < 0x80)
1449 			product_str = "LSIFC929X A0";
1450 		else
1451 			product_str = "LSIFC929XL A1";
1452 		break;
1453 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1454 		product_str = "LSIFC939X A1";
1455 		break;
1456 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1457 		product_str = "LSIFC949X A1";
1458 		break;
1459 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1460 		switch (revision)
1461 		{
1462 		case 0x00:
1463 			product_str = "LSIFC949E A0";
1464 			break;
1465 		case 0x01:
1466 			product_str = "LSIFC949E A1";
1467 			break;
1468 		default:
1469 			product_str = "LSIFC949E";
1470 			break;
1471 		}
1472 		break;
1473 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1474 		switch (revision)
1475 		{
1476 		case 0x00:
1477 			product_str = "LSI53C1030 A0";
1478 			break;
1479 		case 0x01:
1480 			product_str = "LSI53C1030 B0";
1481 			break;
1482 		case 0x03:
1483 			product_str = "LSI53C1030 B1";
1484 			break;
1485 		case 0x07:
1486 			product_str = "LSI53C1030 B2";
1487 			break;
1488 		case 0x08:
1489 			product_str = "LSI53C1030 C0";
1490 			break;
1491 		case 0x80:
1492 			product_str = "LSI53C1030T A0";
1493 			break;
1494 		case 0x83:
1495 			product_str = "LSI53C1030T A2";
1496 			break;
1497 		case 0x87:
1498 			product_str = "LSI53C1030T A3";
1499 			break;
1500 		case 0xc1:
1501 			product_str = "LSI53C1020A A1";
1502 			break;
1503 		default:
1504 			product_str = "LSI53C1030";
1505 			break;
1506 		}
1507 		break;
1508 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1509 		switch (revision)
1510 		{
1511 		case 0x03:
1512 			product_str = "LSI53C1035 A2";
1513 			break;
1514 		case 0x04:
1515 			product_str = "LSI53C1035 B0";
1516 			break;
1517 		default:
1518 			product_str = "LSI53C1035";
1519 			break;
1520 		}
1521 		break;
1522 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1523 		switch (revision)
1524 		{
1525 		case 0x00:
1526 			product_str = "LSISAS1064 A1";
1527 			break;
1528 		case 0x01:
1529 			product_str = "LSISAS1064 A2";
1530 			break;
1531 		case 0x02:
1532 			product_str = "LSISAS1064 A3";
1533 			break;
1534 		case 0x03:
1535 			product_str = "LSISAS1064 A4";
1536 			break;
1537 		default:
1538 			product_str = "LSISAS1064";
1539 			break;
1540 		}
1541 		break;
1542 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1543 		switch (revision)
1544 		{
1545 		case 0x00:
1546 			product_str = "LSISAS1064E A0";
1547 			break;
1548 		case 0x01:
1549 			product_str = "LSISAS1064E B0";
1550 			break;
1551 		case 0x02:
1552 			product_str = "LSISAS1064E B1";
1553 			break;
1554 		case 0x04:
1555 			product_str = "LSISAS1064E B2";
1556 			break;
1557 		case 0x08:
1558 			product_str = "LSISAS1064E B3";
1559 			break;
1560 		default:
1561 			product_str = "LSISAS1064E";
1562 			break;
1563 		}
1564 		break;
1565 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1566 		switch (revision)
1567 		{
1568 		case 0x00:
1569 			product_str = "LSISAS1068 A0";
1570 			break;
1571 		case 0x01:
1572 			product_str = "LSISAS1068 B0";
1573 			break;
1574 		case 0x02:
1575 			product_str = "LSISAS1068 B1";
1576 			break;
1577 		default:
1578 			product_str = "LSISAS1068";
1579 			break;
1580 		}
1581 		break;
1582 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1583 		switch (revision)
1584 		{
1585 		case 0x00:
1586 			product_str = "LSISAS1068E A0";
1587 			break;
1588 		case 0x01:
1589 			product_str = "LSISAS1068E B0";
1590 			break;
1591 		case 0x02:
1592 			product_str = "LSISAS1068E B1";
1593 			break;
1594 		case 0x04:
1595 			product_str = "LSISAS1068E B2";
1596 			break;
1597 		case 0x08:
1598 			product_str = "LSISAS1068E B3";
1599 			break;
1600 		default:
1601 			product_str = "LSISAS1068E";
1602 			break;
1603 		}
1604 		break;
1605 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1606 		switch (revision)
1607 		{
1608 		case 0x00:
1609 			product_str = "LSISAS1078 A0";
1610 			break;
1611 		case 0x01:
1612 			product_str = "LSISAS1078 B0";
1613 			break;
1614 		case 0x02:
1615 			product_str = "LSISAS1078 C0";
1616 			break;
1617 		case 0x03:
1618 			product_str = "LSISAS1078 C1";
1619 			break;
1620 		case 0x04:
1621 			product_str = "LSISAS1078 C2";
1622 			break;
1623 		default:
1624 			product_str = "LSISAS1078";
1625 			break;
1626 		}
1627 		break;
1628 	}
1629 
1630  out:
1631 	return product_str;
1632 }
1633 
1634 /**
1635  *	mpt_mapresources - map in memory mapped io
1636  *	@ioc: Pointer to pointer to IOC adapter
1637  *
1638  **/
1639 static int
1640 mpt_mapresources(MPT_ADAPTER *ioc)
1641 {
1642 	u8		__iomem *mem;
1643 	int		 ii;
1644 	resource_size_t	 mem_phys;
1645 	unsigned long	 port;
1646 	u32		 msize;
1647 	u32		 psize;
1648 	int		 r = -ENODEV;
1649 	struct pci_dev *pdev;
1650 
1651 	pdev = ioc->pcidev;
1652 	ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1653 	if (pci_enable_device_mem(pdev)) {
1654 		printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1655 		    "failed\n", ioc->name);
1656 		return r;
1657 	}
1658 	if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1659 		printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1660 		    "MEM failed\n", ioc->name);
1661 		goto out_pci_disable_device;
1662 	}
1663 
1664 	if (sizeof(dma_addr_t) > 4) {
1665 		const uint64_t required_mask = dma_get_required_mask
1666 		    (&pdev->dev);
1667 		if (required_mask > DMA_BIT_MASK(32)
1668 			&& !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1669 			&& !pci_set_consistent_dma_mask(pdev,
1670 						 DMA_BIT_MASK(64))) {
1671 			ioc->dma_mask = DMA_BIT_MASK(64);
1672 			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1673 				": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1674 				ioc->name));
1675 		} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1676 			&& !pci_set_consistent_dma_mask(pdev,
1677 						DMA_BIT_MASK(32))) {
1678 			ioc->dma_mask = DMA_BIT_MASK(32);
1679 			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1680 				": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1681 				ioc->name));
1682 		} else {
1683 			printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1684 			    ioc->name, pci_name(pdev));
1685 			goto out_pci_release_region;
1686 		}
1687 	} else {
1688 		if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1689 			&& !pci_set_consistent_dma_mask(pdev,
1690 						DMA_BIT_MASK(32))) {
1691 			ioc->dma_mask = DMA_BIT_MASK(32);
1692 			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1693 				": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1694 				ioc->name));
1695 		} else {
1696 			printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1697 			    ioc->name, pci_name(pdev));
1698 			goto out_pci_release_region;
1699 		}
1700 	}
1701 
1702 	mem_phys = msize = 0;
1703 	port = psize = 0;
1704 	for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1705 		if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1706 			if (psize)
1707 				continue;
1708 			/* Get I/O space! */
1709 			port = pci_resource_start(pdev, ii);
1710 			psize = pci_resource_len(pdev, ii);
1711 		} else {
1712 			if (msize)
1713 				continue;
1714 			/* Get memmap */
1715 			mem_phys = pci_resource_start(pdev, ii);
1716 			msize = pci_resource_len(pdev, ii);
1717 		}
1718 	}
1719 	ioc->mem_size = msize;
1720 
1721 	mem = NULL;
1722 	/* Get logical ptr for PciMem0 space */
1723 	/*mem = ioremap(mem_phys, msize);*/
1724 	mem = ioremap(mem_phys, msize);
1725 	if (mem == NULL) {
1726 		printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1727 			" memory!\n", ioc->name);
1728 		r = -EINVAL;
1729 		goto out_pci_release_region;
1730 	}
1731 	ioc->memmap = mem;
1732 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1733 	    ioc->name, mem, (unsigned long long)mem_phys));
1734 
1735 	ioc->mem_phys = mem_phys;
1736 	ioc->chip = (SYSIF_REGS __iomem *)mem;
1737 
1738 	/* Save Port IO values in case we need to do downloadboot */
1739 	ioc->pio_mem_phys = port;
1740 	ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1741 
1742 	return 0;
1743 
1744 out_pci_release_region:
1745 	pci_release_selected_regions(pdev, ioc->bars);
1746 out_pci_disable_device:
1747 	pci_disable_device(pdev);
1748 	return r;
1749 }
1750 
1751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1752 /**
1753  *	mpt_attach - Install a PCI intelligent MPT adapter.
1754  *	@pdev: Pointer to pci_dev structure
1755  *	@id: PCI device ID information
1756  *
1757  *	This routine performs all the steps necessary to bring the IOC of
1758  *	a MPT adapter to a OPERATIONAL state.  This includes registering
1759  *	memory regions, registering the interrupt, and allocating request
1760  *	and reply memory pools.
1761  *
1762  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
1763  *	MPT adapter.
1764  *
1765  *	Returns 0 for success, non-zero for failure.
1766  *
1767  *	TODO: Add support for polled controllers
1768  */
1769 int
1770 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1771 {
1772 	MPT_ADAPTER	*ioc;
1773 	u8		 cb_idx;
1774 	int		 r = -ENODEV;
1775 	u8		 pcixcmd;
1776 	static int	 mpt_ids = 0;
1777 #ifdef CONFIG_PROC_FS
1778 	struct proc_dir_entry *dent;
1779 #endif
1780 
1781 	ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1782 	if (ioc == NULL) {
1783 		printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1784 		return -ENOMEM;
1785 	}
1786 
1787 	ioc->id = mpt_ids++;
1788 	sprintf(ioc->name, "ioc%d", ioc->id);
1789 	dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1790 
1791 	/*
1792 	 * set initial debug level
1793 	 * (refer to mptdebug.h)
1794 	 *
1795 	 */
1796 	ioc->debug_level = mpt_debug_level;
1797 	if (mpt_debug_level)
1798 		printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1799 
1800 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1801 
1802 	ioc->pcidev = pdev;
1803 	if (mpt_mapresources(ioc)) {
1804 		goto out_free_ioc;
1805 	}
1806 
1807 	/*
1808 	 * Setting up proper handlers for scatter gather handling
1809 	 */
1810 	if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1811 		if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1812 			ioc->add_sge = &mpt_add_sge_64bit_1078;
1813 		else
1814 			ioc->add_sge = &mpt_add_sge_64bit;
1815 		ioc->add_chain = &mpt_add_chain_64bit;
1816 		ioc->sg_addr_size = 8;
1817 	} else {
1818 		ioc->add_sge = &mpt_add_sge;
1819 		ioc->add_chain = &mpt_add_chain;
1820 		ioc->sg_addr_size = 4;
1821 	}
1822 	ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1823 
1824 	ioc->alloc_total = sizeof(MPT_ADAPTER);
1825 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
1826 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1827 
1828 
1829 	spin_lock_init(&ioc->taskmgmt_lock);
1830 	mutex_init(&ioc->internal_cmds.mutex);
1831 	init_completion(&ioc->internal_cmds.done);
1832 	mutex_init(&ioc->mptbase_cmds.mutex);
1833 	init_completion(&ioc->mptbase_cmds.done);
1834 	mutex_init(&ioc->taskmgmt_cmds.mutex);
1835 	init_completion(&ioc->taskmgmt_cmds.done);
1836 
1837 	/* Initialize the event logging.
1838 	 */
1839 	ioc->eventTypes = 0;	/* None */
1840 	ioc->eventContext = 0;
1841 	ioc->eventLogSize = 0;
1842 	ioc->events = NULL;
1843 
1844 #ifdef MFCNT
1845 	ioc->mfcnt = 0;
1846 #endif
1847 
1848 	ioc->sh = NULL;
1849 	ioc->cached_fw = NULL;
1850 
1851 	/* Initialize SCSI Config Data structure
1852 	 */
1853 	memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1854 
1855 	/* Initialize the fc rport list head.
1856 	 */
1857 	INIT_LIST_HEAD(&ioc->fc_rports);
1858 
1859 	/* Find lookup slot. */
1860 	INIT_LIST_HEAD(&ioc->list);
1861 
1862 
1863 	/* Initialize workqueue */
1864 	INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1865 
1866 	snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1867 		 "mpt_poll_%d", ioc->id);
1868 	ioc->reset_work_q = alloc_workqueue(ioc->reset_work_q_name,
1869 					    WQ_MEM_RECLAIM, 0);
1870 	if (!ioc->reset_work_q) {
1871 		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1872 		    ioc->name);
1873 		r = -ENOMEM;
1874 		goto out_unmap_resources;
1875 	}
1876 
1877 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1878 	    ioc->name, &ioc->facts, &ioc->pfacts[0]));
1879 
1880 	ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1881 					      pdev->revision);
1882 
1883 	switch (pdev->device)
1884 	{
1885 	case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1886 	case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1887 		ioc->errata_flag_1064 = 1;
1888 	case MPI_MANUFACTPAGE_DEVICEID_FC909:
1889 	case MPI_MANUFACTPAGE_DEVICEID_FC929:
1890 	case MPI_MANUFACTPAGE_DEVICEID_FC919:
1891 	case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1892 		ioc->bus_type = FC;
1893 		break;
1894 
1895 	case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1896 		if (pdev->revision < XL_929) {
1897 			/* 929X Chip Fix. Set Split transactions level
1898 		 	* for PCIX. Set MOST bits to zero.
1899 		 	*/
1900 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1901 			pcixcmd &= 0x8F;
1902 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1903 		} else {
1904 			/* 929XL Chip Fix. Set MMRBC to 0x08.
1905 		 	*/
1906 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1907 			pcixcmd |= 0x08;
1908 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1909 		}
1910 		ioc->bus_type = FC;
1911 		break;
1912 
1913 	case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1914 		/* 919X Chip Fix. Set Split transactions level
1915 		 * for PCIX. Set MOST bits to zero.
1916 		 */
1917 		pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1918 		pcixcmd &= 0x8F;
1919 		pci_write_config_byte(pdev, 0x6a, pcixcmd);
1920 		ioc->bus_type = FC;
1921 		break;
1922 
1923 	case MPI_MANUFACTPAGE_DEVID_53C1030:
1924 		/* 1030 Chip Fix. Disable Split transactions
1925 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1926 		 */
1927 		if (pdev->revision < C0_1030) {
1928 			pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1929 			pcixcmd &= 0x8F;
1930 			pci_write_config_byte(pdev, 0x6a, pcixcmd);
1931 		}
1932 
1933 	case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1934 		ioc->bus_type = SPI;
1935 		break;
1936 
1937 	case MPI_MANUFACTPAGE_DEVID_SAS1064:
1938 	case MPI_MANUFACTPAGE_DEVID_SAS1068:
1939 		ioc->errata_flag_1064 = 1;
1940 		ioc->bus_type = SAS;
1941 		break;
1942 
1943 	case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1944 	case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1945 	case MPI_MANUFACTPAGE_DEVID_SAS1078:
1946 		ioc->bus_type = SAS;
1947 		break;
1948 	}
1949 
1950 
1951 	switch (ioc->bus_type) {
1952 
1953 	case SAS:
1954 		ioc->msi_enable = mpt_msi_enable_sas;
1955 		break;
1956 
1957 	case SPI:
1958 		ioc->msi_enable = mpt_msi_enable_spi;
1959 		break;
1960 
1961 	case FC:
1962 		ioc->msi_enable = mpt_msi_enable_fc;
1963 		break;
1964 
1965 	default:
1966 		ioc->msi_enable = 0;
1967 		break;
1968 	}
1969 
1970 	ioc->fw_events_off = 1;
1971 
1972 	if (ioc->errata_flag_1064)
1973 		pci_disable_io_access(pdev);
1974 
1975 	spin_lock_init(&ioc->FreeQlock);
1976 
1977 	/* Disable all! */
1978 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1979 	ioc->active = 0;
1980 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1981 
1982 	/* Set IOC ptr in the pcidev's driver data. */
1983 	pci_set_drvdata(ioc->pcidev, ioc);
1984 
1985 	/* Set lookup ptr. */
1986 	list_add_tail(&ioc->list, &ioc_list);
1987 
1988 	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1989 	 */
1990 	mpt_detect_bound_ports(ioc, pdev);
1991 
1992 	INIT_LIST_HEAD(&ioc->fw_event_list);
1993 	spin_lock_init(&ioc->fw_event_lock);
1994 	snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1995 	ioc->fw_event_q = alloc_workqueue(ioc->fw_event_q_name,
1996 					  WQ_MEM_RECLAIM, 0);
1997 	if (!ioc->fw_event_q) {
1998 		printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1999 		    ioc->name);
2000 		r = -ENOMEM;
2001 		goto out_remove_ioc;
2002 	}
2003 
2004 	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2005 	    CAN_SLEEP)) != 0){
2006 		printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2007 		    ioc->name, r);
2008 
2009 		destroy_workqueue(ioc->fw_event_q);
2010 		ioc->fw_event_q = NULL;
2011 
2012 		list_del(&ioc->list);
2013 		if (ioc->alt_ioc)
2014 			ioc->alt_ioc->alt_ioc = NULL;
2015 		iounmap(ioc->memmap);
2016 		if (pci_is_enabled(pdev))
2017 			pci_disable_device(pdev);
2018 		if (r != -5)
2019 			pci_release_selected_regions(pdev, ioc->bars);
2020 
2021 		destroy_workqueue(ioc->reset_work_q);
2022 		ioc->reset_work_q = NULL;
2023 
2024 		kfree(ioc);
2025 		return r;
2026 	}
2027 
2028 	/* call per device driver probe entry point */
2029 	for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2030 		if(MptDeviceDriverHandlers[cb_idx] &&
2031 		  MptDeviceDriverHandlers[cb_idx]->probe) {
2032 			MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2033 		}
2034 	}
2035 
2036 #ifdef CONFIG_PROC_FS
2037 	/*
2038 	 *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2039 	 */
2040 	dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2041 	if (dent) {
2042 		proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
2043 		proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
2044 	}
2045 #endif
2046 
2047 	if (!ioc->alt_ioc)
2048 		queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2049 			msecs_to_jiffies(MPT_POLLING_INTERVAL));
2050 
2051 	return 0;
2052 
2053 out_remove_ioc:
2054 	list_del(&ioc->list);
2055 	if (ioc->alt_ioc)
2056 		ioc->alt_ioc->alt_ioc = NULL;
2057 
2058 	destroy_workqueue(ioc->reset_work_q);
2059 	ioc->reset_work_q = NULL;
2060 
2061 out_unmap_resources:
2062 	iounmap(ioc->memmap);
2063 	pci_disable_device(pdev);
2064 	pci_release_selected_regions(pdev, ioc->bars);
2065 
2066 out_free_ioc:
2067 	kfree(ioc);
2068 
2069 	return r;
2070 }
2071 
2072 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2073 /**
2074  *	mpt_detach - Remove a PCI intelligent MPT adapter.
2075  *	@pdev: Pointer to pci_dev structure
2076  */
2077 
2078 void
2079 mpt_detach(struct pci_dev *pdev)
2080 {
2081 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
2082 	char pname[32];
2083 	u8 cb_idx;
2084 	unsigned long flags;
2085 	struct workqueue_struct *wq;
2086 
2087 	/*
2088 	 * Stop polling ioc for fault condition
2089 	 */
2090 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2091 	wq = ioc->reset_work_q;
2092 	ioc->reset_work_q = NULL;
2093 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2094 	cancel_delayed_work(&ioc->fault_reset_work);
2095 	destroy_workqueue(wq);
2096 
2097 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
2098 	wq = ioc->fw_event_q;
2099 	ioc->fw_event_q = NULL;
2100 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2101 	destroy_workqueue(wq);
2102 
2103 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2104 	remove_proc_entry(pname, NULL);
2105 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2106 	remove_proc_entry(pname, NULL);
2107 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2108 	remove_proc_entry(pname, NULL);
2109 
2110 	/* call per device driver remove entry point */
2111 	for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2112 		if(MptDeviceDriverHandlers[cb_idx] &&
2113 		  MptDeviceDriverHandlers[cb_idx]->remove) {
2114 			MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2115 		}
2116 	}
2117 
2118 	/* Disable interrupts! */
2119 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2120 
2121 	ioc->active = 0;
2122 	synchronize_irq(pdev->irq);
2123 
2124 	/* Clear any lingering interrupt */
2125 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2126 
2127 	CHIPREG_READ32(&ioc->chip->IntStatus);
2128 
2129 	mpt_adapter_dispose(ioc);
2130 
2131 }
2132 
2133 /**************************************************************************
2134  * Power Management
2135  */
2136 #ifdef CONFIG_PM
2137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2138 /**
2139  *	mpt_suspend - Fusion MPT base driver suspend routine.
2140  *	@pdev: Pointer to pci_dev structure
2141  *	@state: new state to enter
2142  */
2143 int
2144 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2145 {
2146 	u32 device_state;
2147 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2148 
2149 	device_state = pci_choose_state(pdev, state);
2150 	printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2151 	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2152 	    device_state);
2153 
2154 	/* put ioc into READY_STATE */
2155 	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2156 		printk(MYIOC_s_ERR_FMT
2157 		"pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
2158 	}
2159 
2160 	/* disable interrupts */
2161 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2162 	ioc->active = 0;
2163 
2164 	/* Clear any lingering interrupt */
2165 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2166 
2167 	free_irq(ioc->pci_irq, ioc);
2168 	if (ioc->msi_enable)
2169 		pci_disable_msi(ioc->pcidev);
2170 	ioc->pci_irq = -1;
2171 	pci_save_state(pdev);
2172 	pci_disable_device(pdev);
2173 	pci_release_selected_regions(pdev, ioc->bars);
2174 	pci_set_power_state(pdev, device_state);
2175 	return 0;
2176 }
2177 
2178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2179 /**
2180  *	mpt_resume - Fusion MPT base driver resume routine.
2181  *	@pdev: Pointer to pci_dev structure
2182  */
2183 int
2184 mpt_resume(struct pci_dev *pdev)
2185 {
2186 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2187 	u32 device_state = pdev->current_state;
2188 	int recovery_state;
2189 	int err;
2190 
2191 	printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2192 	    "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2193 	    device_state);
2194 
2195 	pci_set_power_state(pdev, PCI_D0);
2196 	pci_enable_wake(pdev, PCI_D0, 0);
2197 	pci_restore_state(pdev);
2198 	ioc->pcidev = pdev;
2199 	err = mpt_mapresources(ioc);
2200 	if (err)
2201 		return err;
2202 
2203 	if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2204 		if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2205 			ioc->add_sge = &mpt_add_sge_64bit_1078;
2206 		else
2207 			ioc->add_sge = &mpt_add_sge_64bit;
2208 		ioc->add_chain = &mpt_add_chain_64bit;
2209 		ioc->sg_addr_size = 8;
2210 	} else {
2211 
2212 		ioc->add_sge = &mpt_add_sge;
2213 		ioc->add_chain = &mpt_add_chain;
2214 		ioc->sg_addr_size = 4;
2215 	}
2216 	ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2217 
2218 	printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2219 	    ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2220 	    CHIPREG_READ32(&ioc->chip->Doorbell));
2221 
2222 	/*
2223 	 * Errata workaround for SAS pci express:
2224 	 * Upon returning to the D0 state, the contents of the doorbell will be
2225 	 * stale data, and this will incorrectly signal to the host driver that
2226 	 * the firmware is ready to process mpt commands.   The workaround is
2227 	 * to issue a diagnostic reset.
2228 	 */
2229 	if (ioc->bus_type == SAS && (pdev->device ==
2230 	    MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2231 	    MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2232 		if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2233 			printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2234 			    ioc->name);
2235 			goto out;
2236 		}
2237 	}
2238 
2239 	/* bring ioc to operational state */
2240 	printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2241 	recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2242 						 CAN_SLEEP);
2243 	if (recovery_state != 0)
2244 		printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2245 		    "error:[%x]\n", ioc->name, recovery_state);
2246 	else
2247 		printk(MYIOC_s_INFO_FMT
2248 		    "pci-resume: success\n", ioc->name);
2249  out:
2250 	return 0;
2251 
2252 }
2253 #endif
2254 
2255 static int
2256 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2257 {
2258 	if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2259 	     ioc->bus_type != SPI) ||
2260 	    (MptDriverClass[index] == MPTFC_DRIVER &&
2261 	     ioc->bus_type != FC) ||
2262 	    (MptDriverClass[index] == MPTSAS_DRIVER &&
2263 	     ioc->bus_type != SAS))
2264 		/* make sure we only call the relevant reset handler
2265 		 * for the bus */
2266 		return 0;
2267 	return (MptResetHandlers[index])(ioc, reset_phase);
2268 }
2269 
2270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2271 /**
2272  *	mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2273  *	@ioc: Pointer to MPT adapter structure
2274  *	@reason: Event word / reason
2275  *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2276  *
2277  *	This routine performs all the steps necessary to bring the IOC
2278  *	to a OPERATIONAL state.
2279  *
2280  *	This routine also pre-fetches the LAN MAC address of a Fibre Channel
2281  *	MPT adapter.
2282  *
2283  *	Returns:
2284  *		 0 for success
2285  *		-1 if failed to get board READY
2286  *		-2 if READY but IOCFacts Failed
2287  *		-3 if READY but PrimeIOCFifos Failed
2288  *		-4 if READY but IOCInit Failed
2289  *		-5 if failed to enable_device and/or request_selected_regions
2290  *		-6 if failed to upload firmware
2291  */
2292 static int
2293 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2294 {
2295 	int	 hard_reset_done = 0;
2296 	int	 alt_ioc_ready = 0;
2297 	int	 hard;
2298 	int	 rc=0;
2299 	int	 ii;
2300 	int	 ret = 0;
2301 	int	 reset_alt_ioc_active = 0;
2302 	int	 irq_allocated = 0;
2303 	u8	*a;
2304 
2305 	printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2306 	    reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2307 
2308 	/* Disable reply interrupts (also blocks FreeQ) */
2309 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2310 	ioc->active = 0;
2311 
2312 	if (ioc->alt_ioc) {
2313 		if (ioc->alt_ioc->active ||
2314 		    reason == MPT_HOSTEVENT_IOC_RECOVER) {
2315 			reset_alt_ioc_active = 1;
2316 			/* Disable alt-IOC's reply interrupts
2317 			 *  (and FreeQ) for a bit
2318 			 **/
2319 			CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2320 				0xFFFFFFFF);
2321 			ioc->alt_ioc->active = 0;
2322 		}
2323 	}
2324 
2325 	hard = 1;
2326 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2327 		hard = 0;
2328 
2329 	if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2330 		if (hard_reset_done == -4) {
2331 			printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2332 			    ioc->name);
2333 
2334 			if (reset_alt_ioc_active && ioc->alt_ioc) {
2335 				/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2336 				dprintk(ioc, printk(MYIOC_s_INFO_FMT
2337 				    "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2338 				CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2339 				ioc->alt_ioc->active = 1;
2340 			}
2341 
2342 		} else {
2343 			printk(MYIOC_s_WARN_FMT
2344 			    "NOT READY WARNING!\n", ioc->name);
2345 		}
2346 		ret = -1;
2347 		goto out;
2348 	}
2349 
2350 	/* hard_reset_done = 0 if a soft reset was performed
2351 	 * and 1 if a hard reset was performed.
2352 	 */
2353 	if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2354 		if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2355 			alt_ioc_ready = 1;
2356 		else
2357 			printk(MYIOC_s_WARN_FMT
2358 			    ": alt-ioc Not ready WARNING!\n",
2359 			    ioc->alt_ioc->name);
2360 	}
2361 
2362 	for (ii=0; ii<5; ii++) {
2363 		/* Get IOC facts! Allow 5 retries */
2364 		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2365 			break;
2366 	}
2367 
2368 
2369 	if (ii == 5) {
2370 		dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2371 		    "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2372 		ret = -2;
2373 	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2374 		MptDisplayIocCapabilities(ioc);
2375 	}
2376 
2377 	if (alt_ioc_ready) {
2378 		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2379 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2380 			    "Initial Alt IocFacts failed rc=%x\n",
2381 			    ioc->name, rc));
2382 			/* Retry - alt IOC was initialized once
2383 			 */
2384 			rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2385 		}
2386 		if (rc) {
2387 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2388 			    "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2389 			alt_ioc_ready = 0;
2390 			reset_alt_ioc_active = 0;
2391 		} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2392 			MptDisplayIocCapabilities(ioc->alt_ioc);
2393 		}
2394 	}
2395 
2396 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2397 	    (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2398 		pci_release_selected_regions(ioc->pcidev, ioc->bars);
2399 		ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2400 		    IORESOURCE_IO);
2401 		if (pci_enable_device(ioc->pcidev))
2402 			return -5;
2403 		if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2404 			"mpt"))
2405 			return -5;
2406 	}
2407 
2408 	/*
2409 	 * Device is reset now. It must have de-asserted the interrupt line
2410 	 * (if it was asserted) and it should be safe to register for the
2411 	 * interrupt now.
2412 	 */
2413 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2414 		ioc->pci_irq = -1;
2415 		if (ioc->pcidev->irq) {
2416 			if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2417 				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2418 				    ioc->name);
2419 			else
2420 				ioc->msi_enable = 0;
2421 			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2422 			    IRQF_SHARED, ioc->name, ioc);
2423 			if (rc < 0) {
2424 				printk(MYIOC_s_ERR_FMT "Unable to allocate "
2425 				    "interrupt %d!\n",
2426 				    ioc->name, ioc->pcidev->irq);
2427 				if (ioc->msi_enable)
2428 					pci_disable_msi(ioc->pcidev);
2429 				ret = -EBUSY;
2430 				goto out;
2431 			}
2432 			irq_allocated = 1;
2433 			ioc->pci_irq = ioc->pcidev->irq;
2434 			pci_set_master(ioc->pcidev);		/* ?? */
2435 			pci_set_drvdata(ioc->pcidev, ioc);
2436 			dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2437 			    "installed at interrupt %d\n", ioc->name,
2438 			    ioc->pcidev->irq));
2439 		}
2440 	}
2441 
2442 	/* Prime reply & request queues!
2443 	 * (mucho alloc's) Must be done prior to
2444 	 * init as upper addresses are needed for init.
2445 	 * If fails, continue with alt-ioc processing
2446 	 */
2447 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2448 	    ioc->name));
2449 	if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2450 		ret = -3;
2451 
2452 	/* May need to check/upload firmware & data here!
2453 	 * If fails, continue with alt-ioc processing
2454 	 */
2455 	dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2456 	    ioc->name));
2457 	if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2458 		ret = -4;
2459 // NEW!
2460 	if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2461 		printk(MYIOC_s_WARN_FMT
2462 		    ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2463 		    ioc->alt_ioc->name, rc);
2464 		alt_ioc_ready = 0;
2465 		reset_alt_ioc_active = 0;
2466 	}
2467 
2468 	if (alt_ioc_ready) {
2469 		if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2470 			alt_ioc_ready = 0;
2471 			reset_alt_ioc_active = 0;
2472 			printk(MYIOC_s_WARN_FMT
2473 				": alt-ioc: (%d) init failure WARNING!\n",
2474 					ioc->alt_ioc->name, rc);
2475 		}
2476 	}
2477 
2478 	if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2479 		if (ioc->upload_fw) {
2480 			ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2481 			    "firmware upload required!\n", ioc->name));
2482 
2483 			/* Controller is not operational, cannot do upload
2484 			 */
2485 			if (ret == 0) {
2486 				rc = mpt_do_upload(ioc, sleepFlag);
2487 				if (rc == 0) {
2488 					if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2489 						/*
2490 						 * Maintain only one pointer to FW memory
2491 						 * so there will not be two attempt to
2492 						 * downloadboot onboard dual function
2493 						 * chips (mpt_adapter_disable,
2494 						 * mpt_diag_reset)
2495 						 */
2496 						ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2497 						    "mpt_upload:  alt_%s has cached_fw=%p \n",
2498 						    ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2499 						ioc->cached_fw = NULL;
2500 					}
2501 				} else {
2502 					printk(MYIOC_s_WARN_FMT
2503 					    "firmware upload failure!\n", ioc->name);
2504 					ret = -6;
2505 				}
2506 			}
2507 		}
2508 	}
2509 
2510 	/*  Enable MPT base driver management of EventNotification
2511 	 *  and EventAck handling.
2512 	 */
2513 	if ((ret == 0) && (!ioc->facts.EventState)) {
2514 		dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2515 			"SendEventNotification\n",
2516 		    ioc->name));
2517 		ret = SendEventNotification(ioc, 1, sleepFlag);	/* 1=Enable */
2518 	}
2519 
2520 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2521 		rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2522 
2523 	if (ret == 0) {
2524 		/* Enable! (reply interrupt) */
2525 		CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2526 		ioc->active = 1;
2527 	}
2528 	if (rc == 0) {	/* alt ioc */
2529 		if (reset_alt_ioc_active && ioc->alt_ioc) {
2530 			/* (re)Enable alt-IOC! (reply interrupt) */
2531 			dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2532 				"reply irq re-enabled\n",
2533 				ioc->alt_ioc->name));
2534 			CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2535 				MPI_HIM_DIM);
2536 			ioc->alt_ioc->active = 1;
2537 		}
2538 	}
2539 
2540 
2541 	/*	Add additional "reason" check before call to GetLanConfigPages
2542 	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
2543 	 *	recursive scenario; GetLanConfigPages times out, timer expired
2544 	 *	routine calls HardResetHandler, which calls into here again,
2545 	 *	and we try GetLanConfigPages again...
2546 	 */
2547 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2548 
2549 		/*
2550 		 * Initialize link list for inactive raid volumes.
2551 		 */
2552 		mutex_init(&ioc->raid_data.inactive_list_mutex);
2553 		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2554 
2555 		switch (ioc->bus_type) {
2556 
2557 		case SAS:
2558 			/* clear persistency table */
2559 			if(ioc->facts.IOCExceptions &
2560 			    MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2561 				ret = mptbase_sas_persist_operation(ioc,
2562 				    MPI_SAS_OP_CLEAR_NOT_PRESENT);
2563 				if(ret != 0)
2564 					goto out;
2565 			}
2566 
2567 			/* Find IM volumes
2568 			 */
2569 			mpt_findImVolumes(ioc);
2570 
2571 			/* Check, and possibly reset, the coalescing value
2572 			 */
2573 			mpt_read_ioc_pg_1(ioc);
2574 
2575 			break;
2576 
2577 		case FC:
2578 			if ((ioc->pfacts[0].ProtocolFlags &
2579 				MPI_PORTFACTS_PROTOCOL_LAN) &&
2580 			    (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2581 				/*
2582 				 *  Pre-fetch the ports LAN MAC address!
2583 				 *  (LANPage1_t stuff)
2584 				 */
2585 				(void) GetLanConfigPages(ioc);
2586 				a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2587 				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2588 					"LanAddr = %02X:%02X:%02X"
2589 					":%02X:%02X:%02X\n",
2590 					ioc->name, a[5], a[4],
2591 					a[3], a[2], a[1], a[0]));
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 		printk("%s: ", ioc->prod_name);
2872 	printk("Capabilities={");
2873 
2874 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2875 		printk("Initiator");
2876 		i++;
2877 	}
2878 
2879 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2880 		printk("%sTarget", i ? "," : "");
2881 		i++;
2882 	}
2883 
2884 	if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2885 		printk("%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 		printk("%sLogBusAddr", i ? "," : "");
2895 		i++;
2896 	}
2897 #endif
2898 
2899 	printk("}\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("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6612 	proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6613 	return 0;
6614 }
6615 
6616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6617 /**
6618  *	procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6619  *
6620  *	Returns 0 for success, non-zero for failure.
6621  */
6622 static void
6623 procmpt_destroy(void)
6624 {
6625 	remove_proc_entry("version", mpt_proc_root_dir);
6626 	remove_proc_entry("summary", mpt_proc_root_dir);
6627 	remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6628 }
6629 
6630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6631 /*
6632  *	Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6633  */
6634 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6635 
6636 static int mpt_summary_proc_show(struct seq_file *m, void *v)
6637 {
6638 	MPT_ADAPTER *ioc = m->private;
6639 
6640 	if (ioc) {
6641 		seq_mpt_print_ioc_summary(ioc, m, 1);
6642 	} else {
6643 		list_for_each_entry(ioc, &ioc_list, list) {
6644 			seq_mpt_print_ioc_summary(ioc, m, 1);
6645 		}
6646 	}
6647 
6648 	return 0;
6649 }
6650 
6651 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6652 {
6653 	return single_open(file, mpt_summary_proc_show, PDE_DATA(inode));
6654 }
6655 
6656 static const struct file_operations mpt_summary_proc_fops = {
6657 	.owner		= THIS_MODULE,
6658 	.open		= mpt_summary_proc_open,
6659 	.read		= seq_read,
6660 	.llseek		= seq_lseek,
6661 	.release	= single_release,
6662 };
6663 
6664 static int mpt_version_proc_show(struct seq_file *m, void *v)
6665 {
6666 	u8	 cb_idx;
6667 	int	 scsi, fc, sas, lan, ctl, targ, dmp;
6668 	char	*drvname;
6669 
6670 	seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6671 	seq_printf(m, "  Fusion MPT base driver\n");
6672 
6673 	scsi = fc = sas = lan = ctl = targ = dmp = 0;
6674 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6675 		drvname = NULL;
6676 		if (MptCallbacks[cb_idx]) {
6677 			switch (MptDriverClass[cb_idx]) {
6678 			case MPTSPI_DRIVER:
6679 				if (!scsi++) drvname = "SPI host";
6680 				break;
6681 			case MPTFC_DRIVER:
6682 				if (!fc++) drvname = "FC host";
6683 				break;
6684 			case MPTSAS_DRIVER:
6685 				if (!sas++) drvname = "SAS host";
6686 				break;
6687 			case MPTLAN_DRIVER:
6688 				if (!lan++) drvname = "LAN";
6689 				break;
6690 			case MPTSTM_DRIVER:
6691 				if (!targ++) drvname = "SCSI target";
6692 				break;
6693 			case MPTCTL_DRIVER:
6694 				if (!ctl++) drvname = "ioctl";
6695 				break;
6696 			}
6697 
6698 			if (drvname)
6699 				seq_printf(m, "  Fusion MPT %s driver\n", drvname);
6700 		}
6701 	}
6702 
6703 	return 0;
6704 }
6705 
6706 static int mpt_version_proc_open(struct inode *inode, struct file *file)
6707 {
6708 	return single_open(file, mpt_version_proc_show, NULL);
6709 }
6710 
6711 static const struct file_operations mpt_version_proc_fops = {
6712 	.owner		= THIS_MODULE,
6713 	.open		= mpt_version_proc_open,
6714 	.read		= seq_read,
6715 	.llseek		= seq_lseek,
6716 	.release	= single_release,
6717 };
6718 
6719 static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6720 {
6721 	MPT_ADAPTER	*ioc = m->private;
6722 	char		 expVer[32];
6723 	int		 sz;
6724 	int		 p;
6725 
6726 	mpt_get_fw_exp_ver(expVer, ioc);
6727 
6728 	seq_printf(m, "%s:", ioc->name);
6729 	if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6730 		seq_printf(m, "  (f/w download boot flag set)");
6731 //	if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6732 //		seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");
6733 
6734 	seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
6735 			ioc->facts.ProductID,
6736 			ioc->prod_name);
6737 	seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6738 	if (ioc->facts.FWImageSize)
6739 		seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6740 	seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6741 	seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6742 	seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);
6743 
6744 	seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
6745 			ioc->facts.CurrentHostMfaHighAddr);
6746 	seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6747 			ioc->facts.CurrentSenseBufferHighAddr);
6748 
6749 	seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6750 	seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6751 
6752 	seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6753 					(void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6754 	/*
6755 	 *  Rounding UP to nearest 4-kB boundary here...
6756 	 */
6757 	sz = (ioc->req_sz * ioc->req_depth) + 128;
6758 	sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6759 	seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6760 					ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6761 	seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6762 					4*ioc->facts.RequestFrameSize,
6763 					ioc->facts.GlobalCredits);
6764 
6765 	seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6766 					(void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6767 	sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6768 	seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6769 					ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6770 	seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6771 					ioc->facts.CurReplyFrameSize,
6772 					ioc->facts.ReplyQueueDepth);
6773 
6774 	seq_printf(m, "  MaxDevices = %d\n",
6775 			(ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6776 	seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6777 
6778 	/* per-port info */
6779 	for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6780 		seq_printf(m, "  PortNumber = %d (of %d)\n",
6781 				p+1,
6782 				ioc->facts.NumberOfPorts);
6783 		if (ioc->bus_type == FC) {
6784 			if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6785 				u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6786 				seq_printf(m, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6787 						a[5], a[4], a[3], a[2], a[1], a[0]);
6788 			}
6789 			seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
6790 					ioc->fc_port_page0[p].WWNN.High,
6791 					ioc->fc_port_page0[p].WWNN.Low,
6792 					ioc->fc_port_page0[p].WWPN.High,
6793 					ioc->fc_port_page0[p].WWPN.Low);
6794 		}
6795 	}
6796 
6797 	return 0;
6798 }
6799 
6800 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6801 {
6802 	return single_open(file, mpt_iocinfo_proc_show, PDE_DATA(inode));
6803 }
6804 
6805 static const struct file_operations mpt_iocinfo_proc_fops = {
6806 	.owner		= THIS_MODULE,
6807 	.open		= mpt_iocinfo_proc_open,
6808 	.read		= seq_read,
6809 	.llseek		= seq_lseek,
6810 	.release	= single_release,
6811 };
6812 #endif		/* CONFIG_PROC_FS } */
6813 
6814 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6815 static void
6816 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6817 {
6818 	buf[0] ='\0';
6819 	if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6820 		sprintf(buf, " (Exp %02d%02d)",
6821 			(ioc->facts.FWVersion.Word >> 16) & 0x00FF,	/* Month */
6822 			(ioc->facts.FWVersion.Word >> 8) & 0x1F);	/* Day */
6823 
6824 		/* insider hack! */
6825 		if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6826 			strcat(buf, " [MDBG]");
6827 	}
6828 }
6829 
6830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6831 /**
6832  *	mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6833  *	@ioc: Pointer to MPT_ADAPTER structure
6834  *	@buffer: Pointer to buffer where IOC summary info should be written
6835  *	@size: Pointer to number of bytes we wrote (set by this routine)
6836  *	@len: Offset at which to start writing in buffer
6837  *	@showlan: Display LAN stuff?
6838  *
6839  *	This routine writes (english readable) ASCII text, which represents
6840  *	a summary of IOC information, to a buffer.
6841  */
6842 void
6843 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6844 {
6845 	char expVer[32];
6846 	int y;
6847 
6848 	mpt_get_fw_exp_ver(expVer, ioc);
6849 
6850 	/*
6851 	 *  Shorter summary of attached ioc's...
6852 	 */
6853 	y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6854 			ioc->name,
6855 			ioc->prod_name,
6856 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6857 			ioc->facts.FWVersion.Word,
6858 			expVer,
6859 			ioc->facts.NumberOfPorts,
6860 			ioc->req_depth);
6861 
6862 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6863 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6864 		y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6865 			a[5], a[4], a[3], a[2], a[1], a[0]);
6866 	}
6867 
6868 	y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6869 
6870 	if (!ioc->active)
6871 		y += sprintf(buffer+len+y, " (disabled)");
6872 
6873 	y += sprintf(buffer+len+y, "\n");
6874 
6875 	*size = y;
6876 }
6877 
6878 #ifdef CONFIG_PROC_FS
6879 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6880 {
6881 	char expVer[32];
6882 
6883 	mpt_get_fw_exp_ver(expVer, ioc);
6884 
6885 	/*
6886 	 *  Shorter summary of attached ioc's...
6887 	 */
6888 	seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6889 			ioc->name,
6890 			ioc->prod_name,
6891 			MPT_FW_REV_MAGIC_ID_STRING,	/* "FwRev=" or somesuch */
6892 			ioc->facts.FWVersion.Word,
6893 			expVer,
6894 			ioc->facts.NumberOfPorts,
6895 			ioc->req_depth);
6896 
6897 	if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6898 		u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6899 		seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6900 			a[5], a[4], a[3], a[2], a[1], a[0]);
6901 	}
6902 
6903 	seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6904 
6905 	if (!ioc->active)
6906 		seq_printf(m, " (disabled)");
6907 
6908 	seq_putc(m, '\n');
6909 }
6910 #endif
6911 
6912 /**
6913  *	mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6914  *	@ioc: Pointer to MPT_ADAPTER structure
6915  *
6916  *	Returns 0 for SUCCESS or -1 if FAILED.
6917  *
6918  *	If -1 is return, then it was not possible to set the flags
6919  **/
6920 int
6921 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6922 {
6923 	unsigned long	 flags;
6924 	int		 retval;
6925 
6926 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6927 	if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6928 	    (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6929 		retval = -1;
6930 		goto out;
6931 	}
6932 	retval = 0;
6933 	ioc->taskmgmt_in_progress = 1;
6934 	ioc->taskmgmt_quiesce_io = 1;
6935 	if (ioc->alt_ioc) {
6936 		ioc->alt_ioc->taskmgmt_in_progress = 1;
6937 		ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6938 	}
6939  out:
6940 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6941 	return retval;
6942 }
6943 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6944 
6945 /**
6946  *	mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6947  *	@ioc: Pointer to MPT_ADAPTER structure
6948  *
6949  **/
6950 void
6951 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6952 {
6953 	unsigned long	 flags;
6954 
6955 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6956 	ioc->taskmgmt_in_progress = 0;
6957 	ioc->taskmgmt_quiesce_io = 0;
6958 	if (ioc->alt_ioc) {
6959 		ioc->alt_ioc->taskmgmt_in_progress = 0;
6960 		ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6961 	}
6962 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6963 }
6964 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6965 
6966 
6967 /**
6968  *	mpt_halt_firmware - Halts the firmware if it is operational and panic
6969  *	the kernel
6970  *	@ioc: Pointer to MPT_ADAPTER structure
6971  *
6972  **/
6973 void
6974 mpt_halt_firmware(MPT_ADAPTER *ioc)
6975 {
6976 	u32	 ioc_raw_state;
6977 
6978 	ioc_raw_state = mpt_GetIocState(ioc, 0);
6979 
6980 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6981 		printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6982 			ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6983 		panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6984 			ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6985 	} else {
6986 		CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6987 		panic("%s: Firmware is halted due to command timeout\n",
6988 			ioc->name);
6989 	}
6990 }
6991 EXPORT_SYMBOL(mpt_halt_firmware);
6992 
6993 /**
6994  *	mpt_SoftResetHandler - Issues a less expensive reset
6995  *	@ioc: Pointer to MPT_ADAPTER structure
6996  *	@sleepFlag: Indicates if sleep or schedule must be called.
6997  *
6998  *	Returns 0 for SUCCESS or -1 if FAILED.
6999  *
7000  *	Message Unit Reset - instructs the IOC to reset the Reply Post and
7001  *	Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
7002  *	All posted buffers are freed, and event notification is turned off.
7003  *	IOC doesn't reply to any outstanding request. This will transfer IOC
7004  *	to READY state.
7005  **/
7006 static int
7007 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7008 {
7009 	int		 rc;
7010 	int		 ii;
7011 	u8		 cb_idx;
7012 	unsigned long	 flags;
7013 	u32		 ioc_state;
7014 	unsigned long	 time_count;
7015 
7016 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
7017 		ioc->name));
7018 
7019 	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7020 
7021 	if (mpt_fwfault_debug)
7022 		mpt_halt_firmware(ioc);
7023 
7024 	if (ioc_state == MPI_IOC_STATE_FAULT ||
7025 	    ioc_state == MPI_IOC_STATE_RESET) {
7026 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7027 		    "skipping, either in FAULT or RESET state!\n", ioc->name));
7028 		return -1;
7029 	}
7030 
7031 	if (ioc->bus_type == FC) {
7032 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7033 		    "skipping, because the bus type is FC!\n", ioc->name));
7034 		return -1;
7035 	}
7036 
7037 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7038 	if (ioc->ioc_reset_in_progress) {
7039 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7040 		return -1;
7041 	}
7042 	ioc->ioc_reset_in_progress = 1;
7043 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7044 
7045 	rc = -1;
7046 
7047 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7048 		if (MptResetHandlers[cb_idx])
7049 			mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7050 	}
7051 
7052 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7053 	if (ioc->taskmgmt_in_progress) {
7054 		ioc->ioc_reset_in_progress = 0;
7055 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7056 		return -1;
7057 	}
7058 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7059 	/* Disable reply interrupts (also blocks FreeQ) */
7060 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7061 	ioc->active = 0;
7062 	time_count = jiffies;
7063 
7064 	rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7065 
7066 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7067 		if (MptResetHandlers[cb_idx])
7068 			mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7069 	}
7070 
7071 	if (rc)
7072 		goto out;
7073 
7074 	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7075 	if (ioc_state != MPI_IOC_STATE_READY)
7076 		goto out;
7077 
7078 	for (ii = 0; ii < 5; ii++) {
7079 		/* Get IOC facts! Allow 5 retries */
7080 		rc = GetIocFacts(ioc, sleepFlag,
7081 			MPT_HOSTEVENT_IOC_RECOVER);
7082 		if (rc == 0)
7083 			break;
7084 		if (sleepFlag == CAN_SLEEP)
7085 			msleep(100);
7086 		else
7087 			mdelay(100);
7088 	}
7089 	if (ii == 5)
7090 		goto out;
7091 
7092 	rc = PrimeIocFifos(ioc);
7093 	if (rc != 0)
7094 		goto out;
7095 
7096 	rc = SendIocInit(ioc, sleepFlag);
7097 	if (rc != 0)
7098 		goto out;
7099 
7100 	rc = SendEventNotification(ioc, 1, sleepFlag);
7101 	if (rc != 0)
7102 		goto out;
7103 
7104 	if (ioc->hard_resets < -1)
7105 		ioc->hard_resets++;
7106 
7107 	/*
7108 	 * At this point, we know soft reset succeeded.
7109 	 */
7110 
7111 	ioc->active = 1;
7112 	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7113 
7114  out:
7115 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7116 	ioc->ioc_reset_in_progress = 0;
7117 	ioc->taskmgmt_quiesce_io = 0;
7118 	ioc->taskmgmt_in_progress = 0;
7119 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7120 
7121 	if (ioc->active) {	/* otherwise, hard reset coming */
7122 		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7123 			if (MptResetHandlers[cb_idx])
7124 				mpt_signal_reset(cb_idx, ioc,
7125 					MPT_IOC_POST_RESET);
7126 		}
7127 	}
7128 
7129 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7130 		"SoftResetHandler: completed (%d seconds): %s\n",
7131 		ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7132 		((rc == 0) ? "SUCCESS" : "FAILED")));
7133 
7134 	return rc;
7135 }
7136 
7137 /**
7138  *	mpt_Soft_Hard_ResetHandler - Try less expensive reset
7139  *	@ioc: Pointer to MPT_ADAPTER structure
7140  *	@sleepFlag: Indicates if sleep or schedule must be called.
7141  *
7142  *	Returns 0 for SUCCESS or -1 if FAILED.
7143  *	Try for softreset first, only if it fails go for expensive
7144  *	HardReset.
7145  **/
7146 int
7147 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7148 	int ret = -1;
7149 
7150 	ret = mpt_SoftResetHandler(ioc, sleepFlag);
7151 	if (ret == 0)
7152 		return ret;
7153 	ret = mpt_HardResetHandler(ioc, sleepFlag);
7154 	return ret;
7155 }
7156 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7157 
7158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7159 /*
7160  *	Reset Handling
7161  */
7162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7163 /**
7164  *	mpt_HardResetHandler - Generic reset handler
7165  *	@ioc: Pointer to MPT_ADAPTER structure
7166  *	@sleepFlag: Indicates if sleep or schedule must be called.
7167  *
7168  *	Issues SCSI Task Management call based on input arg values.
7169  *	If TaskMgmt fails, returns associated SCSI request.
7170  *
7171  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7172  *	or a non-interrupt thread.  In the former, must not call schedule().
7173  *
7174  *	Note: A return of -1 is a FATAL error case, as it means a
7175  *	FW reload/initialization failed.
7176  *
7177  *	Returns 0 for SUCCESS or -1 if FAILED.
7178  */
7179 int
7180 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7181 {
7182 	int	 rc;
7183 	u8	 cb_idx;
7184 	unsigned long	 flags;
7185 	unsigned long	 time_count;
7186 
7187 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7188 #ifdef MFCNT
7189 	printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7190 	printk("MF count 0x%x !\n", ioc->mfcnt);
7191 #endif
7192 	if (mpt_fwfault_debug)
7193 		mpt_halt_firmware(ioc);
7194 
7195 	/* Reset the adapter. Prevent more than 1 call to
7196 	 * mpt_do_ioc_recovery at any instant in time.
7197 	 */
7198 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7199 	if (ioc->ioc_reset_in_progress) {
7200 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7201 		ioc->wait_on_reset_completion = 1;
7202 		do {
7203 			ssleep(1);
7204 		} while (ioc->ioc_reset_in_progress == 1);
7205 		ioc->wait_on_reset_completion = 0;
7206 		return ioc->reset_status;
7207 	}
7208 	if (ioc->wait_on_reset_completion) {
7209 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7210 		rc = 0;
7211 		time_count = jiffies;
7212 		goto exit;
7213 	}
7214 	ioc->ioc_reset_in_progress = 1;
7215 	if (ioc->alt_ioc)
7216 		ioc->alt_ioc->ioc_reset_in_progress = 1;
7217 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7218 
7219 
7220 	/* The SCSI driver needs to adjust timeouts on all current
7221 	 * commands prior to the diagnostic reset being issued.
7222 	 * Prevents timeouts occurring during a diagnostic reset...very bad.
7223 	 * For all other protocol drivers, this is a no-op.
7224 	 */
7225 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7226 		if (MptResetHandlers[cb_idx]) {
7227 			mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7228 			if (ioc->alt_ioc)
7229 				mpt_signal_reset(cb_idx, ioc->alt_ioc,
7230 					MPT_IOC_SETUP_RESET);
7231 		}
7232 	}
7233 
7234 	time_count = jiffies;
7235 	rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7236 	if (rc != 0) {
7237 		printk(KERN_WARNING MYNAM
7238 		       ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7239 		       rc, ioc->name, mpt_GetIocState(ioc, 0));
7240 	} else {
7241 		if (ioc->hard_resets < -1)
7242 			ioc->hard_resets++;
7243 	}
7244 
7245 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7246 	ioc->ioc_reset_in_progress = 0;
7247 	ioc->taskmgmt_quiesce_io = 0;
7248 	ioc->taskmgmt_in_progress = 0;
7249 	ioc->reset_status = rc;
7250 	if (ioc->alt_ioc) {
7251 		ioc->alt_ioc->ioc_reset_in_progress = 0;
7252 		ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7253 		ioc->alt_ioc->taskmgmt_in_progress = 0;
7254 	}
7255 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7256 
7257 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7258 		if (MptResetHandlers[cb_idx]) {
7259 			mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7260 			if (ioc->alt_ioc)
7261 				mpt_signal_reset(cb_idx,
7262 					ioc->alt_ioc, MPT_IOC_POST_RESET);
7263 		}
7264 	}
7265 exit:
7266 	dtmprintk(ioc,
7267 	    printk(MYIOC_s_DEBUG_FMT
7268 		"HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7269 		jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7270 		"SUCCESS" : "FAILED")));
7271 
7272 	return rc;
7273 }
7274 
7275 #ifdef CONFIG_FUSION_LOGGING
7276 static void
7277 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7278 {
7279 	char *ds = NULL;
7280 	u32 evData0;
7281 	int ii;
7282 	u8 event;
7283 	char *evStr = ioc->evStr;
7284 
7285 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
7286 	evData0 = le32_to_cpu(pEventReply->Data[0]);
7287 
7288 	switch(event) {
7289 	case MPI_EVENT_NONE:
7290 		ds = "None";
7291 		break;
7292 	case MPI_EVENT_LOG_DATA:
7293 		ds = "Log Data";
7294 		break;
7295 	case MPI_EVENT_STATE_CHANGE:
7296 		ds = "State Change";
7297 		break;
7298 	case MPI_EVENT_UNIT_ATTENTION:
7299 		ds = "Unit Attention";
7300 		break;
7301 	case MPI_EVENT_IOC_BUS_RESET:
7302 		ds = "IOC Bus Reset";
7303 		break;
7304 	case MPI_EVENT_EXT_BUS_RESET:
7305 		ds = "External Bus Reset";
7306 		break;
7307 	case MPI_EVENT_RESCAN:
7308 		ds = "Bus Rescan Event";
7309 		break;
7310 	case MPI_EVENT_LINK_STATUS_CHANGE:
7311 		if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7312 			ds = "Link Status(FAILURE) Change";
7313 		else
7314 			ds = "Link Status(ACTIVE) Change";
7315 		break;
7316 	case MPI_EVENT_LOOP_STATE_CHANGE:
7317 		if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7318 			ds = "Loop State(LIP) Change";
7319 		else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7320 			ds = "Loop State(LPE) Change";
7321 		else
7322 			ds = "Loop State(LPB) Change";
7323 		break;
7324 	case MPI_EVENT_LOGOUT:
7325 		ds = "Logout";
7326 		break;
7327 	case MPI_EVENT_EVENT_CHANGE:
7328 		if (evData0)
7329 			ds = "Events ON";
7330 		else
7331 			ds = "Events OFF";
7332 		break;
7333 	case MPI_EVENT_INTEGRATED_RAID:
7334 	{
7335 		u8 ReasonCode = (u8)(evData0 >> 16);
7336 		switch (ReasonCode) {
7337 		case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7338 			ds = "Integrated Raid: Volume Created";
7339 			break;
7340 		case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7341 			ds = "Integrated Raid: Volume Deleted";
7342 			break;
7343 		case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7344 			ds = "Integrated Raid: Volume Settings Changed";
7345 			break;
7346 		case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7347 			ds = "Integrated Raid: Volume Status Changed";
7348 			break;
7349 		case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7350 			ds = "Integrated Raid: Volume Physdisk Changed";
7351 			break;
7352 		case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7353 			ds = "Integrated Raid: Physdisk Created";
7354 			break;
7355 		case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7356 			ds = "Integrated Raid: Physdisk Deleted";
7357 			break;
7358 		case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7359 			ds = "Integrated Raid: Physdisk Settings Changed";
7360 			break;
7361 		case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7362 			ds = "Integrated Raid: Physdisk Status Changed";
7363 			break;
7364 		case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7365 			ds = "Integrated Raid: Domain Validation Needed";
7366 			break;
7367 		case MPI_EVENT_RAID_RC_SMART_DATA :
7368 			ds = "Integrated Raid; Smart Data";
7369 			break;
7370 		case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7371 			ds = "Integrated Raid: Replace Action Started";
7372 			break;
7373 		default:
7374 			ds = "Integrated Raid";
7375 		break;
7376 		}
7377 		break;
7378 	}
7379 	case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7380 		ds = "SCSI Device Status Change";
7381 		break;
7382 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7383 	{
7384 		u8 id = (u8)(evData0);
7385 		u8 channel = (u8)(evData0 >> 8);
7386 		u8 ReasonCode = (u8)(evData0 >> 16);
7387 		switch (ReasonCode) {
7388 		case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7389 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7390 			    "SAS Device Status Change: Added: "
7391 			    "id=%d channel=%d", id, channel);
7392 			break;
7393 		case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7394 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7395 			    "SAS Device Status Change: Deleted: "
7396 			    "id=%d channel=%d", id, channel);
7397 			break;
7398 		case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7399 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7400 			    "SAS Device Status Change: SMART Data: "
7401 			    "id=%d channel=%d", id, channel);
7402 			break;
7403 		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7404 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7405 			    "SAS Device Status Change: No Persistancy: "
7406 			    "id=%d channel=%d", id, channel);
7407 			break;
7408 		case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7409 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7410 			    "SAS Device Status Change: Unsupported Device "
7411 			    "Discovered : id=%d channel=%d", id, channel);
7412 			break;
7413 		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7414 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7415 			    "SAS Device Status Change: Internal Device "
7416 			    "Reset : id=%d channel=%d", id, channel);
7417 			break;
7418 		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7419 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7420 			    "SAS Device Status Change: Internal Task "
7421 			    "Abort : id=%d channel=%d", id, channel);
7422 			break;
7423 		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7424 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7425 			    "SAS Device Status Change: Internal Abort "
7426 			    "Task Set : id=%d channel=%d", id, channel);
7427 			break;
7428 		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7429 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7430 			    "SAS Device Status Change: Internal Clear "
7431 			    "Task Set : id=%d channel=%d", id, channel);
7432 			break;
7433 		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7434 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7435 			    "SAS Device Status Change: Internal Query "
7436 			    "Task : id=%d channel=%d", id, channel);
7437 			break;
7438 		default:
7439 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7440 			    "SAS Device Status Change: Unknown: "
7441 			    "id=%d channel=%d", id, channel);
7442 			break;
7443 		}
7444 		break;
7445 	}
7446 	case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7447 		ds = "Bus Timer Expired";
7448 		break;
7449 	case MPI_EVENT_QUEUE_FULL:
7450 	{
7451 		u16 curr_depth = (u16)(evData0 >> 16);
7452 		u8 channel = (u8)(evData0 >> 8);
7453 		u8 id = (u8)(evData0);
7454 
7455 		snprintf(evStr, EVENT_DESCR_STR_SZ,
7456 		   "Queue Full: channel=%d id=%d depth=%d",
7457 		   channel, id, curr_depth);
7458 		break;
7459 	}
7460 	case MPI_EVENT_SAS_SES:
7461 		ds = "SAS SES Event";
7462 		break;
7463 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
7464 		ds = "Persistent Table Full";
7465 		break;
7466 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
7467 	{
7468 		u8 LinkRates = (u8)(evData0 >> 8);
7469 		u8 PhyNumber = (u8)(evData0);
7470 		LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7471 			MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7472 		switch (LinkRates) {
7473 		case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7474 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7475 			   "SAS PHY Link Status: Phy=%d:"
7476 			   " Rate Unknown",PhyNumber);
7477 			break;
7478 		case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7479 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7480 			   "SAS PHY Link Status: Phy=%d:"
7481 			   " Phy Disabled",PhyNumber);
7482 			break;
7483 		case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7484 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7485 			   "SAS PHY Link Status: Phy=%d:"
7486 			   " Failed Speed Nego",PhyNumber);
7487 			break;
7488 		case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7489 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7490 			   "SAS PHY Link Status: Phy=%d:"
7491 			   " Sata OOB Completed",PhyNumber);
7492 			break;
7493 		case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7494 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7495 			   "SAS PHY Link Status: Phy=%d:"
7496 			   " Rate 1.5 Gbps",PhyNumber);
7497 			break;
7498 		case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7499 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7500 			   "SAS PHY Link Status: Phy=%d:"
7501 			   " Rate 3.0 Gbps", PhyNumber);
7502 			break;
7503 		case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7504 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7505 			   "SAS PHY Link Status: Phy=%d:"
7506 			   " Rate 6.0 Gbps", PhyNumber);
7507 			break;
7508 		default:
7509 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7510 			   "SAS PHY Link Status: Phy=%d", PhyNumber);
7511 			break;
7512 		}
7513 		break;
7514 	}
7515 	case MPI_EVENT_SAS_DISCOVERY_ERROR:
7516 		ds = "SAS Discovery Error";
7517 		break;
7518 	case MPI_EVENT_IR_RESYNC_UPDATE:
7519 	{
7520 		u8 resync_complete = (u8)(evData0 >> 16);
7521 		snprintf(evStr, EVENT_DESCR_STR_SZ,
7522 		    "IR Resync Update: Complete = %d:",resync_complete);
7523 		break;
7524 	}
7525 	case MPI_EVENT_IR2:
7526 	{
7527 		u8 id = (u8)(evData0);
7528 		u8 channel = (u8)(evData0 >> 8);
7529 		u8 phys_num = (u8)(evData0 >> 24);
7530 		u8 ReasonCode = (u8)(evData0 >> 16);
7531 
7532 		switch (ReasonCode) {
7533 		case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7534 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7535 			    "IR2: LD State Changed: "
7536 			    "id=%d channel=%d phys_num=%d",
7537 			    id, channel, phys_num);
7538 			break;
7539 		case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7540 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7541 			    "IR2: PD State Changed "
7542 			    "id=%d channel=%d phys_num=%d",
7543 			    id, channel, phys_num);
7544 			break;
7545 		case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7546 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7547 			    "IR2: Bad Block Table Full: "
7548 			    "id=%d channel=%d phys_num=%d",
7549 			    id, channel, phys_num);
7550 			break;
7551 		case MPI_EVENT_IR2_RC_PD_INSERTED:
7552 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7553 			    "IR2: PD Inserted: "
7554 			    "id=%d channel=%d phys_num=%d",
7555 			    id, channel, phys_num);
7556 			break;
7557 		case MPI_EVENT_IR2_RC_PD_REMOVED:
7558 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7559 			    "IR2: PD Removed: "
7560 			    "id=%d channel=%d phys_num=%d",
7561 			    id, channel, phys_num);
7562 			break;
7563 		case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7564 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7565 			    "IR2: Foreign CFG Detected: "
7566 			    "id=%d channel=%d phys_num=%d",
7567 			    id, channel, phys_num);
7568 			break;
7569 		case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7570 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7571 			    "IR2: Rebuild Medium Error: "
7572 			    "id=%d channel=%d phys_num=%d",
7573 			    id, channel, phys_num);
7574 			break;
7575 		case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7576 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7577 			    "IR2: Dual Port Added: "
7578 			    "id=%d channel=%d phys_num=%d",
7579 			    id, channel, phys_num);
7580 			break;
7581 		case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7582 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7583 			    "IR2: Dual Port Removed: "
7584 			    "id=%d channel=%d phys_num=%d",
7585 			    id, channel, phys_num);
7586 			break;
7587 		default:
7588 			ds = "IR2";
7589 		break;
7590 		}
7591 		break;
7592 	}
7593 	case MPI_EVENT_SAS_DISCOVERY:
7594 	{
7595 		if (evData0)
7596 			ds = "SAS Discovery: Start";
7597 		else
7598 			ds = "SAS Discovery: Stop";
7599 		break;
7600 	}
7601 	case MPI_EVENT_LOG_ENTRY_ADDED:
7602 		ds = "SAS Log Entry Added";
7603 		break;
7604 
7605 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7606 	{
7607 		u8 phy_num = (u8)(evData0);
7608 		u8 port_num = (u8)(evData0 >> 8);
7609 		u8 port_width = (u8)(evData0 >> 16);
7610 		u8 primative = (u8)(evData0 >> 24);
7611 		snprintf(evStr, EVENT_DESCR_STR_SZ,
7612 		    "SAS Broadcase Primative: phy=%d port=%d "
7613 		    "width=%d primative=0x%02x",
7614 		    phy_num, port_num, port_width, primative);
7615 		break;
7616 	}
7617 
7618 	case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7619 	{
7620 		u8 reason = (u8)(evData0);
7621 
7622 		switch (reason) {
7623 		case MPI_EVENT_SAS_INIT_RC_ADDED:
7624 			ds = "SAS Initiator Status Change: Added";
7625 			break;
7626 		case MPI_EVENT_SAS_INIT_RC_REMOVED:
7627 			ds = "SAS Initiator Status Change: Deleted";
7628 			break;
7629 		default:
7630 			ds = "SAS Initiator Status Change";
7631 			break;
7632 		}
7633 		break;
7634 	}
7635 
7636 	case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7637 	{
7638 		u8 max_init = (u8)(evData0);
7639 		u8 current_init = (u8)(evData0 >> 8);
7640 
7641 		snprintf(evStr, EVENT_DESCR_STR_SZ,
7642 		    "SAS Initiator Device Table Overflow: max initiators=%02d "
7643 		    "current initators=%02d",
7644 		    max_init, current_init);
7645 		break;
7646 	}
7647 	case MPI_EVENT_SAS_SMP_ERROR:
7648 	{
7649 		u8 status = (u8)(evData0);
7650 		u8 port_num = (u8)(evData0 >> 8);
7651 		u8 result = (u8)(evData0 >> 16);
7652 
7653 		if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7654 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7655 			    "SAS SMP Error: port=%d result=0x%02x",
7656 			    port_num, result);
7657 		else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7658 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7659 			    "SAS SMP Error: port=%d : CRC Error",
7660 			    port_num);
7661 		else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7662 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7663 			    "SAS SMP Error: port=%d : Timeout",
7664 			    port_num);
7665 		else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7666 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7667 			    "SAS SMP Error: port=%d : No Destination",
7668 			    port_num);
7669 		else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7670 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7671 			    "SAS SMP Error: port=%d : Bad Destination",
7672 			    port_num);
7673 		else
7674 			snprintf(evStr, EVENT_DESCR_STR_SZ,
7675 			    "SAS SMP Error: port=%d : status=0x%02x",
7676 			    port_num, status);
7677 		break;
7678 	}
7679 
7680 	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7681 	{
7682 		u8 reason = (u8)(evData0);
7683 
7684 		switch (reason) {
7685 		case MPI_EVENT_SAS_EXP_RC_ADDED:
7686 			ds = "Expander Status Change: Added";
7687 			break;
7688 		case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7689 			ds = "Expander Status Change: Deleted";
7690 			break;
7691 		default:
7692 			ds = "Expander Status Change";
7693 			break;
7694 		}
7695 		break;
7696 	}
7697 
7698 	/*
7699 	 *  MPT base "custom" events may be added here...
7700 	 */
7701 	default:
7702 		ds = "Unknown";
7703 		break;
7704 	}
7705 	if (ds)
7706 		strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7707 
7708 
7709 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7710 	    "MPT event:(%02Xh) : %s\n",
7711 	    ioc->name, event, evStr));
7712 
7713 	devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7714 	    ": Event data:\n"));
7715 	for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7716 		devtverboseprintk(ioc, printk(" %08x",
7717 		    le32_to_cpu(pEventReply->Data[ii])));
7718 	devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7719 }
7720 #endif
7721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7722 /**
7723  *	ProcessEventNotification - Route EventNotificationReply to all event handlers
7724  *	@ioc: Pointer to MPT_ADAPTER structure
7725  *	@pEventReply: Pointer to EventNotification reply frame
7726  *	@evHandlers: Pointer to integer, number of event handlers
7727  *
7728  *	Routes a received EventNotificationReply to all currently registered
7729  *	event handlers.
7730  *	Returns sum of event handlers return values.
7731  */
7732 static int
7733 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7734 {
7735 	u16 evDataLen;
7736 	u32 evData0 = 0;
7737 	int ii;
7738 	u8 cb_idx;
7739 	int r = 0;
7740 	int handlers = 0;
7741 	u8 event;
7742 
7743 	/*
7744 	 *  Do platform normalization of values
7745 	 */
7746 	event = le32_to_cpu(pEventReply->Event) & 0xFF;
7747 	evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7748 	if (evDataLen) {
7749 		evData0 = le32_to_cpu(pEventReply->Data[0]);
7750 	}
7751 
7752 #ifdef CONFIG_FUSION_LOGGING
7753 	if (evDataLen)
7754 		mpt_display_event_info(ioc, pEventReply);
7755 #endif
7756 
7757 	/*
7758 	 *  Do general / base driver event processing
7759 	 */
7760 	switch(event) {
7761 	case MPI_EVENT_EVENT_CHANGE:		/* 0A */
7762 		if (evDataLen) {
7763 			u8 evState = evData0 & 0xFF;
7764 
7765 			/* CHECKME! What if evState unexpectedly says OFF (0)? */
7766 
7767 			/* Update EventState field in cached IocFacts */
7768 			if (ioc->facts.Function) {
7769 				ioc->facts.EventState = evState;
7770 			}
7771 		}
7772 		break;
7773 	case MPI_EVENT_INTEGRATED_RAID:
7774 		mptbase_raid_process_event_data(ioc,
7775 		    (MpiEventDataRaid_t *)pEventReply->Data);
7776 		break;
7777 	default:
7778 		break;
7779 	}
7780 
7781 	/*
7782 	 * Should this event be logged? Events are written sequentially.
7783 	 * When buffer is full, start again at the top.
7784 	 */
7785 	if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7786 		int idx;
7787 
7788 		idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7789 
7790 		ioc->events[idx].event = event;
7791 		ioc->events[idx].eventContext = ioc->eventContext;
7792 
7793 		for (ii = 0; ii < 2; ii++) {
7794 			if (ii < evDataLen)
7795 				ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7796 			else
7797 				ioc->events[idx].data[ii] =  0;
7798 		}
7799 
7800 		ioc->eventContext++;
7801 	}
7802 
7803 
7804 	/*
7805 	 *  Call each currently registered protocol event handler.
7806 	 */
7807 	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7808 		if (MptEvHandlers[cb_idx]) {
7809 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7810 			    "Routing Event to event handler #%d\n",
7811 			    ioc->name, cb_idx));
7812 			r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7813 			handlers++;
7814 		}
7815 	}
7816 	/* FIXME?  Examine results here? */
7817 
7818 	/*
7819 	 *  If needed, send (a single) EventAck.
7820 	 */
7821 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7822 		devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7823 			"EventAck required\n",ioc->name));
7824 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7825 			devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7826 					ioc->name, ii));
7827 		}
7828 	}
7829 
7830 	*evHandlers = handlers;
7831 	return r;
7832 }
7833 
7834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7835 /**
7836  *	mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7837  *	@ioc: Pointer to MPT_ADAPTER structure
7838  *	@log_info: U32 LogInfo reply word from the IOC
7839  *
7840  *	Refer to lsi/mpi_log_fc.h.
7841  */
7842 static void
7843 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7844 {
7845 	char *desc = "unknown";
7846 
7847 	switch (log_info & 0xFF000000) {
7848 	case MPI_IOCLOGINFO_FC_INIT_BASE:
7849 		desc = "FCP Initiator";
7850 		break;
7851 	case MPI_IOCLOGINFO_FC_TARGET_BASE:
7852 		desc = "FCP Target";
7853 		break;
7854 	case MPI_IOCLOGINFO_FC_LAN_BASE:
7855 		desc = "LAN";
7856 		break;
7857 	case MPI_IOCLOGINFO_FC_MSG_BASE:
7858 		desc = "MPI Message Layer";
7859 		break;
7860 	case MPI_IOCLOGINFO_FC_LINK_BASE:
7861 		desc = "FC Link";
7862 		break;
7863 	case MPI_IOCLOGINFO_FC_CTX_BASE:
7864 		desc = "Context Manager";
7865 		break;
7866 	case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7867 		desc = "Invalid Field Offset";
7868 		break;
7869 	case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7870 		desc = "State Change Info";
7871 		break;
7872 	}
7873 
7874 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7875 			ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7876 }
7877 
7878 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7879 /**
7880  *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7881  *	@ioc: Pointer to MPT_ADAPTER structure
7882  *	@log_info: U32 LogInfo word from the IOC
7883  *
7884  *	Refer to lsi/sp_log.h.
7885  */
7886 static void
7887 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7888 {
7889 	u32 info = log_info & 0x00FF0000;
7890 	char *desc = "unknown";
7891 
7892 	switch (info) {
7893 	case 0x00010000:
7894 		desc = "bug! MID not found";
7895 		break;
7896 
7897 	case 0x00020000:
7898 		desc = "Parity Error";
7899 		break;
7900 
7901 	case 0x00030000:
7902 		desc = "ASYNC Outbound Overrun";
7903 		break;
7904 
7905 	case 0x00040000:
7906 		desc = "SYNC Offset Error";
7907 		break;
7908 
7909 	case 0x00050000:
7910 		desc = "BM Change";
7911 		break;
7912 
7913 	case 0x00060000:
7914 		desc = "Msg In Overflow";
7915 		break;
7916 
7917 	case 0x00070000:
7918 		desc = "DMA Error";
7919 		break;
7920 
7921 	case 0x00080000:
7922 		desc = "Outbound DMA Overrun";
7923 		break;
7924 
7925 	case 0x00090000:
7926 		desc = "Task Management";
7927 		break;
7928 
7929 	case 0x000A0000:
7930 		desc = "Device Problem";
7931 		break;
7932 
7933 	case 0x000B0000:
7934 		desc = "Invalid Phase Change";
7935 		break;
7936 
7937 	case 0x000C0000:
7938 		desc = "Untagged Table Size";
7939 		break;
7940 
7941 	}
7942 
7943 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7944 }
7945 
7946 /* strings for sas loginfo */
7947 	static char *originator_str[] = {
7948 		"IOP",						/* 00h */
7949 		"PL",						/* 01h */
7950 		"IR"						/* 02h */
7951 	};
7952 	static char *iop_code_str[] = {
7953 		NULL,						/* 00h */
7954 		"Invalid SAS Address",				/* 01h */
7955 		NULL,						/* 02h */
7956 		"Invalid Page",					/* 03h */
7957 		"Diag Message Error",				/* 04h */
7958 		"Task Terminated",				/* 05h */
7959 		"Enclosure Management",				/* 06h */
7960 		"Target Mode"					/* 07h */
7961 	};
7962 	static char *pl_code_str[] = {
7963 		NULL,						/* 00h */
7964 		"Open Failure",					/* 01h */
7965 		"Invalid Scatter Gather List",			/* 02h */
7966 		"Wrong Relative Offset or Frame Length",	/* 03h */
7967 		"Frame Transfer Error",				/* 04h */
7968 		"Transmit Frame Connected Low",			/* 05h */
7969 		"SATA Non-NCQ RW Error Bit Set",		/* 06h */
7970 		"SATA Read Log Receive Data Error",		/* 07h */
7971 		"SATA NCQ Fail All Commands After Error",	/* 08h */
7972 		"SATA Error in Receive Set Device Bit FIS",	/* 09h */
7973 		"Receive Frame Invalid Message",		/* 0Ah */
7974 		"Receive Context Message Valid Error",		/* 0Bh */
7975 		"Receive Frame Current Frame Error",		/* 0Ch */
7976 		"SATA Link Down",				/* 0Dh */
7977 		"Discovery SATA Init W IOS",			/* 0Eh */
7978 		"Config Invalid Page",				/* 0Fh */
7979 		"Discovery SATA Init Timeout",			/* 10h */
7980 		"Reset",					/* 11h */
7981 		"Abort",					/* 12h */
7982 		"IO Not Yet Executed",				/* 13h */
7983 		"IO Executed",					/* 14h */
7984 		"Persistent Reservation Out Not Affiliation "
7985 		    "Owner", 					/* 15h */
7986 		"Open Transmit DMA Abort",			/* 16h */
7987 		"IO Device Missing Delay Retry",		/* 17h */
7988 		"IO Cancelled Due to Receive Error",		/* 18h */
7989 		NULL,						/* 19h */
7990 		NULL,						/* 1Ah */
7991 		NULL,						/* 1Bh */
7992 		NULL,						/* 1Ch */
7993 		NULL,						/* 1Dh */
7994 		NULL,						/* 1Eh */
7995 		NULL,						/* 1Fh */
7996 		"Enclosure Management"				/* 20h */
7997 	};
7998 	static char *ir_code_str[] = {
7999 		"Raid Action Error",				/* 00h */
8000 		NULL,						/* 00h */
8001 		NULL,						/* 01h */
8002 		NULL,						/* 02h */
8003 		NULL,						/* 03h */
8004 		NULL,						/* 04h */
8005 		NULL,						/* 05h */
8006 		NULL,						/* 06h */
8007 		NULL						/* 07h */
8008 	};
8009 	static char *raid_sub_code_str[] = {
8010 		NULL, 						/* 00h */
8011 		"Volume Creation Failed: Data Passed too "
8012 		    "Large", 					/* 01h */
8013 		"Volume Creation Failed: Duplicate Volumes "
8014 		    "Attempted", 				/* 02h */
8015 		"Volume Creation Failed: Max Number "
8016 		    "Supported Volumes Exceeded",		/* 03h */
8017 		"Volume Creation Failed: DMA Error",		/* 04h */
8018 		"Volume Creation Failed: Invalid Volume Type",	/* 05h */
8019 		"Volume Creation Failed: Error Reading "
8020 		    "MFG Page 4", 				/* 06h */
8021 		"Volume Creation Failed: Creating Internal "
8022 		    "Structures", 				/* 07h */
8023 		NULL,						/* 08h */
8024 		NULL,						/* 09h */
8025 		NULL,						/* 0Ah */
8026 		NULL,						/* 0Bh */
8027 		NULL,						/* 0Ch */
8028 		NULL,						/* 0Dh */
8029 		NULL,						/* 0Eh */
8030 		NULL,						/* 0Fh */
8031 		"Activation failed: Already Active Volume", 	/* 10h */
8032 		"Activation failed: Unsupported Volume Type", 	/* 11h */
8033 		"Activation failed: Too Many Active Volumes", 	/* 12h */
8034 		"Activation failed: Volume ID in Use", 		/* 13h */
8035 		"Activation failed: Reported Failure", 		/* 14h */
8036 		"Activation failed: Importing a Volume", 	/* 15h */
8037 		NULL,						/* 16h */
8038 		NULL,						/* 17h */
8039 		NULL,						/* 18h */
8040 		NULL,						/* 19h */
8041 		NULL,						/* 1Ah */
8042 		NULL,						/* 1Bh */
8043 		NULL,						/* 1Ch */
8044 		NULL,						/* 1Dh */
8045 		NULL,						/* 1Eh */
8046 		NULL,						/* 1Fh */
8047 		"Phys Disk failed: Too Many Phys Disks", 	/* 20h */
8048 		"Phys Disk failed: Data Passed too Large",	/* 21h */
8049 		"Phys Disk failed: DMA Error", 			/* 22h */
8050 		"Phys Disk failed: Invalid <channel:id>", 	/* 23h */
8051 		"Phys Disk failed: Creating Phys Disk Config "
8052 		    "Page", 					/* 24h */
8053 		NULL,						/* 25h */
8054 		NULL,						/* 26h */
8055 		NULL,						/* 27h */
8056 		NULL,						/* 28h */
8057 		NULL,						/* 29h */
8058 		NULL,						/* 2Ah */
8059 		NULL,						/* 2Bh */
8060 		NULL,						/* 2Ch */
8061 		NULL,						/* 2Dh */
8062 		NULL,						/* 2Eh */
8063 		NULL,						/* 2Fh */
8064 		"Compatibility Error: IR Disabled",		/* 30h */
8065 		"Compatibility Error: Inquiry Command Failed",	/* 31h */
8066 		"Compatibility Error: Device not Direct Access "
8067 		    "Device ",					/* 32h */
8068 		"Compatibility Error: Removable Device Found",	/* 33h */
8069 		"Compatibility Error: Device SCSI Version not "
8070 		    "2 or Higher", 				/* 34h */
8071 		"Compatibility Error: SATA Device, 48 BIT LBA "
8072 		    "not Supported", 				/* 35h */
8073 		"Compatibility Error: Device doesn't have "
8074 		    "512 Byte Block Sizes", 			/* 36h */
8075 		"Compatibility Error: Volume Type Check Failed", /* 37h */
8076 		"Compatibility Error: Volume Type is "
8077 		    "Unsupported by FW", 			/* 38h */
8078 		"Compatibility Error: Disk Drive too Small for "
8079 		    "use in Volume", 				/* 39h */
8080 		"Compatibility Error: Phys Disk for Create "
8081 		    "Volume not Found", 			/* 3Ah */
8082 		"Compatibility Error: Too Many or too Few "
8083 		    "Disks for Volume Type", 			/* 3Bh */
8084 		"Compatibility Error: Disk stripe Sizes "
8085 		    "Must be 64KB", 				/* 3Ch */
8086 		"Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8087 	};
8088 
8089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8090 /**
8091  *	mpt_sas_log_info - Log information returned from SAS IOC.
8092  *	@ioc: Pointer to MPT_ADAPTER structure
8093  *	@log_info: U32 LogInfo reply word from the IOC
8094  *	@cb_idx: callback function's handle
8095  *
8096  *	Refer to lsi/mpi_log_sas.h.
8097  **/
8098 static void
8099 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8100 {
8101 union loginfo_type {
8102 	u32	loginfo;
8103 	struct {
8104 		u32	subcode:16;
8105 		u32	code:8;
8106 		u32	originator:4;
8107 		u32	bus_type:4;
8108 	}dw;
8109 };
8110 	union loginfo_type sas_loginfo;
8111 	char *originator_desc = NULL;
8112 	char *code_desc = NULL;
8113 	char *sub_code_desc = NULL;
8114 
8115 	sas_loginfo.loginfo = log_info;
8116 	if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8117 	    (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8118 		return;
8119 
8120 	originator_desc = originator_str[sas_loginfo.dw.originator];
8121 
8122 	switch (sas_loginfo.dw.originator) {
8123 
8124 		case 0:  /* IOP */
8125 			if (sas_loginfo.dw.code <
8126 			    ARRAY_SIZE(iop_code_str))
8127 				code_desc = iop_code_str[sas_loginfo.dw.code];
8128 			break;
8129 		case 1:  /* PL */
8130 			if (sas_loginfo.dw.code <
8131 			    ARRAY_SIZE(pl_code_str))
8132 				code_desc = pl_code_str[sas_loginfo.dw.code];
8133 			break;
8134 		case 2:  /* IR */
8135 			if (sas_loginfo.dw.code >=
8136 			    ARRAY_SIZE(ir_code_str))
8137 				break;
8138 			code_desc = ir_code_str[sas_loginfo.dw.code];
8139 			if (sas_loginfo.dw.subcode >=
8140 			    ARRAY_SIZE(raid_sub_code_str))
8141 				break;
8142 			if (sas_loginfo.dw.code == 0)
8143 				sub_code_desc =
8144 				    raid_sub_code_str[sas_loginfo.dw.subcode];
8145 			break;
8146 		default:
8147 			return;
8148 	}
8149 
8150 	if (sub_code_desc != NULL)
8151 		printk(MYIOC_s_INFO_FMT
8152 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
8153 			" SubCode={%s} cb_idx %s\n",
8154 			ioc->name, log_info, originator_desc, code_desc,
8155 			sub_code_desc, MptCallbacksName[cb_idx]);
8156 	else if (code_desc != NULL)
8157 		printk(MYIOC_s_INFO_FMT
8158 			"LogInfo(0x%08x): Originator={%s}, Code={%s},"
8159 			" SubCode(0x%04x) cb_idx %s\n",
8160 			ioc->name, log_info, originator_desc, code_desc,
8161 			sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8162 	else
8163 		printk(MYIOC_s_INFO_FMT
8164 			"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8165 			" SubCode(0x%04x) cb_idx %s\n",
8166 			ioc->name, log_info, originator_desc,
8167 			sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8168 			MptCallbacksName[cb_idx]);
8169 }
8170 
8171 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8172 /**
8173  *	mpt_iocstatus_info_config - IOCSTATUS information for config pages
8174  *	@ioc: Pointer to MPT_ADAPTER structure
8175  *	@ioc_status: U32 IOCStatus word from IOC
8176  *	@mf: Pointer to MPT request frame
8177  *
8178  *	Refer to lsi/mpi.h.
8179  **/
8180 static void
8181 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8182 {
8183 	Config_t *pReq = (Config_t *)mf;
8184 	char extend_desc[EVENT_DESCR_STR_SZ];
8185 	char *desc = NULL;
8186 	u32 form;
8187 	u8 page_type;
8188 
8189 	if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8190 		page_type = pReq->ExtPageType;
8191 	else
8192 		page_type = pReq->Header.PageType;
8193 
8194 	/*
8195 	 * ignore invalid page messages for GET_NEXT_HANDLE
8196 	 */
8197 	form = le32_to_cpu(pReq->PageAddress);
8198 	if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8199 		if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8200 		    page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8201 		    page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8202 			if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8203 				MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8204 				return;
8205 		}
8206 		if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8207 			if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8208 				MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8209 				return;
8210 	}
8211 
8212 	snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8213 	    "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8214 	    page_type, pReq->Header.PageNumber, pReq->Action, form);
8215 
8216 	switch (ioc_status) {
8217 
8218 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8219 		desc = "Config Page Invalid Action";
8220 		break;
8221 
8222 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8223 		desc = "Config Page Invalid Type";
8224 		break;
8225 
8226 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8227 		desc = "Config Page Invalid Page";
8228 		break;
8229 
8230 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8231 		desc = "Config Page Invalid Data";
8232 		break;
8233 
8234 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8235 		desc = "Config Page No Defaults";
8236 		break;
8237 
8238 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8239 		desc = "Config Page Can't Commit";
8240 		break;
8241 	}
8242 
8243 	if (!desc)
8244 		return;
8245 
8246 	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8247 	    ioc->name, ioc_status, desc, extend_desc));
8248 }
8249 
8250 /**
8251  *	mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8252  *	@ioc: Pointer to MPT_ADAPTER structure
8253  *	@ioc_status: U32 IOCStatus word from IOC
8254  *	@mf: Pointer to MPT request frame
8255  *
8256  *	Refer to lsi/mpi.h.
8257  **/
8258 static void
8259 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8260 {
8261 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8262 	char *desc = NULL;
8263 
8264 	switch (status) {
8265 
8266 /****************************************************************************/
8267 /*  Common IOCStatus values for all replies                                 */
8268 /****************************************************************************/
8269 
8270 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8271 		desc = "Invalid Function";
8272 		break;
8273 
8274 	case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8275 		desc = "Busy";
8276 		break;
8277 
8278 	case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8279 		desc = "Invalid SGL";
8280 		break;
8281 
8282 	case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8283 		desc = "Internal Error";
8284 		break;
8285 
8286 	case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8287 		desc = "Reserved";
8288 		break;
8289 
8290 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8291 		desc = "Insufficient Resources";
8292 		break;
8293 
8294 	case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8295 		desc = "Invalid Field";
8296 		break;
8297 
8298 	case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8299 		desc = "Invalid State";
8300 		break;
8301 
8302 /****************************************************************************/
8303 /*  Config IOCStatus values                                                 */
8304 /****************************************************************************/
8305 
8306 	case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8307 	case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8308 	case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8309 	case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8310 	case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8311 	case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8312 		mpt_iocstatus_info_config(ioc, status, mf);
8313 		break;
8314 
8315 /****************************************************************************/
8316 /*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
8317 /*                                                                          */
8318 /*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8319 /*                                                                          */
8320 /****************************************************************************/
8321 
8322 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8323 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8324 	case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8325 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8326 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8327 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8328 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8329 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8330 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8331 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8332 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8333 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8334 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8335 		break;
8336 
8337 /****************************************************************************/
8338 /*  SCSI Target values                                                      */
8339 /****************************************************************************/
8340 
8341 	case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8342 		desc = "Target: Priority IO";
8343 		break;
8344 
8345 	case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8346 		desc = "Target: Invalid Port";
8347 		break;
8348 
8349 	case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8350 		desc = "Target Invalid IO Index:";
8351 		break;
8352 
8353 	case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8354 		desc = "Target: Aborted";
8355 		break;
8356 
8357 	case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8358 		desc = "Target: No Conn Retryable";
8359 		break;
8360 
8361 	case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8362 		desc = "Target: No Connection";
8363 		break;
8364 
8365 	case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8366 		desc = "Target: Transfer Count Mismatch";
8367 		break;
8368 
8369 	case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8370 		desc = "Target: STS Data not Sent";
8371 		break;
8372 
8373 	case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8374 		desc = "Target: Data Offset Error";
8375 		break;
8376 
8377 	case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8378 		desc = "Target: Too Much Write Data";
8379 		break;
8380 
8381 	case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8382 		desc = "Target: IU Too Short";
8383 		break;
8384 
8385 	case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8386 		desc = "Target: ACK NAK Timeout";
8387 		break;
8388 
8389 	case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8390 		desc = "Target: Nak Received";
8391 		break;
8392 
8393 /****************************************************************************/
8394 /*  Fibre Channel Direct Access values                                      */
8395 /****************************************************************************/
8396 
8397 	case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8398 		desc = "FC: Aborted";
8399 		break;
8400 
8401 	case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8402 		desc = "FC: RX ID Invalid";
8403 		break;
8404 
8405 	case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8406 		desc = "FC: DID Invalid";
8407 		break;
8408 
8409 	case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8410 		desc = "FC: Node Logged Out";
8411 		break;
8412 
8413 	case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8414 		desc = "FC: Exchange Canceled";
8415 		break;
8416 
8417 /****************************************************************************/
8418 /*  LAN values                                                              */
8419 /****************************************************************************/
8420 
8421 	case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8422 		desc = "LAN: Device not Found";
8423 		break;
8424 
8425 	case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8426 		desc = "LAN: Device Failure";
8427 		break;
8428 
8429 	case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8430 		desc = "LAN: Transmit Error";
8431 		break;
8432 
8433 	case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8434 		desc = "LAN: Transmit Aborted";
8435 		break;
8436 
8437 	case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8438 		desc = "LAN: Receive Error";
8439 		break;
8440 
8441 	case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8442 		desc = "LAN: Receive Aborted";
8443 		break;
8444 
8445 	case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8446 		desc = "LAN: Partial Packet";
8447 		break;
8448 
8449 	case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8450 		desc = "LAN: Canceled";
8451 		break;
8452 
8453 /****************************************************************************/
8454 /*  Serial Attached SCSI values                                             */
8455 /****************************************************************************/
8456 
8457 	case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8458 		desc = "SAS: SMP Request Failed";
8459 		break;
8460 
8461 	case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8462 		desc = "SAS: SMP Data Overrun";
8463 		break;
8464 
8465 	default:
8466 		desc = "Others";
8467 		break;
8468 	}
8469 
8470 	if (!desc)
8471 		return;
8472 
8473 	dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8474 	    ioc->name, status, desc));
8475 }
8476 
8477 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8478 EXPORT_SYMBOL(mpt_attach);
8479 EXPORT_SYMBOL(mpt_detach);
8480 #ifdef CONFIG_PM
8481 EXPORT_SYMBOL(mpt_resume);
8482 EXPORT_SYMBOL(mpt_suspend);
8483 #endif
8484 EXPORT_SYMBOL(ioc_list);
8485 EXPORT_SYMBOL(mpt_register);
8486 EXPORT_SYMBOL(mpt_deregister);
8487 EXPORT_SYMBOL(mpt_event_register);
8488 EXPORT_SYMBOL(mpt_event_deregister);
8489 EXPORT_SYMBOL(mpt_reset_register);
8490 EXPORT_SYMBOL(mpt_reset_deregister);
8491 EXPORT_SYMBOL(mpt_device_driver_register);
8492 EXPORT_SYMBOL(mpt_device_driver_deregister);
8493 EXPORT_SYMBOL(mpt_get_msg_frame);
8494 EXPORT_SYMBOL(mpt_put_msg_frame);
8495 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8496 EXPORT_SYMBOL(mpt_free_msg_frame);
8497 EXPORT_SYMBOL(mpt_send_handshake_request);
8498 EXPORT_SYMBOL(mpt_verify_adapter);
8499 EXPORT_SYMBOL(mpt_GetIocState);
8500 EXPORT_SYMBOL(mpt_print_ioc_summary);
8501 EXPORT_SYMBOL(mpt_HardResetHandler);
8502 EXPORT_SYMBOL(mpt_config);
8503 EXPORT_SYMBOL(mpt_findImVolumes);
8504 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8505 EXPORT_SYMBOL(mpt_free_fw_memory);
8506 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8507 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8508 
8509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8510 /**
8511  *	fusion_init - Fusion MPT base driver initialization routine.
8512  *
8513  *	Returns 0 for success, non-zero for failure.
8514  */
8515 static int __init
8516 fusion_init(void)
8517 {
8518 	u8 cb_idx;
8519 
8520 	show_mptmod_ver(my_NAME, my_VERSION);
8521 	printk(KERN_INFO COPYRIGHT "\n");
8522 
8523 	for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8524 		MptCallbacks[cb_idx] = NULL;
8525 		MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8526 		MptEvHandlers[cb_idx] = NULL;
8527 		MptResetHandlers[cb_idx] = NULL;
8528 	}
8529 
8530 	/*  Register ourselves (mptbase) in order to facilitate
8531 	 *  EventNotification handling.
8532 	 */
8533 	mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8534 	    "mptbase_reply");
8535 
8536 	/* Register for hard reset handling callbacks.
8537 	 */
8538 	mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8539 
8540 #ifdef CONFIG_PROC_FS
8541 	(void) procmpt_create();
8542 #endif
8543 	return 0;
8544 }
8545 
8546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8547 /**
8548  *	fusion_exit - Perform driver unload cleanup.
8549  *
8550  *	This routine frees all resources associated with each MPT adapter
8551  *	and removes all %MPT_PROCFS_MPTBASEDIR entries.
8552  */
8553 static void __exit
8554 fusion_exit(void)
8555 {
8556 
8557 	mpt_reset_deregister(mpt_base_index);
8558 
8559 #ifdef CONFIG_PROC_FS
8560 	procmpt_destroy();
8561 #endif
8562 }
8563 
8564 module_init(fusion_init);
8565 module_exit(fusion_exit);
8566