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