xref: /openbmc/linux/drivers/scsi/aacraid/src.c (revision 63dc02bd)
1 /*
2  *	Adaptec AAC series RAID controller driver
3  *	(c) Copyright 2001 Red Hat Inc.
4  *
5  * based on the old aacraid driver that is..
6  * Adaptec aacraid device driver for Linux.
7  *
8  * Copyright (c) 2000-2010 Adaptec, Inc.
9  *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; see the file COPYING.  If not, write to
23  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  * Module Name:
26  *  src.c
27  *
28  * Abstract: Hardware Device Interface for PMC SRC based controllers
29  *
30  */
31 
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/types.h>
35 #include <linux/pci.h>
36 #include <linux/spinlock.h>
37 #include <linux/slab.h>
38 #include <linux/blkdev.h>
39 #include <linux/delay.h>
40 #include <linux/completion.h>
41 #include <linux/time.h>
42 #include <linux/interrupt.h>
43 #include <scsi/scsi_host.h>
44 
45 #include "aacraid.h"
46 
47 static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
48 {
49 	struct aac_dev *dev = dev_id;
50 	unsigned long bellbits, bellbits_shifted;
51 	int our_interrupt = 0;
52 	int isFastResponse;
53 	u32 index, handle;
54 
55 	bellbits = src_readl(dev, MUnit.ODR_R);
56 	if (bellbits & PmDoorBellResponseSent) {
57 		bellbits = PmDoorBellResponseSent;
58 		/* handle async. status */
59 		our_interrupt = 1;
60 		index = dev->host_rrq_idx;
61 		if (dev->host_rrq[index] == 0) {
62 			u32 old_index = index;
63 			/* adjust index */
64 			do {
65 				index++;
66 				if (index == dev->scsi_host_ptr->can_queue +
67 							AAC_NUM_MGT_FIB)
68 					index = 0;
69 				if (dev->host_rrq[index] != 0)
70 					break;
71 			} while (index != old_index);
72 			dev->host_rrq_idx = index;
73 		}
74 		for (;;) {
75 			isFastResponse = 0;
76 			/* remove toggle bit (31) */
77 			handle = (dev->host_rrq[index] & 0x7fffffff);
78 			/* check fast response bit (30) */
79 			if (handle & 0x40000000)
80 				isFastResponse = 1;
81 			handle &= 0x0000ffff;
82 			if (handle == 0)
83 				break;
84 
85 			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
86 
87 			dev->host_rrq[index++] = 0;
88 			if (index == dev->scsi_host_ptr->can_queue +
89 						AAC_NUM_MGT_FIB)
90 				index = 0;
91 			dev->host_rrq_idx = index;
92 		}
93 	} else {
94 		bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
95 		if (bellbits_shifted & DoorBellAifPending) {
96 			our_interrupt = 1;
97 			/* handle AIF */
98 			aac_intr_normal(dev, 0, 2, 0, NULL);
99 		} else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
100 			unsigned long sflags;
101 			struct list_head *entry;
102 			int send_it = 0;
103 
104 			if (dev->sync_fib) {
105 				our_interrupt = 1;
106 				if (dev->sync_fib->callback)
107 					dev->sync_fib->callback(dev->sync_fib->callback_data,
108 						dev->sync_fib);
109 				spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
110 				if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
111 					dev->management_fib_count--;
112 					up(&dev->sync_fib->event_wait);
113 				}
114 				spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
115 				spin_lock_irqsave(&dev->sync_lock, sflags);
116 				if (!list_empty(&dev->sync_fib_list)) {
117 					entry = dev->sync_fib_list.next;
118 					dev->sync_fib = list_entry(entry, struct fib, fiblink);
119 					list_del(entry);
120 					send_it = 1;
121 				} else {
122 					dev->sync_fib = NULL;
123 				}
124 				spin_unlock_irqrestore(&dev->sync_lock, sflags);
125 				if (send_it) {
126 					aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
127 						(u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
128 						NULL, NULL, NULL, NULL, NULL);
129 				}
130 			}
131 		}
132 	}
133 
134 	if (our_interrupt) {
135 		src_writel(dev, MUnit.ODR_C, bellbits);
136 		return IRQ_HANDLED;
137 	}
138 	return IRQ_NONE;
139 }
140 
141 /**
142  *	aac_src_disable_interrupt	-	Disable interrupts
143  *	@dev: Adapter
144  */
145 
146 static void aac_src_disable_interrupt(struct aac_dev *dev)
147 {
148 	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
149 }
150 
151 /**
152  *	aac_src_enable_interrupt_message	-	Enable interrupts
153  *	@dev: Adapter
154  */
155 
156 static void aac_src_enable_interrupt_message(struct aac_dev *dev)
157 {
158 	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
159 }
160 
161 /**
162  *	src_sync_cmd	-	send a command and wait
163  *	@dev: Adapter
164  *	@command: Command to execute
165  *	@p1: first parameter
166  *	@ret: adapter status
167  *
168  *	This routine will send a synchronous command to the adapter and wait
169  *	for its	completion.
170  */
171 
172 static int src_sync_cmd(struct aac_dev *dev, u32 command,
173 	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
174 	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
175 {
176 	unsigned long start;
177 	int ok;
178 
179 	/*
180 	 *	Write the command into Mailbox 0
181 	 */
182 	writel(command, &dev->IndexRegs->Mailbox[0]);
183 	/*
184 	 *	Write the parameters into Mailboxes 1 - 6
185 	 */
186 	writel(p1, &dev->IndexRegs->Mailbox[1]);
187 	writel(p2, &dev->IndexRegs->Mailbox[2]);
188 	writel(p3, &dev->IndexRegs->Mailbox[3]);
189 	writel(p4, &dev->IndexRegs->Mailbox[4]);
190 
191 	/*
192 	 *	Clear the synch command doorbell to start on a clean slate.
193 	 */
194 	src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
195 
196 	/*
197 	 *	Disable doorbell interrupts
198 	 */
199 	src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
200 
201 	/*
202 	 *	Force the completion of the mask register write before issuing
203 	 *	the interrupt.
204 	 */
205 	src_readl(dev, MUnit.OIMR);
206 
207 	/*
208 	 *	Signal that there is a new synch command
209 	 */
210 	src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
211 
212 	if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) {
213 		ok = 0;
214 		start = jiffies;
215 
216 		/*
217 		 *	Wait up to 5 minutes
218 		 */
219 		while (time_before(jiffies, start+300*HZ)) {
220 			udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
221 			/*
222 			 *	Mon960 will set doorbell0 bit when it has completed the command.
223 			 */
224 			if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
225 				/*
226 				 *	Clear the doorbell.
227 				 */
228 				src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
229 				ok = 1;
230 				break;
231 			}
232 			/*
233 			 *	Yield the processor in case we are slow
234 			 */
235 			msleep(1);
236 		}
237 		if (unlikely(ok != 1)) {
238 			/*
239 			 *	Restore interrupt mask even though we timed out
240 			 */
241 			aac_adapter_enable_int(dev);
242 			return -ETIMEDOUT;
243 		}
244 		/*
245 		 *	Pull the synch status from Mailbox 0.
246 		 */
247 		if (status)
248 			*status = readl(&dev->IndexRegs->Mailbox[0]);
249 		if (r1)
250 			*r1 = readl(&dev->IndexRegs->Mailbox[1]);
251 		if (r2)
252 			*r2 = readl(&dev->IndexRegs->Mailbox[2]);
253 		if (r3)
254 			*r3 = readl(&dev->IndexRegs->Mailbox[3]);
255 		if (r4)
256 			*r4 = readl(&dev->IndexRegs->Mailbox[4]);
257 
258 		/*
259 		 *	Clear the synch command doorbell.
260 		 */
261 		src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
262 	}
263 
264 	/*
265 	 *	Restore interrupt mask
266 	 */
267 	aac_adapter_enable_int(dev);
268 	return 0;
269 }
270 
271 /**
272  *	aac_src_interrupt_adapter	-	interrupt adapter
273  *	@dev: Adapter
274  *
275  *	Send an interrupt to the i960 and breakpoint it.
276  */
277 
278 static void aac_src_interrupt_adapter(struct aac_dev *dev)
279 {
280 	src_sync_cmd(dev, BREAKPOINT_REQUEST,
281 		0, 0, 0, 0, 0, 0,
282 		NULL, NULL, NULL, NULL, NULL);
283 }
284 
285 /**
286  *	aac_src_notify_adapter		-	send an event to the adapter
287  *	@dev: Adapter
288  *	@event: Event to send
289  *
290  *	Notify the i960 that something it probably cares about has
291  *	happened.
292  */
293 
294 static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
295 {
296 	switch (event) {
297 
298 	case AdapNormCmdQue:
299 		src_writel(dev, MUnit.ODR_C,
300 			INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
301 		break;
302 	case HostNormRespNotFull:
303 		src_writel(dev, MUnit.ODR_C,
304 			INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
305 		break;
306 	case AdapNormRespQue:
307 		src_writel(dev, MUnit.ODR_C,
308 			INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
309 		break;
310 	case HostNormCmdNotFull:
311 		src_writel(dev, MUnit.ODR_C,
312 			INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
313 		break;
314 	case FastIo:
315 		src_writel(dev, MUnit.ODR_C,
316 			INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
317 		break;
318 	case AdapPrintfDone:
319 		src_writel(dev, MUnit.ODR_C,
320 			INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
321 		break;
322 	default:
323 		BUG();
324 		break;
325 	}
326 }
327 
328 /**
329  *	aac_src_start_adapter		-	activate adapter
330  *	@dev:	Adapter
331  *
332  *	Start up processing on an i960 based AAC adapter
333  */
334 
335 static void aac_src_start_adapter(struct aac_dev *dev)
336 {
337 	struct aac_init *init;
338 
339 	init = dev->init;
340 	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
341 
342 	/* We can only use a 32 bit address here */
343 	src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
344 	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
345 }
346 
347 /**
348  *	aac_src_check_health
349  *	@dev: device to check if healthy
350  *
351  *	Will attempt to determine if the specified adapter is alive and
352  *	capable of handling requests, returning 0 if alive.
353  */
354 static int aac_src_check_health(struct aac_dev *dev)
355 {
356 	u32 status = src_readl(dev, MUnit.OMR);
357 
358 	/*
359 	 *	Check to see if the board failed any self tests.
360 	 */
361 	if (unlikely(status & SELF_TEST_FAILED))
362 		return -1;
363 
364 	/*
365 	 *	Check to see if the board panic'd.
366 	 */
367 	if (unlikely(status & KERNEL_PANIC))
368 		return (status >> 16) & 0xFF;
369 	/*
370 	 *	Wait for the adapter to be up and running.
371 	 */
372 	if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
373 		return -3;
374 	/*
375 	 *	Everything is OK
376 	 */
377 	return 0;
378 }
379 
380 /**
381  *	aac_src_deliver_message
382  *	@fib: fib to issue
383  *
384  *	Will send a fib, returning 0 if successful.
385  */
386 static int aac_src_deliver_message(struct fib *fib)
387 {
388 	struct aac_dev *dev = fib->dev;
389 	struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
390 	unsigned long qflags;
391 	u32 fibsize;
392 	u64 address;
393 	struct aac_fib_xporthdr *pFibX;
394 
395 	spin_lock_irqsave(q->lock, qflags);
396 	q->numpending++;
397 	spin_unlock_irqrestore(q->lock, qflags);
398 
399 	/* Calculate the amount to the fibsize bits */
400 	fibsize = (sizeof(struct aac_fib_xporthdr) +
401 		fib->hw_fib_va->header.Size + 127) / 128 - 1;
402 	if (fibsize > (ALIGN32 - 1))
403 		fibsize = ALIGN32 - 1;
404 
405     /* Fill XPORT header */
406 	pFibX = (struct aac_fib_xporthdr *)
407 		((unsigned char *)fib->hw_fib_va -
408 		sizeof(struct aac_fib_xporthdr));
409 	pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
410 	pFibX->HostAddress = fib->hw_fib_pa;
411 	pFibX->Size = fib->hw_fib_va->header.Size;
412 	address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
413 
414 	src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
415 	src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
416 	return 0;
417 }
418 
419 /**
420  *	aac_src_ioremap
421  *	@size: mapping resize request
422  *
423  */
424 static int aac_src_ioremap(struct aac_dev *dev, u32 size)
425 {
426 	if (!size) {
427 		iounmap(dev->regs.src.bar0);
428 		dev->base = dev->regs.src.bar0 = NULL;
429 		return 0;
430 	}
431 	dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
432 		AAC_MIN_SRC_BAR1_SIZE);
433 	dev->base = NULL;
434 	if (dev->regs.src.bar1 == NULL)
435 		return -1;
436 	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
437 				size);
438 	if (dev->base == NULL) {
439 		iounmap(dev->regs.src.bar1);
440 		dev->regs.src.bar1 = NULL;
441 		return -1;
442 	}
443 	dev->IndexRegs = &((struct src_registers __iomem *)
444 		dev->base)->u.tupelo.IndexRegs;
445 	return 0;
446 }
447 
448 /**
449  *  aac_srcv_ioremap
450  *	@size: mapping resize request
451  *
452  */
453 static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
454 {
455 	if (!size) {
456 		iounmap(dev->regs.src.bar0);
457 		dev->base = dev->regs.src.bar0 = NULL;
458 		return 0;
459 	}
460 	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size);
461 	if (dev->base == NULL)
462 		return -1;
463 	dev->IndexRegs = &((struct src_registers __iomem *)
464 		dev->base)->u.denali.IndexRegs;
465 	return 0;
466 }
467 
468 static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
469 {
470 	u32 var, reset_mask;
471 
472 	if (bled >= 0) {
473 		if (bled)
474 			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
475 				dev->name, dev->id, bled);
476 		bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
477 			0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
478 			if (bled || (var != 0x00000001))
479 				return -EINVAL;
480 		if (dev->supplement_adapter_info.SupportedOptions2 &
481 			AAC_OPTION_DOORBELL_RESET) {
482 			src_writel(dev, MUnit.IDR, reset_mask);
483 			msleep(5000); /* Delay 5 seconds */
484 		}
485 	}
486 
487 	if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
488 		return -ENODEV;
489 
490 	if (startup_timeout < 300)
491 		startup_timeout = 300;
492 
493 	return 0;
494 }
495 
496 /**
497  *	aac_src_select_comm	-	Select communications method
498  *	@dev: Adapter
499  *	@comm: communications method
500  */
501 int aac_src_select_comm(struct aac_dev *dev, int comm)
502 {
503 	switch (comm) {
504 	case AAC_COMM_MESSAGE:
505 		dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
506 		dev->a_ops.adapter_intr = aac_src_intr_message;
507 		dev->a_ops.adapter_deliver = aac_src_deliver_message;
508 		break;
509 	default:
510 		return 1;
511 	}
512 	return 0;
513 }
514 
515 /**
516  *  aac_src_init	-	initialize an Cardinal Frey Bar card
517  *  @dev: device to configure
518  *
519  */
520 
521 int aac_src_init(struct aac_dev *dev)
522 {
523 	unsigned long start;
524 	unsigned long status;
525 	int restart = 0;
526 	int instance = dev->id;
527 	const char *name = dev->name;
528 
529 	dev->a_ops.adapter_ioremap = aac_src_ioremap;
530 	dev->a_ops.adapter_comm = aac_src_select_comm;
531 
532 	dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
533 	if (aac_adapter_ioremap(dev, dev->base_size)) {
534 		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
535 		goto error_iounmap;
536 	}
537 
538 	/* Failure to reset here is an option ... */
539 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
540 	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
541 	if ((aac_reset_devices || reset_devices) &&
542 		!aac_src_restart_adapter(dev, 0))
543 		++restart;
544 	/*
545 	 *	Check to see if the board panic'd while booting.
546 	 */
547 	status = src_readl(dev, MUnit.OMR);
548 	if (status & KERNEL_PANIC) {
549 		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
550 			goto error_iounmap;
551 		++restart;
552 	}
553 	/*
554 	 *	Check to see if the board failed any self tests.
555 	 */
556 	status = src_readl(dev, MUnit.OMR);
557 	if (status & SELF_TEST_FAILED) {
558 		printk(KERN_ERR "%s%d: adapter self-test failed.\n",
559 			dev->name, instance);
560 		goto error_iounmap;
561 	}
562 	/*
563 	 *	Check to see if the monitor panic'd while booting.
564 	 */
565 	if (status & MONITOR_PANIC) {
566 		printk(KERN_ERR "%s%d: adapter monitor panic.\n",
567 			dev->name, instance);
568 		goto error_iounmap;
569 	}
570 	start = jiffies;
571 	/*
572 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
573 	 */
574 	while (!((status = src_readl(dev, MUnit.OMR)) &
575 		KERNEL_UP_AND_RUNNING)) {
576 		if ((restart &&
577 		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
578 		  time_after(jiffies, start+HZ*startup_timeout)) {
579 			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
580 					dev->name, instance, status);
581 			goto error_iounmap;
582 		}
583 		if (!restart &&
584 		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
585 		  time_after(jiffies, start + HZ *
586 		  ((startup_timeout > 60)
587 		    ? (startup_timeout - 60)
588 		    : (startup_timeout / 2))))) {
589 			if (likely(!aac_src_restart_adapter(dev,
590 			    aac_src_check_health(dev))))
591 				start = jiffies;
592 			++restart;
593 		}
594 		msleep(1);
595 	}
596 	if (restart && aac_commit)
597 		aac_commit = 1;
598 	/*
599 	 *	Fill in the common function dispatch table.
600 	 */
601 	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
602 	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
603 	dev->a_ops.adapter_notify = aac_src_notify_adapter;
604 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
605 	dev->a_ops.adapter_check_health = aac_src_check_health;
606 	dev->a_ops.adapter_restart = aac_src_restart_adapter;
607 
608 	/*
609 	 *	First clear out all interrupts.  Then enable the one's that we
610 	 *	can handle.
611 	 */
612 	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
613 	aac_adapter_disable_int(dev);
614 	src_writel(dev, MUnit.ODR_C, 0xffffffff);
615 	aac_adapter_enable_int(dev);
616 
617 	if (aac_init_adapter(dev) == NULL)
618 		goto error_iounmap;
619 	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
620 		goto error_iounmap;
621 
622 	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
623 
624 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
625 			IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
626 
627 		if (dev->msi)
628 			pci_disable_msi(dev->pdev);
629 
630 		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
631 			name, instance);
632 		goto error_iounmap;
633 	}
634 	dev->dbg_base = pci_resource_start(dev->pdev, 2);
635 	dev->dbg_base_mapped = dev->regs.src.bar1;
636 	dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
637 
638 	aac_adapter_enable_int(dev);
639 
640 	if (!dev->sync_mode) {
641 		/*
642 		 * Tell the adapter that all is configured, and it can
643 		 * start accepting requests
644 		 */
645 		aac_src_start_adapter(dev);
646 	}
647 	return 0;
648 
649 error_iounmap:
650 
651 	return -1;
652 }
653 
654 /**
655  *  aac_srcv_init	-	initialize an SRCv card
656  *  @dev: device to configure
657  *
658  */
659 
660 int aac_srcv_init(struct aac_dev *dev)
661 {
662 	unsigned long start;
663 	unsigned long status;
664 	int restart = 0;
665 	int instance = dev->id;
666 	const char *name = dev->name;
667 
668 	dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
669 	dev->a_ops.adapter_comm = aac_src_select_comm;
670 
671 	dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
672 	if (aac_adapter_ioremap(dev, dev->base_size)) {
673 		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
674 		goto error_iounmap;
675 	}
676 
677 	/* Failure to reset here is an option ... */
678 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
679 	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
680 	if ((aac_reset_devices || reset_devices) &&
681 		!aac_src_restart_adapter(dev, 0))
682 		++restart;
683 	/*
684 	 *	Check to see if the board panic'd while booting.
685 	 */
686 	status = src_readl(dev, MUnit.OMR);
687 	if (status & KERNEL_PANIC) {
688 		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
689 			goto error_iounmap;
690 		++restart;
691 	}
692 	/*
693 	 *	Check to see if the board failed any self tests.
694 	 */
695 	status = src_readl(dev, MUnit.OMR);
696 	if (status & SELF_TEST_FAILED) {
697 		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
698 		goto error_iounmap;
699 	}
700 	/*
701 	 *	Check to see if the monitor panic'd while booting.
702 	 */
703 	if (status & MONITOR_PANIC) {
704 		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
705 		goto error_iounmap;
706 	}
707 	start = jiffies;
708 	/*
709 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
710 	 */
711 	while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)) {
712 		if ((restart &&
713 		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
714 		  time_after(jiffies, start+HZ*startup_timeout)) {
715 			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
716 					dev->name, instance, status);
717 			goto error_iounmap;
718 		}
719 		if (!restart &&
720 		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
721 		  time_after(jiffies, start + HZ *
722 		  ((startup_timeout > 60)
723 		    ? (startup_timeout - 60)
724 		    : (startup_timeout / 2))))) {
725 			if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev))))
726 				start = jiffies;
727 			++restart;
728 		}
729 		msleep(1);
730 	}
731 	if (restart && aac_commit)
732 		aac_commit = 1;
733 	/*
734 	 *	Fill in the common function dispatch table.
735 	 */
736 	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
737 	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
738 	dev->a_ops.adapter_notify = aac_src_notify_adapter;
739 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
740 	dev->a_ops.adapter_check_health = aac_src_check_health;
741 	dev->a_ops.adapter_restart = aac_src_restart_adapter;
742 
743 	/*
744 	 *	First clear out all interrupts.  Then enable the one's that we
745 	 *	can handle.
746 	 */
747 	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
748 	aac_adapter_disable_int(dev);
749 	src_writel(dev, MUnit.ODR_C, 0xffffffff);
750 	aac_adapter_enable_int(dev);
751 
752 	if (aac_init_adapter(dev) == NULL)
753 		goto error_iounmap;
754 	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
755 		goto error_iounmap;
756 	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
757 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
758 		IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
759 		if (dev->msi)
760 			pci_disable_msi(dev->pdev);
761 		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
762 			name, instance);
763 		goto error_iounmap;
764 	}
765 	dev->dbg_base = dev->scsi_host_ptr->base;
766 	dev->dbg_base_mapped = dev->base;
767 	dev->dbg_size = dev->base_size;
768 
769 	aac_adapter_enable_int(dev);
770 
771 	if (!dev->sync_mode) {
772 		/*
773 		 * Tell the adapter that all is configured, and it can
774 		 * start accepting requests
775 		 */
776 		aac_src_start_adapter(dev);
777 	}
778 	return 0;
779 
780 error_iounmap:
781 
782 	return -1;
783 }
784 
785