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