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