Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *	Adaptec AAC series RAID controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *	(c) Copyright 2001 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * based on the old aacraid driver that is..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Adaptec aacraid device driver for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (c) 2000-2010 Adaptec, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Module Name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  sa.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Abstract: Drawbridge specific support functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include "aacraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static irqreturn_t aac_sa_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct aac_dev *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned short intstat, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	intstat = sa_readw(dev, DoorbellReg_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 *	Read mask and invert because drawbridge is reversed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	 *	This allows us to only service interrupts that have been enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	mask = ~(sa_readw(dev, SaDbCSR.PRISETIRQMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	/* Check to see if this is our interrupt.  If it isn't just return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (intstat & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (intstat & PrintfReady) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			aac_printf(dev, sa_readl(dev, Mailbox5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			sa_writew(dev, DoorbellReg_s, PrintfDone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		} else if (intstat & DOORBELL_1) {	// dev -> Host Normal Command Ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			sa_writew(dev, DoorbellClrReg_p, DOORBELL_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		} else if (intstat & DOORBELL_2) {	// dev -> Host Normal Response Ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			sa_writew(dev, DoorbellClrReg_p, DOORBELL_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		} else if (intstat & DOORBELL_3) {	// dev -> Host Normal Command Not Full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			sa_writew(dev, DoorbellClrReg_p, DOORBELL_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		} else if (intstat & DOORBELL_4) {	// dev -> Host Normal Response Not Full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			sa_writew(dev, DoorbellClrReg_p, DOORBELL_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	aac_sa_disable_interrupt	-	disable interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	@dev: Which adapter to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static void aac_sa_disable_interrupt (struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *	aac_sa_enable_interrupt	-	enable interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *	@dev: Which adapter to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) static void aac_sa_enable_interrupt (struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *	aac_sa_notify_adapter		-	handle adapter notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *	@dev:	Adapter that notification is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *	@event:	Event to notidy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *	Notify the adapter of an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	case AdapNormCmdQue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		sa_writew(dev, DoorbellReg_s,DOORBELL_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	case HostNormRespNotFull:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		sa_writew(dev, DoorbellReg_s,DOORBELL_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	case AdapNormRespQue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		sa_writew(dev, DoorbellReg_s,DOORBELL_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	case HostNormCmdNotFull:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		sa_writew(dev, DoorbellReg_s,DOORBELL_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	case HostShutdown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		sa_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	case FastIo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		sa_writew(dev, DoorbellReg_s,DOORBELL_6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	case AdapPrintfDone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		sa_writew(dev, DoorbellReg_s,DOORBELL_5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *	sa_sync_cmd	-	send a command and wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *	@dev: Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  *	@command: Command to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  *	@p1: first parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *	@p2: second parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  *	@p3: third parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  *	@p4: forth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  *	@p5: fifth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *	@p6: sixth parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  *	@ret: adapter status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *	@r1: first return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  *	@r2: second return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *	@r3: third return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *	@r4: forth return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *	This routine will send a synchronous command to the adapter and wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *	for its	completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int sa_sync_cmd(struct aac_dev *dev, u32 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		u32 *ret, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  	int ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	 *	Write the Command into Mailbox 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	sa_writel(dev, Mailbox0, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	 *	Write the parameters into Mailboxes 1 - 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	sa_writel(dev, Mailbox1, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	sa_writel(dev, Mailbox2, p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	sa_writel(dev, Mailbox3, p3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	sa_writel(dev, Mailbox4, p4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 *	Clear the synch command doorbell to start on a clean slate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	 *	Signal that there is a new synch command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	sa_writew(dev, DoorbellReg_s, DOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	while(time_before(jiffies, start+30*HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		 *	Delay 5uS so that the monitor gets access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		 *	Mon110 will set doorbell0 bit when it has 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		 *	completed the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		if(sa_readw(dev, DoorbellReg_p) & DOORBELL_0)  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			ok = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (ok != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	 *	Clear the synch command doorbell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	sa_writew(dev, DoorbellClrReg_p, DOORBELL_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	 *	Pull the synch status from Mailbox 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		*ret = sa_readl(dev, Mailbox0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		*r1 = sa_readl(dev, Mailbox1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		*r2 = sa_readl(dev, Mailbox2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if (r3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		*r3 = sa_readl(dev, Mailbox3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		*r4 = sa_readl(dev, Mailbox4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  *	aac_sa_interrupt_adapter	-	interrupt an adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  *	@dev: Which adapter to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  *	Breakpoint an adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static void aac_sa_interrupt_adapter (struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  *	aac_sa_start_adapter		-	activate adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  *	@dev:	Adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  *	Start up processing on an ARM based AAC adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static void aac_sa_start_adapter(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	union aac_init *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	 * Fill in the remaining pieces of the init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	init = dev->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	init->r7.host_elapsed_seconds = cpu_to_le32(ktime_get_real_seconds());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/* We can only use a 32 bit address here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			NULL, NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static int aac_sa_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  *	aac_sa_check_health
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  *	@dev: device to check if healthy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  *	Will attempt to determine if the specified adapter is alive and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  *	capable of handling requests, returning 0 if alive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int aac_sa_check_health(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	long status = sa_readl(dev, Mailbox7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	 *	Check to see if the board failed any self tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (status & SELF_TEST_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	 *	Check to see if the board panic'd while booting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (status & KERNEL_PANIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (!(status & KERNEL_UP_AND_RUNNING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		return -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	 *	Everything is OK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  *	aac_sa_ioremap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  *	@dev: device to ioremap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  *	@size: mapping resize request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int aac_sa_ioremap(struct aac_dev * dev, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		iounmap(dev->regs.sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	dev->base = dev->regs.sa = ioremap(dev->base_start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	return (dev->base == NULL) ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  *	aac_sa_init	-	initialize an ARM based AAC card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  *	@dev: device to configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  *	Allocate and set up resources for the ARM based AAC variants. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  *	device_interface in the commregion will be allocated and linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  *	to the comm region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int aac_sa_init(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	unsigned long status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	int instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	instance = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	name     = dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	 *	Fill in the function dispatch table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	dev->a_ops.adapter_notify = aac_sa_notify_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	dev->a_ops.adapter_check_health = aac_sa_check_health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	dev->a_ops.adapter_restart = aac_sa_restart_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	dev->a_ops.adapter_start = aac_sa_start_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	dev->a_ops.adapter_intr = aac_sa_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	dev->a_ops.adapter_ioremap = aac_sa_ioremap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (aac_sa_ioremap(dev, dev->base_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	 *	Check to see if the board failed any self tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	if (sa_readl(dev, Mailbox7) & SELF_TEST_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		printk(KERN_WARNING "%s%d: adapter self-test failed.\n", name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	 *	Check to see if the board panic'd while booting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (sa_readl(dev, Mailbox7) & KERNEL_PANIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		printk(KERN_WARNING "%s%d: adapter kernel panic'd.\n", name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	 *	Wait for the adapter to be up and running. Wait up to 3 minutes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		if (time_after(jiffies, start+startup_timeout*HZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			status = sa_readl(dev, Mailbox7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %lx.\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 					name, instance, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	 *	First clear out all interrupts.  Then enable the one's that 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	 *	we can handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	aac_adapter_disable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if(aac_init_adapter(dev) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		goto error_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	dev->sync_mode = 0;	/* sync. mode not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			IRQF_SHARED, "aacraid", (void *)dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		printk(KERN_WARNING "%s%d: Interrupt unavailable.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			name, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	dev->dbg_base = dev->base_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	dev->dbg_base_mapped = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	dev->dbg_size = dev->base_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	 *	Tell the adapter that all is configure, and it can start 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	 *	accepting requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	aac_sa_start_adapter(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) error_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	aac_sa_disable_interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	free_irq(dev->pdev->irq, (void *)dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) error_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)