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