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