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