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