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