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