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