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