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