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