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