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