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