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