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