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