11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Adaptec AAC series RAID controller driver
3fa195afe4ad3f6d85a9b7cc236ae85c05ca8db03Alan Cox *	(c) Copyright 2001 Red Hat Inc.
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * based on the old aacraid driver that is..
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Adaptec aacraid device driver for Linux.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara * Copyright (c) 2000-2010 Adaptec, Inc.
9e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2, or (at your option)
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * any later version.
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful,
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details.
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; see the file COPYING.  If not, write to
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name:
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  sa.c
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Abstract: Drawbridge specific support functions
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
358ef2224707996aede1808f40116cd467b7c8d549Salyzyn, Mark#include <linux/pci.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/spinlock.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/blkdev.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/completion.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/time.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <scsi/scsi_host.h>
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "aacraid.h"
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
477d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t aac_sa_intr(int irq, void *dev_id)
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct aac_dev *dev = dev_id;
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned short intstat, mask;
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	intstat = sa_readw(dev, DoorbellReg_p);
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Read mask and invert because drawbridge is reversed.
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	This allows us to only service interrupts that have been enabled.
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mask = ~(sa_readw(dev, SaDbCSR.PRISETIRQMASK));
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Check to see if this is our interrupt.  If it isn't just return */
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (intstat & mask) {
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (intstat & PrintfReady) {
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			aac_printf(dev, sa_readl(dev, Mailbox5));
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellReg_s, PrintfDone);
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (intstat & DOORBELL_1) {	// dev -> Host Normal Command Ready
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellClrReg_p, DOORBELL_1);
68df3b7668715f9acfe6ff37dd886f68e46ccd677eMark Haverkamp			aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (intstat & DOORBELL_2) {	// dev -> Host Normal Response Ready
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellClrReg_p, DOORBELL_2);
71df3b7668715f9acfe6ff37dd886f68e46ccd677eMark Haverkamp			aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (intstat & DOORBELL_3) {	// dev -> Host Normal Command Not Full
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellClrReg_p, DOORBELL_3);
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (intstat & DOORBELL_4) {	// dev -> Host Normal Response Not Full
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sa_writew(dev, DoorbellClrReg_p, DOORBELL_4);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return IRQ_HANDLED;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return IRQ_NONE;
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
83bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp *	aac_sa_disable_interrupt	-	disable interrupt
84bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp *	@dev: Which adapter to enable.
85bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp */
86bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp
87bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkampstatic void aac_sa_disable_interrupt (struct aac_dev *dev)
88bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp{
89bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
90bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp}
91bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp
92bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp/**
9328713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp *	aac_sa_enable_interrupt	-	enable interrupt
9428713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp *	@dev: Which adapter to enable.
9528713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp */
9628713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp
9728713324a0f3c055186ecec27239673c36ba1de5Mark Haverkampstatic void aac_sa_enable_interrupt (struct aac_dev *dev)
9828713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp{
9928713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
10028713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp				DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
10128713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp}
10228713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp
10328713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp/**
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	aac_sa_notify_adapter		-	handle adapter notification
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	Adapter that notification is for
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@event:	Event to notidy
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Notify the adapter of an event
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1114833869e6e6c2315e301c256e393dfb949c10076Adrian Bunkstatic void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (event) {
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AdapNormCmdQue:
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_1);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case HostNormRespNotFull:
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_4);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AdapNormRespQue:
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_2);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case HostNormCmdNotFull:
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_3);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case HostShutdown:
1287c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		/*
1297c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		sa_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
1307c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		NULL, NULL, NULL, NULL, NULL);
1317c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		*/
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case FastIo:
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_6);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case AdapPrintfDone:
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sa_writew(dev, DoorbellReg_s,DOORBELL_5);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		BUG();
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	sa_sync_cmd	-	send a command and wait
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: Adapter
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@command: Command to execute
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@p1: first parameter
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@ret: adapter status
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This routine will send a synchronous command to the adapter and wait
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	for its	completion.
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1577c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkampstatic int sa_sync_cmd(struct aac_dev *dev, u32 command,
1587c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
1597c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		u32 *ret, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long start;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 	int ok;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Write the Command into Mailbox 0
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sa_writel(dev, Mailbox0, command);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Write the parameters into Mailboxes 1 - 4
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sa_writel(dev, Mailbox1, p1);
1717c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	sa_writel(dev, Mailbox2, p2);
1727c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	sa_writel(dev, Mailbox3, p3);
1737c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	sa_writel(dev, Mailbox4, p4);
1747c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Clear the synch command doorbell to start on a clean slate.
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Signal that there is a new synch command
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sa_writew(dev, DoorbellReg_s, DOORBELL_0);
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ok = 0;
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	start = jiffies;
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while(time_before(jiffies, start+30*HZ))
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *	Delay 5uS so that the monitor gets access
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(5);
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *	Mon110 will set doorbell0 bit when it has
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *	completed the command.
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(sa_readw(dev, DoorbellReg_p) & DOORBELL_0)  {
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ok = 1;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2011241f3593a8857fab4259b6aa9d17f26e7de3a86Mark Haverkamp		msleep(1);
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ok != 1)
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ETIMEDOUT;
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Clear the synch command doorbell.
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Pull the synch status from Mailbox 0.
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ret)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*ret = sa_readl(dev, Mailbox0);
2157c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	if (r1)
2167c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		*r1 = sa_readl(dev, Mailbox1);
2177c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	if (r2)
2187c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		*r2 = sa_readl(dev, Mailbox2);
2197c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	if (r3)
2207c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		*r3 = sa_readl(dev, Mailbox3);
2217c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	if (r4)
2227c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp		*r4 = sa_readl(dev, Mailbox4);
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	aac_sa_interrupt_adapter	-	interrupt an adapter
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: Which adapter to enable.
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Breakpoint an adapter.
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void aac_sa_interrupt_adapter (struct aac_dev *dev)
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2357c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
236bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp			NULL, NULL, NULL, NULL, NULL);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	aac_sa_start_adapter		-	activate adapter
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev:	Adapter
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Start up processing on an ARM based AAC adapter
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void aac_sa_start_adapter(struct aac_dev *dev)
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct aac_init *init;
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Fill in the remaining pieces of the init.
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init = dev->init;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* We can only use a 32 bit address here */
2557c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
2567c00ffa314bf0fb0e23858bbebad33b48b6abbb9Mark Haverkamp			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
2578e0c5ebde82b08f6d996e11983890fc4cc085fabMark Haverkamp			NULL, NULL, NULL, NULL, NULL);
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2602ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Markstatic int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
2612ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark{
2622ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark	return -EINVAL;
2632ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark}
2642ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	aac_sa_check_health
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: device to check if healthy
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Will attempt to determine if the specified adapter is alive and
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	capable of handling requests, returning 0 if alive.
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int aac_sa_check_health(struct aac_dev *dev)
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long status = sa_readl(dev, Mailbox7);
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Check to see if the board failed any self tests.
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status & SELF_TEST_FAILED)
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Check to see if the board panic'd while booting.
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (status & KERNEL_PANIC)
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -2;
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(status & KERNEL_UP_AND_RUNNING))
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -3;
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Everything is OK
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
29876a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp *	aac_sa_ioremap
29976a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp *	@size: mapping resize request
30076a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp *
30176a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp */
30276a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkampstatic int aac_sa_ioremap(struct aac_dev * dev, u32 size)
30376a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp{
30476a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	if (!size) {
30576a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp		iounmap(dev->regs.sa);
30676a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp		return 0;
30776a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	}
30876a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	dev->base = dev->regs.sa = ioremap(dev->scsi_host_ptr->base, size);
30976a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	return (dev->base == NULL) ? -1 : 0;
31076a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp}
31176a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp
31276a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp/**
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	aac_sa_init	-	initialize an ARM based AAC card
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	@dev: device to configure
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Allocate and set up resources for the ARM based AAC variants. The
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	device_interface in the commregion will be allocated and linked
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	to the comm region.
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint aac_sa_init(struct aac_dev *dev)
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long start;
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long status;
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int instance;
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char *name;
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	instance = dev->id;
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	name     = dev->name;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33176a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	if (aac_sa_ioremap(dev, dev->base_size)) {
33276a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
33376a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp		goto error_iounmap;
33476a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	}
33576a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Check to see if the board failed any self tests.
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sa_readl(dev, Mailbox7) & SELF_TEST_FAILED) {
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "%s%d: adapter self-test failed.\n", name, instance);
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto error_iounmap;
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Check to see if the board panic'd while booting.
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sa_readl(dev, Mailbox7) & KERNEL_PANIC) {
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "%s%d: adapter kernel panic'd.\n", name, instance);
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto error_iounmap;
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	start = jiffies;
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Wait for the adapter to be up and running. Wait up to 3 minutes.
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
355404d9a900b5bc83a3780ec337ca6fdcb04b766c0Mark Haverkamp		if (time_after(jiffies, start+startup_timeout*HZ)) {
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = sa_readl(dev, Mailbox7);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %lx.\n",
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					name, instance, status);
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto error_iounmap;
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
361404d9a900b5bc83a3780ec337ca6fdcb04b766c0Mark Haverkamp		msleep(1);
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Fill in the function dispatch table.
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
369bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
37028713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->a_ops.adapter_notify = aac_sa_notify_adapter;
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->a_ops.adapter_check_health = aac_sa_check_health;
3742ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark	dev->a_ops.adapter_restart = aac_sa_restart_adapter;
37528713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	dev->a_ops.adapter_intr = aac_sa_intr;
3762ab01efd1d2a24db53b4c5d28a2e20cf2b1206c5Salyzyn, Mark	dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
37776a7f8fdc0c2381ae1ba55ef71837712223ecb3cMark Haverkamp	dev->a_ops.adapter_ioremap = aac_sa_ioremap;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
379bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	/*
380bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	 *	First clear out all interrupts.  Then enable the one's that
381bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	 *	we can handle.
382bd1aac809ddbcf7772cfd809d8cfb29c729c6cf9Mark Haverkamp	 */
38328713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	aac_adapter_disable_int(dev);
38428713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	aac_adapter_enable_int(dev);
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(aac_init_adapter(dev) == NULL)
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto error_irq;
388116046127d1a3bad2853d02781ad9fee33f05e5aMahesh Rajashekhara	dev->sync_mode = 0;	/* sync. mode not supported */
3898ef2224707996aede1808f40116cd467b7c8d549Salyzyn, Mark	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
39028713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp			IRQF_SHARED|IRQF_DISABLED,
39128713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp			"aacraid", (void *)dev ) < 0) {
39228713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp		printk(KERN_WARNING "%s%d: Interrupt unavailable.\n",
39328713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp			name, instance);
39428713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp		goto error_iounmap;
39528713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	}
396e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara	dev->dbg_base = dev->scsi_host_ptr->base;
397e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara	dev->dbg_base_mapped = dev->base;
398e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara	dev->dbg_size = dev->base_size;
399e8b12f0fb8352237525961f14ec933e915848840Mahesh Rajashekhara
40028713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	aac_adapter_enable_int(dev);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	Tell the adapter that all is configure, and it can start
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *	accepting requests
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	aac_sa_start_adapter(dev);
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror_irq:
41028713324a0f3c055186ecec27239673c36ba1de5Mark Haverkamp	aac_sa_disable_interrupt(dev);
4118ef2224707996aede1808f40116cd467b7c8d549Salyzyn, Mark	free_irq(dev->pdev->irq, (void *)dev);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror_iounmap:
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return -1;
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
418