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